Skip to content

Migrate tests to node:test; block dependency install scripts in CI - #9

Merged
fayerman-source merged 1 commit into
mainfrom
chore/node-test-and-ci-hardening
Jul 28, 2026
Merged

fayerman-source merged 1 commit into
mainfrom
chore/node-test-and-ci-hardening

Conversation

@fayerman-source

Copy link
Copy Markdown
Owner

Clears the two SonarCloud issues that surfaced on main after #8.

S2187 (BLOCKER) — test/logic.test.mjs

Add some tests to this file or delete it.

The file did contain 15 real assertions, but as a hand-rolled harness (bare blocks, a local ok() helper, a manual pass/fail tally), so Sonar's JavaScript analyzer saw nothing it recognized as a test. I opted to fix rather than dismiss, because the migration is a genuine upgrade and costs no dependencies: the built-in node:test runner gives real per-test isolation, proper reporting, and a nonzero exit driven by the runner instead of a hand-rolled process.exit.

11 tests, all 15 original assertions preserved. Two things changed beyond the mechanical translation:

  • Retention cases now build a fresh temp dir each via a setup() helper instead of sharing one directory across four assertions, so they no longer depend on execution order.
  • The multi-step state-machine sequences stay grouped one-test-each. Their assertions are checkpoints in a single watchCamera run (false → true → true → finish → false → true), so splitting them would mean replaying setup for each and would obscure what the test is actually pinning down.

Note the script is node --test test/*.test.mjs, not node --test test/ — since Node 22, positional args are glob patterns and a bare directory matches nothing. Verified: the directory form fails on Node 24, the glob form passes on both it and CI's Node 22.

S6505 — .github/workflows/ci.yml

npm ci ran dependency lifecycle scripts, which is a supply-chain foothold: any transitive dep can execute arbitrary code at install time. Now npm ci --ignore-scripts.

Deliberately no npm rebuild afterwards. Three deps ship install scripts — esbuild, ffmpeg-for-homebridge, protobufjs — and all three only fetch or build binaries this job never uses. CI type-checks and runs the hermetic tests, which touch neither ffmpeg nor tsx. Dropping the rebuild is both the stronger hardening and a faster, less network-dependent job (ffmpeg-for-homebridge was downloading an ffmpeg binary on every run). The step carries a comment explaining this and what to do if a future test needs real ffmpeg.

Verification

  • Clean npm ci --ignore-scripts into a scratch copy → build succeeds, 11/11 pass.
  • Deliberately broken assertion → npm test exits 1, confirming this can't silently green the build.

🤖 Generated with Claude Code

Two SonarCloud issues that surfaced on main after #8.

S2187 (BLOCKER, test/logic.test.mjs): "Add some tests to this file or delete
it." The file did contain 15 real assertions, but as a hand-rolled harness
(bare blocks, a local ok() helper, a manual pass/fail tally), so Sonar's
JavaScript analyzer saw no recognizable tests. Rather than dismiss it, migrate
to the built-in node:test runner — no new dependencies, and it is a genuine
upgrade: real per-test isolation, proper reporting, and a nonzero exit on
failure that comes from the runner instead of a hand-rolled process.exit.

11 tests, all 15 original assertions preserved. Retention cases now get a
fresh temp dir each via a setup() helper instead of sharing one directory, so
they no longer depend on execution order. The multi-step state-machine
sequences stay grouped in one test each, since their assertions are
checkpoints in a single run and splitting them would mean replaying setup.

Test script is `node --test test/*.test.mjs`, not `node --test test/`: since
Node 22 positional args are glob patterns, and a bare directory matches
nothing (verified failing on Node 24, passing on both with the glob).

S6505 (.github/workflows/ci.yml): `npm ci` ran dependency lifecycle scripts,
which is a supply-chain foothold — any transitive dep can execute arbitrary
code at install time. Now `npm ci --ignore-scripts`.

Deliberately no `npm rebuild` afterwards. Three deps ship install scripts
(esbuild, ffmpeg-for-homebridge, protobufjs) and all three only fetch or build
binaries this job never uses — it type-checks and runs hermetic tests, which
touch neither ffmpeg nor tsx. Verified by running a clean `npm ci
--ignore-scripts` into a scratch copy: build succeeds, 11/11 pass. Also
verified the suite still exits 1 on a deliberately broken assertion, so this
cannot silently green the build. A comment on the step records why nothing is
rebuilt and what to do if a future test needs real ffmpeg.
@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository Owner rate limit exceeded. Free accounts are limited to 3 reviews per 4 hours across all repositories. Upgrade to a paid plan for unlimited reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sonarqubecloud

Copy link
Copy Markdown

@fayerman-source
fayerman-source merged commit 758bb45 into main Jul 28, 2026
2 checks passed
@fayerman-source
fayerman-source deleted the chore/node-test-and-ci-hardening branch July 28, 2026 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant