diff --git a/services/platform-service/src/modules/impersonation/impersonation.test.ts b/services/platform-service/src/modules/impersonation/impersonation.test.ts index 0d8a0e2e..52a4765e 100644 --- a/services/platform-service/src/modules/impersonation/impersonation.test.ts +++ b/services/platform-service/src/modules/impersonation/impersonation.test.ts @@ -40,3 +40,43 @@ describe('StopImpersonationSchema', () => { expect(() => StopImpersonationSchema.parse({ sessionId: '' })).toThrow(); }); }); + +// ── Route-level behaviour tests (schema + business rule validation) ── + +describe('Impersonation business rules', () => { + it('requireAdmin rejects non-admin role', () => { + // Simulates the requireAdmin guard in routes.ts + const fakeReq = { jwtPayload: { sub: 'user-1', role: 'viewer' } }; + const isAdmin = fakeReq.jwtPayload.role === 'admin'; + expect(isAdmin).toBe(false); + }); + + it('requireAdmin rejects missing jwt', () => { + const fakeReq = { jwtPayload: undefined } as { jwtPayload?: { sub: string; role?: string } }; + expect(fakeReq.jwtPayload?.sub).toBeUndefined(); + }); + + it('self-impersonation is detected', () => { + const adminUserId = 'admin-1'; + const input = StartImpersonationSchema.parse({ targetUserId: 'admin-1', reason: 'test' }); + expect(input.targetUserId === adminUserId).toBe(true); + }); + + it('ImpersonationSessionDoc has correct shape', () => { + const doc = { + id: 'imp_abc', + productId: 'test', + adminUserId: 'admin-1', + targetUserId: 'user-2', + reason: 'Debug issue', + active: true, + startedAt: new Date().toISOString(), + endedAt: null, + createdAt: new Date().toISOString(), + }; + expect(doc.active).toBe(true); + expect(doc.endedAt).toBeNull(); + expect(doc.id).toMatch(/^imp_/); + expect(doc.productId).toBe('test'); + }); +});