Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 60 additions & 14 deletions crates/socket-patch-cli/tests/e2e_npm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,16 +458,33 @@ fn test_npm_global_lifecycle() {
assert_eq!(patches[0]["purl"].as_str().unwrap(), NPM_PURL);

// -- ROLLBACK: restore original file globally ----------------------------
// v5.0 rollback is full-state: by default it also drops the rolled-back
// manifest records, leaving `apply` nothing to re-apply. This lifecycle
// re-applies next, so it rolls back with `--preserve-state`, which
// restores the file and keeps the record.
assert_run_ok(
cwd,
&["rollback", "-g", "--global-prefix", nm_str],
"rollback -g",
&[
"rollback",
"-g",
"--global-prefix",
nm_str,
"--preserve-state",
],
"rollback -g --preserve-state",
);
assert_eq!(
git_sha256_file(&index_js),
BEFORE_HASH,
"index.js should match beforeHash after global rollback"
);
let manifest: serde_json::Value =
serde_json::from_str(&std::fs::read_to_string(&manifest_path).unwrap()).unwrap();
assert_eq!(
manifest["patches"][NPM_PURL]["uuid"].as_str(),
Some(NPM_UUID),
"rollback --preserve-state keeps the manifest record"
);

// -- APPLY: re-apply from manifest globally ------------------------------
assert_run_ok(cwd, &["apply", "-g", "--global-prefix", nm_str], "apply -g");
Expand Down Expand Up @@ -690,7 +707,11 @@ fn test_npm_macos_global_auto_discovery() {
);
}

/// UUID shortcut: `socket-patch <UUID>` should behave like `socket-patch get <UUID>`.
/// UUID shortcut: `socket-patch <UUID>` behaves like `socket-patch get
/// <UUID>`. In v5.0 a bare `get` in a lockfile project runs hosted mode: the
/// lockfile is redirected to the Socket-hosted patched tarball and the
/// installed tree is left for the next install; `--mode agent` passes
/// through the shortcut and patches in place, recording the manifest.
#[test]
#[ignore]
fn test_npm_uuid_shortcut() {
Expand All @@ -708,28 +729,53 @@ fn test_npm_uuid_shortcut() {
let index_js = cwd.join("node_modules/minimist/index.js");
assert_eq!(git_sha256_file(&index_js), BEFORE_HASH);

// Run with bare UUID (no "get" subcommand).
assert_run_ok(cwd, &[NPM_UUID], "uuid shortcut");
// Bare UUID (no "get" subcommand): hosted mode, like a bare `get`.
let (stdout, _) = assert_run_ok(cwd, &[NPM_UUID, "--json"], "uuid shortcut");
let env: serde_json::Value = serde_json::from_str(&stdout)
.unwrap_or_else(|e| panic!("uuid shortcut --json is not JSON ({e}): {stdout}"));
assert_eq!(env["status"], "success", "{env:#}");
let lock = std::fs::read_to_string(cwd.join("package-lock.json")).unwrap();
let lock: serde_json::Value = serde_json::from_str(&lock).unwrap();
let resolved = lock["packages"]["node_modules/minimist"]["resolved"]
.as_str()
.unwrap_or_default();
assert!(
resolved.starts_with("https://patch.socket.dev/") && resolved.contains(NPM_UUID),
"the shortcut's hosted get pins minimist to the hosted patch, got {resolved:?}"
);
assert_eq!(
git_sha256_file(&index_js),
BEFORE_HASH,
"hosted mode rewires the lockfile, not the installed tree"
);
assert!(
!cwd.join(".socket/manifest.json").exists(),
"hosted mode keeps no manifest"
);

// `--mode agent` passes through the shortcut: in place, with a manifest.
let agent = tempfile::tempdir().unwrap();
let cwd = agent.path();
write_package_json(cwd);
npm_run(cwd, &["install", "minimist@1.2.2"]);
let index_js = cwd.join("node_modules/minimist/index.js");
assert_run_ok(
cwd,
&[NPM_UUID, "--mode", "agent"],
"uuid shortcut --mode agent",
);
assert_eq!(
git_sha256_file(&index_js),
AFTER_HASH,
"index.js should match afterHash after UUID shortcut"
"index.js should match afterHash after `<UUID> --mode agent`"
);

// The shortcut must behave like `get`: the manifest must actually record
// our patch, not merely exist as an empty stub.
let manifest_path = cwd.join(".socket/manifest.json");
assert!(
manifest_path.exists(),
"manifest should exist after UUID shortcut"
);
let manifest: serde_json::Value =
serde_json::from_str(&std::fs::read_to_string(&manifest_path).unwrap()).unwrap();
let patch = &manifest["patches"][NPM_PURL];
assert!(
patch.is_object(),
"manifest should contain {NPM_PURL} after UUID shortcut"
"manifest should contain {NPM_PURL} after the agent-mode shortcut"
);
assert_eq!(patch["uuid"].as_str().unwrap(), NPM_UUID);
}
12 changes: 9 additions & 3 deletions crates/socket-patch-cli/tests/e2e_vendored_production.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1493,8 +1493,9 @@ fn berry_skip_code(env: &serde_json::Value) -> String {

/// Manifest-less VEX against PRODUCTION for the berry vendored leg, on the
/// fresh checkout the real yarn just installed from the committed artifact:
/// with the manifest deleted (ledger online + `--offline`), with the
/// ledger deleted too (lockfile + artifact, record from the public proxy),
/// with no manifest (v5 vendored mode writes none; ledger online +
/// `--offline`), with the ledger deleted too (lockfile + artifact, record
/// from the public proxy),
/// `--offline` with nothing local (`record_unavailable`), and a copy whose
/// lock + package.json are reverted to the registry while the ledger and
/// artifact stay (`vendor_unwired`, even with `--no-verify`).
Expand All @@ -1508,7 +1509,12 @@ fn yarn_berry_vendored_manifestless_vex(
let manifest = fresh.join(".socket/manifest.json");
let ledger_path = fresh.join(".socket/vendor/state.json");
let ledger = std::fs::read(&ledger_path).expect("vendor ledger");
std::fs::remove_file(&manifest).expect("scan --mode vendored writes a manifest");
// v5.0 vendored mode is manifest-free: the ledger embeds each entry's
// record, so the checkout is already manifest-less.
assert!(
!manifest.exists(),
"{LEG}: scan --mode vendored writes no .socket/manifest.json"
);

let (code, env, doc) = yarn_berry_vex(fresh, &[]);
assert_berry_vendored_attestation(code, &env, doc, &format!("{LEG}: ledger, online"));
Expand Down
Loading