Skip to content

Commit dcae4a2

Browse files
committed
test(stack): stage USER_JWT live-coverage guard (skipped pending secret)
The identity/lock-context live suites soft-skip on a missing USER_JWT, which the CI coverage guard never asserted. Add a LIVE_LOCK_CONTEXT_ENABLED flag and a guard assertion, kept as it.skip until the USER_JWT CI secret is provisioned (flip to it.runIf(IN_CI) then) so CI does not fail on the not-yet-present secret.
1 parent f281167 commit dcae4a2

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

packages/stack/__tests__/helpers/live-gate.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ export const LIVE_EQL_V3_PG_ENABLED = Boolean(
2323
process.env.DATABASE_URL && LIVE_CIPHERSTASH_ENABLED,
2424
)
2525

26+
/**
27+
* True when live credentials AND a `USER_JWT` are configured. The identity /
28+
* lock-context live suites additionally require a `USER_JWT` to bind keys to an
29+
* end-user identity, and SOFT-SKIP (inline `if (!userJwt) return`) when it is
30+
* absent — so a missing/rotated `USER_JWT` lets them skip green in CI. This
31+
* flag lets the live-coverage guard assert that path is actually exercised.
32+
*/
33+
export const LIVE_LOCK_CONTEXT_ENABLED = Boolean(
34+
process.env.USER_JWT && LIVE_CIPHERSTASH_ENABLED,
35+
)
36+
2637
export const describeLive = LIVE_CIPHERSTASH_ENABLED ? describe : describe.skip
2738

2839
export const describeLivePg = LIVE_EQL_V3_PG_ENABLED ? describe : describe.skip

packages/stack/__tests__/live-coverage-guard.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import { describe, expect, it } from 'vitest'
5555
import {
5656
LIVE_CIPHERSTASH_ENABLED,
5757
LIVE_EQL_V3_PG_ENABLED,
58+
LIVE_LOCK_CONTEXT_ENABLED,
5859
} from './helpers/live-gate'
5960

6061
// GitHub Actions always sets CI=true; treat any truthy CI as "must run live".
@@ -87,6 +88,28 @@ describe('live-coverage guard', () => {
8788
},
8889
)
8990

91+
// DEFERRED (follow-up): the CI `USER_JWT` secret is not yet provisioned, so
92+
// enforcing this now would fail CI. Skipped until the secret exists — flip
93+
// back to `it.runIf(IN_CI)` at that point. It still documents the real gap:
94+
// the identity / lock-context live suites soft-skip on a missing USER_JWT, so
95+
// once the secret lands this guard turns a silent whole-suite skip into a
96+
// loud failure (as the CS_*/DATABASE_URL guards already do).
97+
it.skip(
98+
'CI must have USER_JWT so the lock-context live suites do not silently skip',
99+
() => {
100+
expect(
101+
LIVE_LOCK_CONTEXT_ENABLED,
102+
'CI must run the live lock-context / identity suites — ' +
103+
'`LIVE_LOCK_CONTEXT_ENABLED` is false. This needs the CS_* creds AND ' +
104+
'a `USER_JWT`; the identity/lock-context suites (e.g. ' +
105+
'lock-context.test.ts, protect-ops.test.ts, ' +
106+
'operators-lock-context-live-pg.test.ts) SOFT-SKIP when USER_JWT is ' +
107+
'absent, so a missing/rotated USER_JWT lets them skip green with no ' +
108+
'signal — the exact failure mode this guard exists to prevent.',
109+
).toBe(true)
110+
},
111+
)
112+
90113
// Local dev with no creds: nothing to assert. Keep at least one always-run
91114
// assertion so the file is never reported as fully empty/pending.
92115
it('is always collected (guard file runs outside every live gate)', () => {

0 commit comments

Comments
 (0)