fix: resolve all failing tests (UUID validation, JWT algorithm, token uniqueness)

This commit is contained in:
root 2026-03-20 23:24:49 +00:00
parent 84664138ad
commit 7f9e302e5e
3 changed files with 21 additions and 18 deletions

View File

@ -52,7 +52,7 @@ describe('Auth Routes', () => {
expect(res.status).toBe(200); expect(res.status).toBe(200);
expect(res.body.user.tenant).toBeTruthy(); expect(res.body.user.tenant).toBeTruthy();
expect(res.body.user.tenant.id).toBe('tenant-a-id'); expect(res.body.user.tenant.id).toBe(TEST_CUSTOMER_USER_A.tenantId);
expect(res.body.user.tenant.name).toBe('Tenant A'); expect(res.body.user.tenant.name).toBe('Tenant A');
expect(res.body.user.tenant.slug).toBe('tenant-a'); expect(res.body.user.tenant.slug).toBe('tenant-a');
}); });
@ -162,7 +162,7 @@ describe('Auth Routes', () => {
expect(res.status).toBe(200); expect(res.status).toBe(200);
expect(res.body.tenant).toBeTruthy(); expect(res.body.tenant).toBeTruthy();
expect(res.body.tenant.id).toBe('tenant-a-id'); expect(res.body.tenant.id).toBe(TEST_CUSTOMER_USER_A.tenantId);
expect(res.body.tenant.name).toBe('Tenant A'); expect(res.body.tenant.name).toBe('Tenant A');
}); });
@ -193,7 +193,7 @@ describe('Auth Routes', () => {
lastName: TEST_CUSTOMER_USER_A.lastName, lastName: TEST_CUSTOMER_USER_A.lastName,
}, },
process.env.JWT_SECRET!, process.env.JWT_SECRET!,
{ expiresIn: '0s' } { algorithm: 'HS256', expiresIn: '0s' }
); );
// Small delay to ensure token is expired // Small delay to ensure token is expired

View File

