auth0/node-jsonwebtoken
Testing is the strongest part of the repo: ~258 `it()` blocks across 30 mocha files in `test/`, backed by chai assertions, sinon fake timers, and 17 checked-in PEM fixtures covering RSA, RSA-PSS, EC (three curves), DSA, and deliberately-invalid keys. The signature move is `test/test-utils.js`, which runs every sign/verify twice — once sync, once async — under a frozen clock and asserts the two produce byte-identical tokens or deep-equal errors; this is why the sync/async parity invariant actually holds. Coverage is configured with hard nyc thresholds, but the CI workflow runs bare `mocha`, so those thresholds and eslint are never enforced on PRs. Test naming is split between a per-claim convention (`claim-*.test.js`, `option-*.test.js`) and older topic/regression files (`*.tests.js`, `issue_*.tests.js`).
- The framework stack is mocha 5 + chai 4 + sinon 6, with `atob` used to independently decode base64url segments in encoding tests. There is no `.mocharc`, so mocha's default `./test/*.js` glob picks up every file in `test/`.
- `test/test-utils.js` exports `signJWTHelper` and `verifyJWTHelper`, both of which freeze time with `sinon.useFakeTimers({now: Date.now()})`, run the sync call in a try/catch, then run the async call and assert equality of token or error before restoring the clock.
- `expectEqualError` exists because chai does not deep-equal errors (the helper cites chaijs/chai#1009); it compares `message` and `name` explicitly plus every enumerable property, which is how `expiredAt`/`date` payloads on the error subclasses get verified.
- Option/claim validation is tested exhaustively by table-driven loops over ~15 bad values (`true, false, null, -1.1, Infinity, NaN, ' ', '', [], ['foo'], {}, {foo:'bar'}` …), applied per-claim in `claim-exp.test.js`, `header-kid.test.js`, and siblings.
- `test/claim-aud.test.js` is the largest test file at 436 lines and 36 `it()` blocks, reflecting that audience matching (string/regex/array cross-product) is the most branch-heavy claim check.
- `test/jwt.asymmetric_signing.tests.js` is parameterized: it builds an `algorithms` map of RS256/ES256 (plus PS256 when `PS_SUPPORTED`) each with `pub_key`, `priv_key`, and an `invalid_pub_key` that is deliberately not the pair of `priv_key`, then runs the same describe block per algorithm.
- Security regressions are explicitly locked in by `test/jwt.malicious.tests.js`: HMAC-with-RSA-key confusion (both KeyObject and PEM form) and the malicious-`toString` Buffer-impersonation RCE vector.
- Historical bugs are pinned by dedicated regression files: `issue_70.tests.js` (PEM headers), `issue_147.tests.js` (signing an `Object.seal`ed payload), `issue_304.tests.js`, and `rsa-public-key.tests.js`.
- `test/validateAsymmetricKey.tests.js` unit-tests the key-matrix module directly (not through sign/verify), including the no-key and no-algorithm short-circuit paths and the PS/curve branches gated on the feature-detection booleans.
- nyc is configured with `check-coverage: true` and thresholds of 95% lines, 95% statements, 100% functions, 95% branches, excluding `./test/**` — a genuinely strict bar.
- GAP: `test.yml` runs only `npm test` (bare mocha). Neither `npm run coverage` nor `npm run lint` appears in any workflow, so the nyc thresholds and the eslint ruleset are advisory only and can silently regress.
- A known-broken case is parked rather than fixed: `it.skip('should work with none algorithm where secret is falsy')` in async_sign, annotated with a link to node-jws issue #62 — the async `alg: none` path with a falsy secret is untested and known not to work.
- A coverage hole is deliberately carved out with `/* istanbul ignore next */` around the entire `ASYMMETRIC_KEY_DETAILS_SUPPORTED` block in validateAsymmetricKey, with a comment explaining it would otherwise sink coverage on Node < 15.7.0 — meaning EC curve matching and RSA-PSS parameter checks are excluded from the coverage numbers.
- Test fixtures include intentionally-bad keys used as negative cases: `invalid_pub.pem`, `ecdsa-public-invalid.pem`, `rsa-pss-invalid-salt-length-private.pem`, and `dsa-public.pem` (to assert `Unknown key type "dsa".`).