-
Notifications
You must be signed in to change notification settings - Fork 296
Expand file tree
/
Copy pathframeworks.controller.spec.ts
More file actions
118 lines (94 loc) · 3.8 KB
/
frameworks.controller.spec.ts
File metadata and controls
118 lines (94 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { Test, TestingModule } from '@nestjs/testing';
import { NotFoundException } from '@nestjs/common';
import { FrameworksController } from './frameworks.controller';
import { FrameworksService } from './frameworks.service';
import { HybridAuthGuard } from '../auth/hybrid-auth.guard';
import { PermissionGuard } from '../auth/permission.guard';
jest.mock('../auth/auth.server', () => ({
auth: { api: { getSession: jest.fn() } },
}));
describe('FrameworksController', () => {
let controller: FrameworksController;
let service: jest.Mocked<FrameworksService>;
const mockService = {
findAll: jest.fn(),
findAvailable: jest.fn(),
delete: jest.fn(),
};
const mockGuard = { canActivate: jest.fn().mockReturnValue(true) };
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [FrameworksController],
providers: [{ provide: FrameworksService, useValue: mockService }],
})
.overrideGuard(HybridAuthGuard)
.useValue(mockGuard)
.overrideGuard(PermissionGuard)
.useValue(mockGuard)
.compile();
controller = module.get<FrameworksController>(FrameworksController);
service = module.get(FrameworksService);
jest.clearAllMocks();
});
describe('findAll', () => {
it('should return framework instances with count', async () => {
const mockData = [
{
id: 'fi1',
frameworkId: 'f1',
framework: { id: 'f1', name: 'ISO 27001' },
},
{
id: 'fi2',
frameworkId: 'f2',
framework: { id: 'f2', name: 'SOC 2' },
},
];
mockService.findAll.mockResolvedValue(mockData);
const result = await controller.findAll('org_1');
expect(result).toEqual({ data: mockData, count: 2 });
expect(service.findAll).toHaveBeenCalledWith('org_1');
});
it('should return empty list when no frameworks', async () => {
mockService.findAll.mockResolvedValue([]);
const result = await controller.findAll('org_1');
expect(result).toEqual({ data: [], count: 0 });
});
});
describe('findAvailable', () => {
// Regression test for the onboarding 500 bug: this endpoint must not throw
// when the authenticated user has no active organization yet (fresh signups
// hitting the first onboarding step). Previously used @OrganizationId(),
// which threw when organizationId was empty → HTTP 500.
it('should return frameworks when user has no active organization', async () => {
const mockFrameworks = [
{ id: 'frk_1', name: 'soc2', visible: true, isCustom: false },
];
mockService.findAvailable.mockResolvedValue(mockFrameworks);
const result = await controller.findAvailable(undefined);
expect(result).toEqual({ data: mockFrameworks, count: 1 });
expect(service.findAvailable).toHaveBeenCalledWith(undefined);
});
it('should pass organizationId to service when user has an active org', async () => {
mockService.findAvailable.mockResolvedValue([]);
await controller.findAvailable('org_1');
expect(service.findAvailable).toHaveBeenCalledWith('org_1');
});
});
describe('delete', () => {
it('should delegate to service and return result', async () => {
mockService.delete.mockResolvedValue({ success: true });
const result = await controller.delete('org_1', 'fi1');
expect(result).toEqual({ success: true });
expect(service.delete).toHaveBeenCalledWith('fi1', 'org_1');
});
it('should propagate NotFoundException from service', async () => {
mockService.delete.mockRejectedValue(
new NotFoundException('Framework instance not found'),
);
await expect(controller.delete('org_1', 'missing')).rejects.toThrow(
NotFoundException,
);
});
});
});