@ -300,7 +300,7 @@ jest.mock('../lib/prisma', () => ({
// ============================================================ // ============================================================
export const TEST_TENANT_A = { export const TEST_TENANT_A = {
id: 'tenant-a-id', id: 'a0000000-0000-0000-0000-000000000001',
name: 'Tenant A', name: 'Tenant A',
slug: 'tenant-a', slug: 'tenant-a',
logo: null, logo: null,
@ -310,7 +310,7 @@ export const TEST_TENANT_A = {
}; };
export const TEST_TENANT_B = { export const TEST_TENANT_B = {
id: 'tenant-b-id', id: 'b0000000-0000-0000-0000-000000000002',
name: 'Tenant B', name: 'Tenant B',
slug: 'tenant-b', slug: 'tenant-b',
logo: null, logo: null,
@ -354,7 +354,7 @@ export const TEST_CUSTOMER_ADMIN_A = {
firstName: 'Customer', firstName: 'Customer',
lastName: 'AdminA', lastName: 'AdminA',
role: 'CUSTOMER_ADMIN' as const, role: 'CUSTOMER_ADMIN' as const,
tenantId: 'tenant-a-id', tenantId: 'a0000000-0000-0000-0000-000000000001',
active: true, active: true,
createdAt: new Date('2025-01-01'), createdAt: new Date('2025-01-01'),
updatedAt: new Date('2025-01-01'), updatedAt: new Date('2025-01-01'),
@ -367,7 +367,7 @@ export const TEST_CUSTOMER_USER_A = {
firstName: 'Customer', firstName: 'Customer',
lastName: 'UserA', lastName: 'UserA',
role: 'CUSTOMER_USER' as const, role: 'CUSTOMER_USER' as const,
tenantId: 'tenant-a-id', tenantId: 'a0000000-0000-0000-0000-000000000001',
active: true, active: true,
createdAt: new Date('2025-01-01'), createdAt: new Date('2025-01-01'),
updatedAt: new Date('2025-01-01'), updatedAt: new Date('2025-01-01'),
@ -380,7 +380,7 @@ export const TEST_CUSTOMER_USER_B = {
firstName: 'Customer', firstName: 'Customer',
lastName: 'UserB', lastName: 'UserB',
role: 'CUSTOMER_USER' as const, role: 'CUSTOMER_USER' as const,
tenantId: 'tenant-b-id', tenantId: 'b0000000-0000-0000-0000-000000000002',
active: true, active: true,
createdAt: new Date('2025-01-01'), createdAt: new Date('2025-01-01'),
updatedAt: new Date('2025-01-01'), updatedAt: new Date('2025-01-01'),
@ -393,7 +393,7 @@ export const TEST_INACTIVE_USER = {
firstName: 'Inactive', firstName: 'Inactive',
lastName: 'User', lastName: 'User',
role: 'CUSTOMER_USER' as const, role: 'CUSTOMER_USER' as const,
tenantId: 'tenant-a-id', tenantId: 'a0000000-0000-0000-0000-000000000001',
active: false, active: false,
createdAt: new Date('2025-01-01'), createdAt: new Date('2025-01-01'),
updatedAt: new Date('2025-01-01'), updatedAt: new Date('2025-01-01'),
@ -420,18 +420,21 @@ export function generateTestToken(user: {
lastName: user.lastName, lastName: user.lastName,
}, },
process.env.JWT_SECRET!, process.env.JWT_SECRET!,
{ expiresIn: '15m' } { algorithm: 'HS256', expiresIn: '15m' }
); );
} }
// Counter to ensure each refresh token is unique even within the same second
let refreshTokenCounter = 0;
/** /**
* Generate a JWT refresh token for testing. * Generate a JWT refresh token for testing.
*/ */
export function generateTestRefreshToken(userId: string): string { export function generateTestRefreshToken(userId: string): string {
return jwt.sign( return jwt.sign(
{ id: userId, type: 'refresh' }, { id: userId, type: 'refresh', jti: `test-${Date.now()}-${++refreshTokenCounter}` },
process.env.JWT_REFRESH_SECRET!, process.env.JWT_REFRESH_SECRET!,
{ expiresIn: '7d' } { algorithm: 'HS256', expiresIn: '7d' }
); );
} }
@ -465,7 +468,7 @@ export function seedTestData(): void {
id: 'workflow-a1-id', id: 'workflow-a1-id',
title: 'Workflow A1', title: 'Workflow A1',
description: 'Test workflow for tenant A', description: 'Test workflow for tenant A',
tenantId: 'tenant-a-id', tenantId: 'a0000000-0000-0000-0000-000000000001',
categoryId: null, categoryId: null,
status: 'DRAFT', status: 'DRAFT',
version: 1, version: 1,
@ -482,7 +485,7 @@ export function seedTestData(): void {
id: 'workflow-b1-id', id: 'workflow-b1-id',
title: 'Workflow B1', title: 'Workflow B1',
description: 'Test workflow for tenant B', description: 'Test workflow for tenant B',
tenantId: 'tenant-b-id', tenantId: 'b0000000-0000-0000-0000-000000000002',
categoryId: null, categoryId: null,
status: 'PUBLISHED', status: 'PUBLISHED',
version: 1, version: 1,

View File

@ -110,7 +110,7 @@ describe('Workflow Routes', () => {
const validWorkflow = { const validWorkflow = {
title: 'New Test Workflow', title: 'New Test Workflow',
description: 'A test workflow description', description: 'A test workflow description',
tenantId: 'tenant-a-id', tenantId: TEST_TENANT_A.id,
tags: ['new', 'test'], tags: ['new', 'test'],
}; };
@ -145,14 +145,14 @@ describe('Workflow Routes', () => {
.send(validWorkflow); .send(validWorkflow);
expect(res.status).toBe(201); expect(res.status).toBe(201);
expect(res.body.data.tenantId).toBe('tenant-a-id'); expect(res.body.data.tenantId).toBe(TEST_TENANT_A.id);
}); });
it('should reject CUSTOMER_ADMIN creating workflow in another tenant', async () => { it('should reject CUSTOMER_ADMIN creating workflow in another tenant', async () => {
const res = await request(app) const res = await request(app)
.post('/api/workflows') .post('/api/workflows')
.set('Authorization', `Bearer ${customerAdminAToken}`) .set('Authorization', `Bearer ${customerAdminAToken}`)
.send({ ...validWorkflow, tenantId: 'tenant-b-id' }); .send({ ...validWorkflow, tenantId: TEST_TENANT_B.id });
expect(res.status).toBe(403); expect(res.status).toBe(403);
}); });
@ -178,7 +178,7 @@ describe('Workflow Routes', () => {
const res = await request(app) const res = await request(app)
.post('/api/workflows') .post('/api/workflows')
.set('Authorization', `Bearer ${systemAdminToken}`) .set('Authorization', `Bearer ${systemAdminToken}`)
.send({ tenantId: 'tenant-a-id' }); .send({ tenantId: TEST_TENANT_A.id });
expect(res.status).toBe(400); expect(res.status).toBe(400);
expect(res.body).toHaveProperty('error'); expect(res.body).toHaveProperty('error');