@flusys/nestjs-auth 6.0.2 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/cjs/controllers/authentication.controller.spec.js +219 -0
  2. package/cjs/controllers/branch.controller.spec.js +134 -0
  3. package/cjs/controllers/company-selection.controller.spec.js +84 -0
  4. package/cjs/controllers/company.controller.spec.js +131 -0
  5. package/cjs/controllers/email-verification.controller.spec.js +142 -0
  6. package/cjs/controllers/user-permission.controller.spec.js +138 -0
  7. package/cjs/controllers/user.controller.spec.js +204 -0
  8. package/cjs/docs/auth-swagger.config.spec.js +130 -0
  9. package/cjs/entities/index.spec.js +73 -0
  10. package/cjs/helpers/auth-response.mapper.js +46 -0
  11. package/cjs/helpers/auth-response.mapper.spec.js +139 -0
  12. package/cjs/helpers/index.js +19 -0
  13. package/cjs/helpers/token.helper.js +58 -0
  14. package/cjs/helpers/token.helper.spec.js +86 -0
  15. package/cjs/index.js +1 -0
  16. package/cjs/interceptors/clear-token.interceptor.spec.js +107 -0
  17. package/cjs/interceptors/set-token.interceptor.spec.js +165 -0
  18. package/cjs/modules/auth.module.spec.js +243 -0
  19. package/cjs/services/auth-config.service.spec.js +97 -0
  20. package/cjs/services/auth-datasource.provider.spec.js +161 -0
  21. package/cjs/services/auth-email.service.spec.js +404 -0
  22. package/cjs/services/authentication.service.js +37 -109
  23. package/cjs/services/authentication.service.spec.js +904 -0
  24. package/cjs/services/branch.service.spec.js +154 -0
  25. package/cjs/services/company-selection-session.service.spec.js +90 -0
  26. package/cjs/services/company.service.spec.js +113 -0
  27. package/cjs/services/user-permission.service.spec.js +202 -0
  28. package/cjs/services/user.service.spec.js +704 -0
  29. package/cjs/strategies/jwt.strategy.js +1 -1
  30. package/cjs/strategies/jwt.strategy.spec.js +166 -0
  31. package/cjs/validators/password.validator.spec.js +161 -0
  32. package/entities/pending-registration.entity.d.ts +2 -7
  33. package/fesm/controllers/authentication.controller.spec.js +215 -0
  34. package/fesm/controllers/branch.controller.spec.js +130 -0
  35. package/fesm/controllers/company-selection.controller.spec.js +80 -0
  36. package/fesm/controllers/company.controller.spec.js +127 -0
  37. package/fesm/controllers/email-verification.controller.spec.js +138 -0
  38. package/fesm/controllers/user-permission.controller.spec.js +134 -0
  39. package/fesm/controllers/user.controller.spec.js +200 -0
  40. package/fesm/docs/auth-swagger.config.spec.js +126 -0
  41. package/fesm/entities/index.spec.js +69 -0
  42. package/fesm/helpers/auth-response.mapper.js +25 -0
  43. package/fesm/helpers/auth-response.mapper.spec.js +135 -0
  44. package/fesm/helpers/index.js +2 -0
  45. package/fesm/helpers/token.helper.js +40 -0
  46. package/fesm/helpers/token.helper.spec.js +82 -0
  47. package/fesm/index.js +1 -0
  48. package/fesm/interceptors/clear-token.interceptor.spec.js +103 -0
  49. package/fesm/interceptors/set-token.interceptor.spec.js +161 -0
  50. package/fesm/interfaces/authentication.interface.js +1 -1
  51. package/fesm/modules/auth.module.spec.js +239 -0
  52. package/fesm/services/auth-config.service.spec.js +93 -0
  53. package/fesm/services/auth-datasource.provider.spec.js +157 -0
  54. package/fesm/services/auth-email.service.spec.js +359 -0
  55. package/fesm/services/authentication.service.js +37 -109
  56. package/fesm/services/authentication.service.spec.js +859 -0
  57. package/fesm/services/branch.service.spec.js +150 -0
  58. package/fesm/services/company-selection-session.service.spec.js +86 -0
  59. package/fesm/services/company.service.spec.js +109 -0
  60. package/fesm/services/user-permission.service.spec.js +198 -0
  61. package/fesm/services/user.service.spec.js +659 -0
  62. package/fesm/strategies/jwt.strategy.js +1 -1
  63. package/fesm/strategies/jwt.strategy.spec.js +162 -0
  64. package/fesm/validators/password.validator.spec.js +157 -0
  65. package/helpers/auth-response.mapper.d.ts +22 -0
  66. package/helpers/index.d.ts +2 -0
  67. package/helpers/token.helper.d.ts +8 -0
  68. package/index.d.ts +1 -0
  69. package/interfaces/authentication.interface.d.ts +7 -0
  70. package/package.json +8 -3
  71. package/services/authentication.service.d.ts +1 -8
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _common = require("@nestjs/common");
6
+ const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
7
+ const _authenticationcontroller = require("./authentication.controller");
8
+ describe('AuthenticationController', ()=>{
9
+ let controller;
10
+ let mockAuthService;
11
+ let mockAuthConfig;
12
+ beforeEach(()=>{
13
+ mockAuthService = {
14
+ login: jest.fn(),
15
+ register: jest.fn(),
16
+ refreshToken: jest.fn(),
17
+ getUserInfo: jest.fn(),
18
+ logout: jest.fn(),
19
+ changePassword: jest.fn()
20
+ };
21
+ mockAuthConfig = {
22
+ getRefreshTokenCookieName: jest.fn().mockReturnValue('fsn_refresh_token')
23
+ };
24
+ controller = new _authenticationcontroller.AuthenticationController(mockAuthService, mockAuthConfig);
25
+ });
26
+ describe('login', ()=>{
27
+ it('wraps a standard login response', async ()=>{
28
+ mockAuthService.login.mockResolvedValue({
29
+ accessToken: 'a',
30
+ refreshToken: 'r',
31
+ user: {
32
+ id: 'u1',
33
+ email: 'u@example.com'
34
+ }
35
+ });
36
+ const result = await controller.login({
37
+ email: 'u@example.com',
38
+ password: 'pw'
39
+ });
40
+ expect(result).toEqual(expect.objectContaining({
41
+ success: true,
42
+ data: expect.objectContaining({
43
+ accessToken: 'a'
44
+ })
45
+ }));
46
+ expect(mockAuthService.login).toHaveBeenCalledWith('u@example.com', 'pw');
47
+ });
48
+ it('wraps a company-selection-required response', async ()=>{
49
+ mockAuthService.login.mockResolvedValue({
50
+ requiresSelection: true,
51
+ sessionId: 'sess-1'
52
+ });
53
+ const result = await controller.login({
54
+ email: 'u@example.com',
55
+ password: 'pw'
56
+ });
57
+ expect(result.message).toBe('Company selection required');
58
+ expect(result.data).toEqual(expect.objectContaining({
59
+ requiresSelection: true
60
+ }));
61
+ });
62
+ it('wraps an email-verification-required response', async ()=>{
63
+ mockAuthService.login.mockResolvedValue({
64
+ requiresEmailVerification: true,
65
+ email: 'u@example.com'
66
+ });
67
+ const result = await controller.login({
68
+ email: 'u@example.com',
69
+ password: 'pw'
70
+ });
71
+ expect(result.message).toBe('Email verification required');
72
+ expect(result.data).toEqual(expect.objectContaining({
73
+ requiresEmailVerification: true
74
+ }));
75
+ });
76
+ it('propagates errors thrown by the service', async ()=>{
77
+ mockAuthService.login.mockRejectedValue(new _common.UnauthorizedException('bad creds'));
78
+ await expect(controller.login({
79
+ email: 'u@example.com',
80
+ password: 'wrong'
81
+ })).rejects.toThrow(_common.UnauthorizedException);
82
+ });
83
+ });
84
+ describe('register', ()=>{
85
+ it('reports success message when registration completes without verification', async ()=>{
86
+ mockAuthService.register.mockResolvedValue({
87
+ accessToken: 'a',
88
+ user: {
89
+ id: 'u1'
90
+ },
91
+ requiresEmailVerification: false
92
+ });
93
+ const req = {
94
+ headers: {},
95
+ get: jest.fn((h)=>h === 'host' ? 'app.example.com' : undefined),
96
+ protocol: 'https'
97
+ };
98
+ const result = await controller.register(req, {
99
+ name: 'New',
100
+ email: 'new@example.com',
101
+ password: 'Password1!'
102
+ });
103
+ expect(result.message).toBe('Registration successful');
104
+ expect(result.success).toBe(true);
105
+ });
106
+ it('reports verification-sent message when email verification is required', async ()=>{
107
+ mockAuthService.register.mockResolvedValue({
108
+ requiresEmailVerification: true,
109
+ user: {
110
+ id: 'u1'
111
+ }
112
+ });
113
+ const req = {
114
+ headers: {},
115
+ get: jest.fn((h)=>h === 'host' ? 'app.example.com' : undefined),
116
+ protocol: 'https'
117
+ };
118
+ const result = await controller.register(req, {
119
+ name: 'New',
120
+ email: 'new@example.com',
121
+ password: 'Password1!'
122
+ });
123
+ expect(result.message).toBe('Verification email sent');
124
+ });
125
+ });
126
+ describe('refreshToken', ()=>{
127
+ it('reads the refresh token from the cookie first', async ()=>{
128
+ mockAuthService.refreshToken.mockResolvedValue({
129
+ accessToken: 'new-token'
130
+ });
131
+ const req = {
132
+ cookies: {
133
+ fsn_refresh_token: 'cookie-token'
134
+ }
135
+ };
136
+ await controller.refreshToken(req, {
137
+ refreshToken: 'body-token'
138
+ });
139
+ expect(mockAuthService.refreshToken).toHaveBeenCalledWith('cookie-token');
140
+ });
141
+ it('falls back to the request body when no cookie is present', async ()=>{
142
+ mockAuthService.refreshToken.mockResolvedValue({
143
+ accessToken: 'new-token'
144
+ });
145
+ const req = {
146
+ cookies: {}
147
+ };
148
+ await controller.refreshToken(req, {
149
+ refreshToken: 'body-token'
150
+ });
151
+ expect(mockAuthService.refreshToken).toHaveBeenCalledWith('body-token');
152
+ });
153
+ it('throws UnauthorizedException when no refresh token is available', async ()=>{
154
+ const req = {
155
+ cookies: {}
156
+ };
157
+ await expect(controller.refreshToken(req, {})).rejects.toThrow(_common.UnauthorizedException);
158
+ expect(mockAuthService.refreshToken).not.toHaveBeenCalled();
159
+ });
160
+ it('uses the default cookie name when authConfig is unavailable', async ()=>{
161
+ controller = new _authenticationcontroller.AuthenticationController(mockAuthService, undefined);
162
+ mockAuthService.refreshToken.mockResolvedValue({
163
+ accessToken: 'new-token'
164
+ });
165
+ const req = {
166
+ cookies: {
167
+ fsn_refresh_token: 'cookie-token'
168
+ }
169
+ };
170
+ await controller.refreshToken(req, {});
171
+ expect(mockAuthService.refreshToken).toHaveBeenCalledWith('cookie-token');
172
+ });
173
+ });
174
+ describe('getCurrentUser', ()=>{
175
+ it('delegates to authService.getUserInfo with the current user context', async ()=>{
176
+ mockAuthService.getUserInfo.mockResolvedValue({
177
+ user: {
178
+ id: 'u1'
179
+ }
180
+ });
181
+ const user = (0, _loggedusermock.buildMockUser)();
182
+ const result = await controller.getCurrentUser(user);
183
+ expect(mockAuthService.getUserInfo).toHaveBeenCalledWith(user.id, user.companyId, user.branchId);
184
+ expect(result.data).toEqual({
185
+ user: {
186
+ id: 'u1'
187
+ }
188
+ });
189
+ });
190
+ });
191
+ describe('logout', ()=>{
192
+ it('delegates to authService.logout and returns a success message', async ()=>{
193
+ const result = await controller.logout('user-1');
194
+ expect(mockAuthService.logout).toHaveBeenCalledWith('user-1');
195
+ expect(result).toEqual(expect.objectContaining({
196
+ success: true
197
+ }));
198
+ });
199
+ });
200
+ describe('changePassword', ()=>{
201
+ it('delegates to authService.changePassword', async ()=>{
202
+ const result = await controller.changePassword('user-1', {
203
+ currentPassword: 'old',
204
+ newPassword: 'New1!aaaa'
205
+ });
206
+ expect(mockAuthService.changePassword).toHaveBeenCalledWith('user-1', 'old', 'New1!aaaa');
207
+ expect(result).toEqual(expect.objectContaining({
208
+ success: true
209
+ }));
210
+ });
211
+ it('propagates errors from an invalid current password', async ()=>{
212
+ mockAuthService.changePassword.mockRejectedValue(new _common.UnauthorizedException());
213
+ await expect(controller.changePassword('user-1', {
214
+ currentPassword: 'wrong',
215
+ newPassword: 'New1!aaaa'
216
+ })).rejects.toThrow(_common.UnauthorizedException);
217
+ });
218
+ });
219
+ });
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
6
+ const _branchcontroller = require("./branch.controller");
7
+ function buildBranch(overrides = {}) {
8
+ return {
9
+ id: 'branch-1',
10
+ name: 'Main Branch',
11
+ slug: 'main-branch',
12
+ companyId: 'company-1',
13
+ parentId: null,
14
+ logoId: null,
15
+ address: null,
16
+ phone: null,
17
+ email: null,
18
+ serial: null,
19
+ isActive: true,
20
+ readOnly: false,
21
+ additionalFields: null,
22
+ createdAt: new Date(),
23
+ updatedAt: new Date(),
24
+ ...overrides
25
+ };
26
+ }
27
+ describe('BranchController', ()=>{
28
+ let controller;
29
+ let mockBranchService;
30
+ beforeEach(()=>{
31
+ mockBranchService = {
32
+ insert: jest.fn(),
33
+ insertMany: jest.fn(),
34
+ findById: jest.fn(),
35
+ findByIds: jest.fn(),
36
+ update: jest.fn(),
37
+ updateMany: jest.fn(),
38
+ bulkUpsert: jest.fn(),
39
+ getAll: jest.fn(),
40
+ delete: jest.fn()
41
+ };
42
+ controller = new _branchcontroller.BranchController(mockBranchService);
43
+ });
44
+ it('wires the injected service onto the generated controller base', ()=>{
45
+ expect(controller.branchService).toBe(mockBranchService);
46
+ expect(controller.service).toBe(mockBranchService);
47
+ });
48
+ describe('insert', ()=>{
49
+ it('creates a branch and returns the mapped response', async ()=>{
50
+ const user = (0, _loggedusermock.buildMockUser)();
51
+ const branch = buildBranch();
52
+ mockBranchService.insert.mockResolvedValue(branch);
53
+ const result = await controller.insert({
54
+ name: 'Main Branch',
55
+ slug: 'main-branch',
56
+ companyId: 'company-1'
57
+ }, user);
58
+ expect(mockBranchService.insert).toHaveBeenCalledWith({
59
+ name: 'Main Branch',
60
+ slug: 'main-branch',
61
+ companyId: 'company-1'
62
+ }, user);
63
+ expect(result.success).toBe(true);
64
+ expect(result.data).toEqual(expect.objectContaining({
65
+ id: 'branch-1',
66
+ slug: 'main-branch'
67
+ }));
68
+ });
69
+ });
70
+ describe('getById', ()=>{
71
+ it('retrieves a branch by id', async ()=>{
72
+ const branch = buildBranch();
73
+ mockBranchService.findById.mockResolvedValue(branch);
74
+ const result = await controller.getById('branch-1', {}, null);
75
+ expect(mockBranchService.findById).toHaveBeenCalledWith('branch-1', null, undefined);
76
+ expect(result.data).toEqual(expect.objectContaining({
77
+ id: 'branch-1'
78
+ }));
79
+ });
80
+ });
81
+ describe('getAll', ()=>{
82
+ it('paginates branches and maps the response list', async ()=>{
83
+ mockBranchService.getAll.mockResolvedValue({
84
+ data: [
85
+ buildBranch()
86
+ ],
87
+ total: 1
88
+ });
89
+ const result = await controller.getAll({}, (0, _loggedusermock.buildMockUser)(), 'main');
90
+ expect(mockBranchService.getAll).toHaveBeenCalledWith('main', {}, (0, _loggedusermock.buildMockUser)());
91
+ expect(result.data).toHaveLength(1);
92
+ expect(result.meta.total).toBe(1);
93
+ });
94
+ });
95
+ describe('update', ()=>{
96
+ it('updates a branch and returns the mapped response', async ()=>{
97
+ const branch = buildBranch({
98
+ name: 'Updated Branch'
99
+ });
100
+ mockBranchService.update.mockResolvedValue(branch);
101
+ const result = await controller.update({
102
+ id: 'branch-1',
103
+ name: 'Updated Branch'
104
+ }, (0, _loggedusermock.buildMockUser)());
105
+ expect(mockBranchService.update).toHaveBeenCalledWith({
106
+ id: 'branch-1',
107
+ name: 'Updated Branch'
108
+ }, (0, _loggedusermock.buildMockUser)());
109
+ expect(result.data).toEqual(expect.objectContaining({
110
+ name: 'Updated Branch'
111
+ }));
112
+ });
113
+ });
114
+ describe('delete', ()=>{
115
+ it('delegates soft-delete to the service', async ()=>{
116
+ mockBranchService.delete.mockResolvedValue({
117
+ count: 1
118
+ });
119
+ const result = await controller.delete({
120
+ id: [
121
+ 'branch-1'
122
+ ],
123
+ type: 'delete'
124
+ }, (0, _loggedusermock.buildMockUser)());
125
+ expect(mockBranchService.delete).toHaveBeenCalledWith({
126
+ id: [
127
+ 'branch-1'
128
+ ],
129
+ type: 'delete'
130
+ }, (0, _loggedusermock.buildMockUser)());
131
+ expect(result.success).toBe(true);
132
+ });
133
+ });
134
+ });
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _companyselectioncontroller = require("./company-selection.controller");
6
+ describe('CompanySelectionController', ()=>{
7
+ let controller;
8
+ let mockAuthService;
9
+ beforeEach(()=>{
10
+ mockAuthService = {
11
+ select: jest.fn(),
12
+ switchCompany: jest.fn(),
13
+ getUserCompanies: jest.fn(),
14
+ getUserBranches: jest.fn()
15
+ };
16
+ controller = new _companyselectioncontroller.CompanySelectionController(mockAuthService);
17
+ });
18
+ describe('select', ()=>{
19
+ it('completes login with the selected company/branch', async ()=>{
20
+ mockAuthService.select.mockResolvedValue({
21
+ accessToken: 'a'
22
+ });
23
+ const result = await controller.select({
24
+ sessionId: 'sess-1',
25
+ companyId: 'company-1',
26
+ branchId: 'branch-1'
27
+ });
28
+ expect(mockAuthService.select).toHaveBeenCalledWith('sess-1', 'company-1', 'branch-1');
29
+ expect(result).toEqual(expect.objectContaining({
30
+ success: true,
31
+ data: {
32
+ accessToken: 'a'
33
+ }
34
+ }));
35
+ });
36
+ });
37
+ describe('switchCompany', ()=>{
38
+ it('switches company for the authenticated user', async ()=>{
39
+ mockAuthService.switchCompany.mockResolvedValue({
40
+ accessToken: 'b'
41
+ });
42
+ const result = await controller.switchCompany('user-1', {
43
+ companyId: 'company-2',
44
+ branchId: 'branch-2'
45
+ });
46
+ expect(mockAuthService.switchCompany).toHaveBeenCalledWith('user-1', 'company-2', 'branch-2');
47
+ expect(result.data).toEqual({
48
+ accessToken: 'b'
49
+ });
50
+ });
51
+ });
52
+ describe('getUserCompanies', ()=>{
53
+ it('returns the companies the user has access to', async ()=>{
54
+ mockAuthService.getUserCompanies.mockResolvedValue([
55
+ {
56
+ id: 'company-1'
57
+ }
58
+ ]);
59
+ const result = await controller.getUserCompanies('user-1');
60
+ expect(mockAuthService.getUserCompanies).toHaveBeenCalledWith('user-1');
61
+ expect(result.data).toEqual([
62
+ {
63
+ id: 'company-1'
64
+ }
65
+ ]);
66
+ });
67
+ });
68
+ describe('getUserBranches', ()=>{
69
+ it('returns the branches for the given company', async ()=>{
70
+ mockAuthService.getUserBranches.mockResolvedValue([
71
+ {
72
+ id: 'branch-1'
73
+ }
74
+ ]);
75
+ const result = await controller.getUserBranches('user-1', 'company-1');
76
+ expect(mockAuthService.getUserBranches).toHaveBeenCalledWith('user-1', 'company-1');
77
+ expect(result.data).toEqual([
78
+ {
79
+ id: 'branch-1'
80
+ }
81
+ ]);
82
+ });
83
+ });
84
+ });
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
6
+ const _companycontroller = require("./company.controller");
7
+ function buildCompany(overrides = {}) {
8
+ return {
9
+ id: 'company-1',
10
+ name: 'Acme Corporation',
11
+ slug: 'acme-corp',
12
+ logoId: null,
13
+ address: null,
14
+ phone: null,
15
+ email: null,
16
+ website: null,
17
+ serial: null,
18
+ isActive: true,
19
+ readOnly: false,
20
+ settings: null,
21
+ additionalFields: null,
22
+ createdAt: new Date(),
23
+ updatedAt: new Date(),
24
+ ...overrides
25
+ };
26
+ }
27
+ describe('CompanyController', ()=>{
28
+ let controller;
29
+ let mockCompanyService;
30
+ beforeEach(()=>{
31
+ mockCompanyService = {
32
+ insert: jest.fn(),
33
+ insertMany: jest.fn(),
34
+ findById: jest.fn(),
35
+ findByIds: jest.fn(),
36
+ update: jest.fn(),
37
+ updateMany: jest.fn(),
38
+ bulkUpsert: jest.fn(),
39
+ getAll: jest.fn(),
40
+ delete: jest.fn()
41
+ };
42
+ controller = new _companycontroller.CompanyController(mockCompanyService);
43
+ });
44
+ it('wires the injected service onto the generated controller base', ()=>{
45
+ expect(controller.companyService).toBe(mockCompanyService);
46
+ expect(controller.service).toBe(mockCompanyService);
47
+ });
48
+ describe('insert', ()=>{
49
+ it('creates a company and returns the mapped response', async ()=>{
50
+ const user = (0, _loggedusermock.buildMockUser)();
51
+ const company = buildCompany();
52
+ mockCompanyService.insert.mockResolvedValue(company);
53
+ const result = await controller.insert({
54
+ name: 'Acme Corporation',
55
+ slug: 'acme-corp'
56
+ }, user);
57
+ expect(mockCompanyService.insert).toHaveBeenCalledWith({
58
+ name: 'Acme Corporation',
59
+ slug: 'acme-corp'
60
+ }, user);
61
+ expect(result.success).toBe(true);
62
+ expect(result.data).toEqual(expect.objectContaining({
63
+ id: 'company-1',
64
+ slug: 'acme-corp'
65
+ }));
66
+ });
67
+ });
68
+ describe('getById', ()=>{
69
+ it('retrieves a company by id', async ()=>{
70
+ mockCompanyService.findById.mockResolvedValue(buildCompany());
71
+ const result = await controller.getById('company-1', {}, null);
72
+ expect(mockCompanyService.findById).toHaveBeenCalledWith('company-1', null, undefined);
73
+ expect(result.data).toEqual(expect.objectContaining({
74
+ id: 'company-1'
75
+ }));
76
+ });
77
+ });
78
+ describe('getAll', ()=>{
79
+ it('paginates companies and maps the response list', async ()=>{
80
+ mockCompanyService.getAll.mockResolvedValue({
81
+ data: [
82
+ buildCompany()
83
+ ],
84
+ total: 1
85
+ });
86
+ const result = await controller.getAll({}, (0, _loggedusermock.buildMockUser)(), 'acme');
87
+ expect(mockCompanyService.getAll).toHaveBeenCalledWith('acme', {}, (0, _loggedusermock.buildMockUser)());
88
+ expect(result.data).toHaveLength(1);
89
+ expect(result.meta.total).toBe(1);
90
+ });
91
+ });
92
+ describe('update', ()=>{
93
+ it('updates a company and returns the mapped response', async ()=>{
94
+ const company = buildCompany({
95
+ name: 'Updated Co'
96
+ });
97
+ mockCompanyService.update.mockResolvedValue(company);
98
+ const result = await controller.update({
99
+ id: 'company-1',
100
+ name: 'Updated Co'
101
+ }, (0, _loggedusermock.buildMockUser)());
102
+ expect(mockCompanyService.update).toHaveBeenCalledWith({
103
+ id: 'company-1',
104
+ name: 'Updated Co'
105
+ }, (0, _loggedusermock.buildMockUser)());
106
+ expect(result.data).toEqual(expect.objectContaining({
107
+ name: 'Updated Co'
108
+ }));
109
+ });
110
+ });
111
+ describe('delete', ()=>{
112
+ it('delegates soft-delete to the service', async ()=>{
113
+ mockCompanyService.delete.mockResolvedValue({
114
+ count: 1
115
+ });
116
+ const result = await controller.delete({
117
+ id: [
118
+ 'company-1'
119
+ ],
120
+ type: 'delete'
121
+ }, (0, _loggedusermock.buildMockUser)());
122
+ expect(mockCompanyService.delete).toHaveBeenCalledWith({
123
+ id: [
124
+ 'company-1'
125
+ ],
126
+ type: 'delete'
127
+ }, (0, _loggedusermock.buildMockUser)());
128
+ expect(result.success).toBe(true);
129
+ });
130
+ });
131
+ });