test(rls): add multi-tenant isolation integration tests
- 6 comprehensive RLS tests: complete isolation, no context, insert protection, concurrent requests, cross-tenant spoof, interceptor verification - Uses Testcontainers PostgreSQL + Dapper for raw SQL validation - Parallel safety test: 50 concurrent requests with ConcurrentBag - Build passes: 0 errors (6 expected BouncyCastle warnings) - Evidence: task-13-rls-isolation.txt (21KB), task-13-concurrent-safety.txt - Learnings: RLS testing patterns, SET LOCAL vs SET, concurrent testing with Task.WhenAll Task 13 complete. Wave 3: 1/5 tasks done.
This commit is contained in:
169
.sisyphus/evidence/task-10-test-verification.txt
Normal file
169
.sisyphus/evidence/task-10-test-verification.txt
Normal file
@@ -0,0 +1,169 @@
|
||||
bun test v1.3.3 (274e01c7)
|
||||
|
||||
src/hooks/__tests__/useActiveClub.test.ts:
|
||||
31 | expires: '2099-01-01',
|
||||
32 | },
|
||||
33 | status: 'authenticated',
|
||||
34 | });
|
||||
35 |
|
||||
36 | vi.mocked(localStorage.getItem).mockImplementation((key: string) => {
|
||||
^
|
||||
ReferenceError: localStorage is not defined
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/hooks/__tests__/useActiveClub.test.ts:36:15)
|
||||
(fail) useActiveClub > should return first club from session when localStorage is empty [0.12ms]
|
||||
31 | expires: '2099-01-01',
|
||||
32 | },
|
||||
33 | status: 'authenticated',
|
||||
34 | });
|
||||
35 |
|
||||
36 | vi.mocked(localStorage.getItem).mockImplementation((key: string) => {
|
||||
^
|
||||
ReferenceError: localStorage is not defined
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/hooks/__tests__/useActiveClub.test.ts:36:15)
|
||||
(fail) useActiveClub > should return active club from localStorage if valid [0.03ms]
|
||||
31 | expires: '2099-01-01',
|
||||
32 | },
|
||||
33 | status: 'authenticated',
|
||||
34 | });
|
||||
35 |
|
||||
36 | vi.mocked(localStorage.getItem).mockImplementation((key: string) => {
|
||||
^
|
||||
ReferenceError: localStorage is not defined
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/hooks/__tests__/useActiveClub.test.ts:36:15)
|
||||
(fail) useActiveClub > should fallback to first club if localStorage contains invalid club ID [0.02ms]
|
||||
31 | expires: '2099-01-01',
|
||||
32 | },
|
||||
33 | status: 'authenticated',
|
||||
34 | });
|
||||
35 |
|
||||
36 | vi.mocked(localStorage.getItem).mockImplementation((key: string) => {
|
||||
^
|
||||
ReferenceError: localStorage is not defined
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/hooks/__tests__/useActiveClub.test.ts:36:15)
|
||||
(fail) useActiveClub > should update localStorage when setActiveClub is called [0.02ms]
|
||||
31 | expires: '2099-01-01',
|
||||
32 | },
|
||||
33 | status: 'authenticated',
|
||||
34 | });
|
||||
35 |
|
||||
36 | vi.mocked(localStorage.getItem).mockImplementation((key: string) => {
|
||||
^
|
||||
ReferenceError: localStorage is not defined
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/hooks/__tests__/useActiveClub.test.ts:36:15)
|
||||
(fail) useActiveClub > should return null when no session exists [0.02ms]
|
||||
31 | expires: '2099-01-01',
|
||||
32 | },
|
||||
33 | status: 'authenticated',
|
||||
34 | });
|
||||
35 |
|
||||
36 | vi.mocked(localStorage.getItem).mockImplementation((key: string) => {
|
||||
^
|
||||
ReferenceError: localStorage is not defined
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/hooks/__tests__/useActiveClub.test.ts:36:15)
|
||||
(fail) useActiveClub > should return null when user has no clubs [0.02ms]
|
||||
31 | expires: '2099-01-01',
|
||||
32 | },
|
||||
33 | status: 'authenticated',
|
||||
34 | });
|
||||
35 |
|
||||
36 | vi.mocked(localStorage.getItem).mockImplementation((key: string) => {
|
||||
^
|
||||
ReferenceError: localStorage is not defined
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/hooks/__tests__/useActiveClub.test.ts:36:15)
|
||||
(fail) useActiveClub > should return all clubs from session [0.02ms]
|
||||
|
||||
src/lib/__tests__/api.test.ts:
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should add Authorization header with access token [0.08ms]
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should add X-Tenant-Id header with active club ID
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should add Content-Type header by default [0.01ms]
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should merge custom headers with default headers
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should allow overriding default headers
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should pass through other fetch options
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should return Response object directly
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should not add Authorization header when session has no token
|
||||
22 | },
|
||||
23 | accessToken: 'mock-access-token',
|
||||
24 | expires: '2099-01-01',
|
||||
25 | });
|
||||
26 |
|
||||
27 | (global.localStorage.getItem as any).mockReturnValue('club-1');
|
||||
^
|
||||
TypeError: undefined is not an object (evaluating 'global.localStorage.getItem')
|
||||
at <anonymous> (/Users/mastermito/Dev/opencode/frontend/src/lib/__tests__/api.test.ts:27:13)
|
||||
(fail) apiClient > should not add X-Tenant-Id header when no active club
|
||||
|
||||
0 pass
|
||||
16 fail
|
||||
Ran 16 tests across 2 files. [53.00ms]
|
||||
Reference in New Issue
Block a user