Skip to content

Commit ba05410

Browse files
committed
test(e2e): add npm global install variant in Docker
Adds npm_global_install_full_apply_chain alongside the existing local install/apply/rollback test. The variant runs `npm install -g`, locates the file at $(npm root -g)/minimist/index.js, then runs scan + apply with --global and grep-verifies SOCKET-PATCH-E2E-MARKER. Host-mode skips the global variant (no safe host npm prefix to mutate); Docker is the canonical run path.
1 parent 3fdfb53 commit ba05410

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

crates/socket-patch-cli/tests/docker_e2e_npm.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,49 @@ exit 0
235235
)
236236
}
237237

238+
/// Driver script for the `npm install -g` variant. Installs minimist
239+
/// globally (into `$(npm root -g)`), runs scan + apply with `--global`,
240+
/// and verifies the marker landed in the global node_modules tree.
241+
fn make_global_script(api_url: &str) -> String {
242+
format!(
243+
r#"#!/usr/bin/env bash
244+
set -uo pipefail
245+
COMMON_ARGS=(--api-url '{api_url}' --api-token fake --org {ORG})
246+
247+
# Global install — populates $(npm root -g)/minimist/.
248+
npm install -g --silent --no-audit --no-fund minimist@1.2.2 > /tmp/install.log 2>&1 || {{
249+
cat /tmp/install.log >&2; exit 1
250+
}}
251+
252+
NPM_GLOBAL_ROOT=$(npm root -g)
253+
GLOBAL_FILE="$NPM_GLOBAL_ROOT/minimist/index.js"
254+
[ -f "$GLOBAL_FILE" ] || {{ echo "FAIL: $GLOBAL_FILE missing" >&2; ls "$NPM_GLOBAL_ROOT" >&2 || true; exit 1; }}
255+
echo "Global-installed at: $GLOBAL_FILE" >&2
256+
257+
# scan + apply run from an empty workspace; --global tells the crawler
258+
# to look at $(npm root -g) instead of cwd-relative node_modules.
259+
mkdir -p /workspace/proj && cd /workspace/proj
260+
261+
socket-patch scan --json --sync --yes --global "${{COMMON_ARGS[@]}}" \
262+
--ecosystems npm 2>/tmp/sync.err
263+
cat /tmp/sync.err >&2
264+
265+
socket-patch apply --json --force --offline --global --ecosystems npm 2>/tmp/apply.err
266+
cat /tmp/apply.err >&2
267+
268+
if ! grep -q 'SOCKET-PATCH-E2E-MARKER' "$GLOBAL_FILE"; then
269+
echo "FAIL: marker not in $GLOBAL_FILE" >&2
270+
head -3 "$GLOBAL_FILE" >&2
271+
exit 1
272+
fi
273+
274+
echo "===PATCH VERIFIED===" >&2
275+
echo "===E2E PASS==="
276+
exit 0
277+
"#
278+
)
279+
}
280+
238281
fn run_in_container(script: &str) -> std::process::Output {
239282
Command::new("docker")
240283
.args([
@@ -333,6 +376,31 @@ async fn npm_install_scan_apply_rollback_cycle() {
333376
);
334377
}
335378

379+
#[tokio::test]
380+
async fn npm_global_install_full_apply_chain() {
381+
// PURL must be the lowercased form scan's crawler emits — see the
382+
// nuget docker test for the same constraint. (npm names are already
383+
// lowercase in practice; we use the canonical form here for clarity.)
384+
let after_hash = git_sha256(PATCHED_BYTES);
385+
let server = make_mock_server(&after_hash).await;
386+
if host_mode() {
387+
// Host mode doesn't have a global npm prefix we can safely
388+
// mutate, so skip silently. Docker mode is the canonical run.
389+
return;
390+
}
391+
assert_docker_image_present();
392+
let api = api_url_for_container(&server);
393+
let out = run_in_container(&make_global_script(&api));
394+
let stdout = String::from_utf8_lossy(&out.stdout);
395+
let stderr = String::from_utf8_lossy(&out.stderr);
396+
assert!(
397+
out.status.success(),
398+
"npm global apply failed:\nstdout=\n{stdout}\nstderr=\n{stderr}"
399+
);
400+
assert!(stderr.contains("===PATCH VERIFIED==="), "stderr=\n{stderr}");
401+
assert!(stdout.contains("===E2E PASS==="), "stdout=\n{stdout}");
402+
}
403+
336404
/// Smoke test: verify the test infrastructure starts up correctly. This
337405
/// runs even without Docker so the test binary itself compiles + the
338406
/// wiremock listener path works.

0 commit comments

Comments
 (0)