feat(19-05): global-setup local_credentials seed + login.spec.ts + CI harness env

- global-setup.ts: TRUNCATE local_credentials + seed devuser/devpass (PHC scrypt inline)
- Create login.spec.ts: real-login-form e2e (gate redirect, wrong-password error, correct login)
- ci.yml: add LOCAL_SESSION_SECRET dev value + local_credentials seed step in harness job
- Fix all test mocks: add devSessionCookieMiddleware no-op to vi.mock(devBypass.js) blocks
  in admin/setup/push/lists/localAuth/authMode/requireAdmin tests (Rule 1 - Bug: missing export)
- Full API suite: 446/446 tests pass; pnpm typecheck: exit 0
This commit is contained in:
Lucas Berger
2026-06-17 17:21:05 -04:00
parent 82391874ee
commit 1f94dc5eb7
10 changed files with 233 additions and 0 deletions
+2
View File
@@ -32,6 +32,8 @@ vi.mock('../../src/auth/devBypass.js', () => ({
color: '#4A90D9',
},
devAuthBypass: () => async (_c: unknown, next: () => Promise<void>) => next(),
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
COLOR_PALETTE: ['#4A90D9'],
}));
+2
View File
@@ -93,6 +93,8 @@ vi.mock('../../src/auth/devBypass.js', () => ({
c.set('user', { id: currentDevUserId });
await next();
},
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests (cookie not needed)
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
}));
vi.mock('@hono/oidc-auth', () => ({
+2
View File
@@ -49,6 +49,8 @@ vi.mock('@hono/oidc-auth', () => ({
vi.mock('../../src/auth/devBypass.js', () => ({
devAuthBypass:
() => async (_c: unknown, next: () => Promise<void>) => next(),
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
}));
vi.mock('../../src/auth/localAuthMiddleware.js', () => ({
+2
View File
@@ -35,6 +35,8 @@ vi.mock('../../src/auth/devBypass.js', () => ({
c.set('user', { id: currentDevUserId });
await next();
},
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
}));
// Also mock the oidcAuthMiddleware so the OIDC guard is a no-op in tests.
+2
View File
@@ -77,6 +77,8 @@ vi.mock('../../src/auth/localSession.js', () => ({
vi.mock('../../src/auth/devBypass.js', () => ({
devAuthBypass:
() => async (_c: unknown, next: () => Promise<void>) => next(),
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
}));
vi.mock('../../src/auth/localAuthMiddleware.js', () => ({
+4
View File
@@ -30,6 +30,8 @@ vi.mock('../../src/auth/devBypass.js', () => ({
c.set('user', { id: currentDevUserId });
await next();
},
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
}));
vi.mock('@hono/oidc-auth', () => ({
@@ -111,6 +113,8 @@ describe('POST /api/push/subscription', () => {
// and OIDC getAuth returns null — so resolveUserId returns null → 401.
vi.doMock('../../src/auth/devBypass.js', () => ({
devAuthBypass: () => async (_c: unknown, next: () => Promise<void>) => next(),
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
}));
vi.doMock('../../src/auth/middleware.js', () => ({
getAuth: () => null,
+2
View File
@@ -101,6 +101,8 @@ vi.mock('../../src/auth/devBypass.js', () => ({
// No user injection for setup routes — pre-auth surface
await next();
},
// Phase 19 Option C: devSessionCookieMiddleware is a no-op in tests
devSessionCookieMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
}));
// ---------------------------------------------------------------------------