@tomei/sso 0.34.10 → 0.34.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. package/.commitlintrc.json +22 -22
  2. package/.eslintrc +16 -16
  3. package/.eslintrc.js +35 -35
  4. package/.gitlab-ci.yml +16 -16
  5. package/.husky/commit-msg +15 -15
  6. package/.husky/pre-commit +7 -7
  7. package/.prettierrc +4 -4
  8. package/Jenkinsfile +57 -57
  9. package/README.md +23 -23
  10. package/__tests__/unit/components/group/group.spec.ts +79 -79
  11. package/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.ts +88 -88
  12. package/__tests__/unit/components/group-privilege/group-privilege.spec.ts +68 -68
  13. package/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.ts +66 -66
  14. package/__tests__/unit/components/group-system-access/group-system-access.spec.ts +83 -83
  15. package/__tests__/unit/components/login-user/l.spec.ts +746 -746
  16. package/__tests__/unit/components/login-user/login.spec.ts +1164 -1164
  17. package/__tests__/unit/components/password-hash/password-hash.service.spec.ts +31 -31
  18. package/__tests__/unit/components/system/system.spec.ts +254 -254
  19. package/__tests__/unit/components/system-privilege/system-privilege.spec.ts +83 -83
  20. package/__tests__/unit/components/user-group/user-group.spec.ts +86 -86
  21. package/__tests__/unit/components/user-object-privilege/user-object-privilege.spec.ts +78 -78
  22. package/__tests__/unit/components/user-privilege/user-privilege.spec.ts +72 -72
  23. package/__tests__/unit/components/user-system-access/user-system-access.spec.ts +89 -89
  24. package/__tests__/unit/redis-client/redis.service.spec.ts +23 -23
  25. package/__tests__/unit/session/session.service.spec.ts +47 -47
  26. package/__tests__/unit/system-privilege/system-privilage.spec.ts +91 -91
  27. package/coverage/clover.xml +1452 -1452
  28. package/coverage/coverage-final.json +47 -47
  29. package/coverage/lcov-report/base.css +224 -224
  30. package/coverage/lcov-report/block-navigation.js +87 -87
  31. package/coverage/lcov-report/components/group/group.repository.ts.html +117 -117
  32. package/coverage/lcov-report/components/group/group.ts.html +327 -327
  33. package/coverage/lcov-report/components/group/index.html +130 -130
  34. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.repository.ts.html +117 -117
  35. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.ts.html +321 -321
  36. package/coverage/lcov-report/components/group-object-privilege/index.html +130 -130
  37. package/coverage/lcov-report/components/group-privilege/group-privilege.repository.ts.html +117 -117
  38. package/coverage/lcov-report/components/group-privilege/group-privilege.ts.html +303 -303
  39. package/coverage/lcov-report/components/group-privilege/index.html +130 -130
  40. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.repository.ts.html +117 -117
  41. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.ts.html +327 -327
  42. package/coverage/lcov-report/components/group-reporting-user/index.html +130 -130
  43. package/coverage/lcov-report/components/group-system-access/group-system-access.repository.ts.html +117 -117
  44. package/coverage/lcov-report/components/group-system-access/group-system-access.ts.html +309 -309
  45. package/coverage/lcov-report/components/group-system-access/index.html +130 -130
  46. package/coverage/lcov-report/components/login-history/index.html +115 -115
  47. package/coverage/lcov-report/components/login-history/login-history.repository.ts.html +117 -117
  48. package/coverage/lcov-report/components/login-user/index.html +130 -130
  49. package/coverage/lcov-report/components/login-user/login-user.ts.html +5007 -5007
  50. package/coverage/lcov-report/components/login-user/user.repository.ts.html +117 -117
  51. package/coverage/lcov-report/components/password-hash/index.html +115 -115
  52. package/coverage/lcov-report/components/password-hash/password-hash.service.ts.html +126 -126
  53. package/coverage/lcov-report/components/system/index.html +130 -130
  54. package/coverage/lcov-report/components/system/system.repository.ts.html +117 -117
  55. package/coverage/lcov-report/components/system/system.ts.html +909 -909
  56. package/coverage/lcov-report/components/system-privilege/index.html +130 -130
  57. package/coverage/lcov-report/components/system-privilege/system-privilege.repository.ts.html +120 -120
  58. package/coverage/lcov-report/components/system-privilege/system-privilege.ts.html +390 -390
  59. package/coverage/lcov-report/components/user-group/index.html +130 -130
  60. package/coverage/lcov-report/components/user-group/user-group.repository.ts.html +117 -117
  61. package/coverage/lcov-report/components/user-group/user-group.ts.html +354 -354
  62. package/coverage/lcov-report/components/user-object-privilege/index.html +130 -130
  63. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.repository.ts.html +117 -117
  64. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.ts.html +312 -312
  65. package/coverage/lcov-report/components/user-privilege/index.html +130 -130
  66. package/coverage/lcov-report/components/user-privilege/user-privilege.repository.ts.html +117 -117
  67. package/coverage/lcov-report/components/user-privilege/user-privilege.ts.html +306 -306
  68. package/coverage/lcov-report/components/user-system-access/index.html +130 -130
  69. package/coverage/lcov-report/components/user-system-access/user-system-access.repository.ts.html +117 -117
  70. package/coverage/lcov-report/components/user-system-access/user-system-access.ts.html +312 -312
  71. package/coverage/lcov-report/enum/group-type.enum.ts.html +108 -108
  72. package/coverage/lcov-report/enum/index.html +160 -160
  73. package/coverage/lcov-report/enum/index.ts.html +93 -93
  74. package/coverage/lcov-report/enum/user-status.enum.ts.html +105 -105
  75. package/coverage/lcov-report/enum/yn.enum.ts.html +96 -96
  76. package/coverage/lcov-report/index.html +370 -370
  77. package/coverage/lcov-report/models/group-object-privilege.entity.ts.html +333 -333
  78. package/coverage/lcov-report/models/group-privilege.entity.ts.html +315 -315
  79. package/coverage/lcov-report/models/group-reporting-user.entity.ts.html +339 -339
  80. package/coverage/lcov-report/models/group-system-access.entity.ts.html +324 -324
  81. package/coverage/lcov-report/models/group.entity.ts.html +435 -435
  82. package/coverage/lcov-report/models/index.html +310 -310
  83. package/coverage/lcov-report/models/login-history.entity.ts.html +252 -252
  84. package/coverage/lcov-report/models/staff.entity.ts.html +411 -411
  85. package/coverage/lcov-report/models/system-privilege.entity.ts.html +354 -354
  86. package/coverage/lcov-report/models/system.entity.ts.html +423 -423
  87. package/coverage/lcov-report/models/user-group.entity.ts.html +354 -354
  88. package/coverage/lcov-report/models/user-object-privilege.entity.ts.html +330 -330
  89. package/coverage/lcov-report/models/user-privilege.entity.ts.html +315 -315
  90. package/coverage/lcov-report/models/user-system-access.entity.ts.html +315 -315
  91. package/coverage/lcov-report/models/user.entity.ts.html +522 -522
  92. package/coverage/lcov-report/prettify.css +1 -1
  93. package/coverage/lcov-report/prettify.js +2 -2
  94. package/coverage/lcov-report/redis-client/index.html +115 -115
  95. package/coverage/lcov-report/redis-client/redis.service.ts.html +240 -240
  96. package/coverage/lcov-report/session/index.html +115 -115
  97. package/coverage/lcov-report/session/session.service.ts.html +246 -246
  98. package/coverage/lcov-report/sorter.js +196 -196
  99. package/coverage/lcov.info +2490 -2490
  100. package/coverage/test-report.xml +128 -128
  101. package/create-sso-user.sql +39 -39
  102. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.d.ts +1 -0
  103. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js +71 -0
  104. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js.map +1 -0
  105. package/dist/__tests__/unit/components/login-user/login-user.spec.d.ts +0 -0
  106. package/dist/__tests__/unit/components/login-user/login-user.spec.js +6 -0
  107. package/dist/__tests__/unit/components/login-user/login-user.spec.js.map +1 -0
  108. package/dist/__tests__/unit/components/login-user/login.spec.js +0 -661
  109. package/dist/__tests__/unit/components/login-user/login.spec.js.map +1 -1
  110. package/dist/src/components/group/group.js +8 -2
  111. package/dist/src/components/group/group.js.map +1 -1
  112. package/dist/tsconfig.tsbuildinfo +1 -1
  113. package/jest.config.js +14 -14
  114. package/migrations/20240314080602-create-user-table.js +124 -124
  115. package/migrations/20240314080603-create-user-group-table.js +85 -85
  116. package/migrations/20240314080604-create-user-user-group-table.js +55 -55
  117. package/migrations/20240314080605-create-login-history-table.js +53 -53
  118. package/migrations/20240527064925-create-system-table.js +78 -78
  119. package/migrations/20240527064926-create-system-privilege-table.js +67 -67
  120. package/migrations/20240527065342-create-group-table.js +89 -89
  121. package/migrations/20240527065633-create-group-reporting-user-table.js +76 -76
  122. package/migrations/20240528011551-create-group-system-access-table.js +72 -72
  123. package/migrations/20240528023018-user-system-access-table.js +75 -75
  124. package/migrations/20240528032229-user-privilege-table.js +75 -75
  125. package/migrations/20240528063003-create-group-privilege-table.js +75 -75
  126. package/migrations/20240528063051-create-group-object-privilege-table.js +84 -84
  127. package/migrations/20240528063107-create-user-object-privilege-table.js +83 -83
  128. package/package.json +89 -89
  129. package/sampledotenv +7 -7
  130. package/sonar-project.properties +22 -22
  131. package/src/components/group/group.ts +9 -2
  132. package/tsconfig.build.json +5 -5
  133. package/tsconfig.json +22 -22
@@ -1,1164 +1,1164 @@
1
- import { SessionService } from '../../../../src/session/session.service';
2
- import { LoginUser } from '../../../../src/components/login-user/login-user';
3
- import { ApplicationConfig, ComponentConfig } from '@tomei/config';
4
- import { UserRepository } from '../../../../src/components/login-user/user.repository';
5
- import { ClassError } from '@tomei/general';
6
- import { Activity } from '@tomei/activity-history';
7
- import { UserStatus } from '../../../../src/enum/user-status.enum';
8
- import { YN } from '../../../../src/enum/yn.enum';
9
- import SystemPrivilegeModel from '../../../../src/models/system-privilege.entity';
10
- import { GroupSystemAccessRepository } from '../../../../src/components/group-system-access/group-system-access.repository';
11
- import { GroupRepository } from '../../../../src/components/group/group.repository';
12
-
13
- describe('LoginUser', () => {
14
- afterAll(() => {
15
- jest.restoreAllMocks();
16
- });
17
-
18
- describe('init', () => {
19
- let sessionService: any;
20
- let userId: number;
21
- let dbTransaction: any;
22
-
23
- beforeEach(() => {
24
- sessionService = {};
25
- userId = 1;
26
- dbTransaction = null;
27
- });
28
-
29
- it('should initialize LoginUser with valid userId', async () => {
30
- const user = {
31
- UserId: 1,
32
- FullName: 'John Doe',
33
- Email: 'john.doe@example.com',
34
- Password: 'password',
35
- Status: 'active',
36
- DefaultPasswordChangedYN: 'yes',
37
- FirstLoginAt: new Date(),
38
- LastLoginAt: new Date(),
39
- MFAEnabled: 1,
40
- MFAConfig: 'config',
41
- RecoveryEmail: 'john.doe@example.com',
42
- FailedLoginAttemptCount: 0,
43
- LastFailedLoginAt: null,
44
- LastPasswordChangedAt: new Date(),
45
- NeedToChangePasswordYN: 'no',
46
- CreatedById: 1,
47
- CreatedAt: new Date(),
48
- UpdatedById: 1,
49
- UpdatedAt: new Date(),
50
- Staff: {
51
- FullName: 'John Doe',
52
- IdNo: '1234567890',
53
- Mobile: '1234567890',
54
- },
55
- };
56
-
57
- const findOneMock = jest
58
- .spyOn(UserRepository.prototype, 'findOne')
59
- .mockResolvedValueOnce(user as any);
60
-
61
- const result = await LoginUser.init(
62
- sessionService,
63
- userId,
64
- dbTransaction,
65
- );
66
-
67
- expect(findOneMock).toHaveBeenCalledTimes(1);
68
- expect(findOneMock).toHaveBeenCalledWith({
69
- where: {
70
- UserId: userId,
71
- },
72
- include: [
73
- {
74
- model: expect.anything(),
75
- },
76
- ],
77
- });
78
- expect(result).toBeInstanceOf(LoginUser);
79
- expect(result.UserId).toBe(user.UserId);
80
- expect(result.FullName).toBe(user.FullName);
81
- expect(result.Email).toBe(user.Email);
82
- expect(result.Password).toBe(user.Password);
83
- expect(result.Status).toBe(user.Status);
84
- expect(result.DefaultPasswordChangedYN).toBe(
85
- user.DefaultPasswordChangedYN,
86
- );
87
- expect(result.FirstLoginAt).toBe(user.FirstLoginAt);
88
- expect(result.LastLoginAt).toBe(user.LastLoginAt);
89
- expect(result.MFAEnabled).toBe(user.MFAEnabled);
90
- expect(result.MFAConfig).toBe(user.MFAConfig);
91
- expect(result.RecoveryEmail).toBe(user.RecoveryEmail);
92
- expect(result.FailedLoginAttemptCount).toBe(user.FailedLoginAttemptCount);
93
- expect(result.LastFailedLoginAt).toBe(user.LastFailedLoginAt);
94
- expect(result.LastPasswordChangedAt).toBe(user.LastPasswordChangedAt);
95
- expect(result.NeedToChangePasswordYN).toBe(user.NeedToChangePasswordYN);
96
- expect(result.CreatedById).toBe(user.CreatedById);
97
- expect(result.CreatedAt).toBe(user.CreatedAt);
98
- expect(result.UpdatedById).toBe(user.UpdatedById);
99
- expect(result.UpdatedAt).toBe(user.UpdatedAt);
100
- });
101
-
102
- it('should throw an error when user is not found', async () => {
103
- const findOneMock = jest
104
- .spyOn(UserRepository.prototype, 'findOne')
105
- .mockResolvedValueOnce(null);
106
-
107
- await expect(
108
- LoginUser.init(sessionService, userId, dbTransaction),
109
- ).rejects.toThrow(Error);
110
-
111
- expect(findOneMock).toHaveBeenCalledTimes(1);
112
- expect(findOneMock).toHaveBeenCalledWith({
113
- where: {
114
- UserId: userId,
115
- },
116
- include: [
117
- {
118
- model: expect.anything(),
119
- },
120
- ],
121
- });
122
- });
123
- });
124
-
125
- // describe('checkSession', () => {
126
- // it('should throw an error if session expired', async () => {
127
- // // Arrange
128
- // const systemCode = 'EZC';
129
- // const sessionId = 'ckymxuh8t000137t011w89zgk';
130
- // const userId = '755';
131
- // const sessionService = await SessionService.init();
132
- // const loginUser = await LoginUser.init(sessionService);
133
-
134
- // // Act
135
- // const checkSessionPromise = loginUser.checkSession(
136
- // systemCode,
137
- // sessionId,
138
- // userId,
139
- // );
140
-
141
- // // Assert
142
- // await expect(checkSessionPromise).rejects.toThrow('Session expired.');
143
- // });
144
-
145
- // it('should refresh the session duration if session is valid', async () => {
146
- // // Arrange
147
- // const systemCode = 'EZC';
148
- // const sessionId = 'ckymxuh8t000137t011w89zgk';
149
- // const userId = '755';
150
- // const sessionService = await SessionService.init();
151
- // const loginUser = await LoginUser.init(sessionService);
152
-
153
- // // Mock the _SessionService.retrieveUserSession method
154
- // loginUser['_SessionService'].retrieveUserSession = jest
155
- // .fn()
156
- // .mockResolvedValue({
157
- // systemLogins: [
158
- // {
159
- // code: systemCode,
160
- // sessionId: sessionId,
161
- // privileges: [],
162
- // },
163
- // ],
164
- // });
165
-
166
- // // Mock the _SessionService.refreshDuration method
167
- // loginUser['_SessionService'].refreshDuration = jest.fn();
168
-
169
- // // Act
170
- // const systemLogin = await loginUser.checkSession(
171
- // systemCode,
172
- // sessionId,
173
- // userId,
174
- // );
175
-
176
- // // Assert
177
- // expect(
178
- // loginUser['_SessionService'].retrieveUserSession,
179
- // ).toHaveBeenCalledWith(userId);
180
- // expect(loginUser['_SessionService'].refreshDuration).toHaveBeenCalledWith(
181
- // userId,
182
- // );
183
- // expect(systemLogin).toEqual({
184
- // code: systemCode,
185
- // sessionId: sessionId,
186
- // privileges: [],
187
- // });
188
- // });
189
- // });
190
-
191
- describe('shouldReleaseLock', () => {
192
- const minuteToAutoRelease = 5;
193
- const autoReleaseYN = 'Y';
194
-
195
- beforeEach(() => {
196
- jest
197
- .spyOn(ComponentConfig, 'getComponentConfigValue')
198
- .mockImplementation((componentName: string, configKey: string) => {
199
- if (configKey === 'minuteToAutoRelease') {
200
- return minuteToAutoRelease as any;
201
- }
202
- if (configKey === 'autoReleaseYN') {
203
- return autoReleaseYN as any;
204
- }
205
- });
206
- });
207
-
208
- it('should return true if autoReleaseYN is "Y" and time difference is greater than minuteToAutoRelease', async () => {
209
- // Arrange
210
- const lastFailedLoginAt = new Date();
211
- lastFailedLoginAt.setMinutes(lastFailedLoginAt.getMinutes() - 10); // Set last failed login time to 10 minutes ago
212
- // Act
213
- const result = LoginUser.shouldReleaseLock(lastFailedLoginAt);
214
-
215
- // Assert
216
- expect(result).toBe(true);
217
- });
218
-
219
- it('should return false if autoReleaseYN is "Y" and time difference is less than or equal to minuteToAutoRelease', async () => {
220
- // Arrange
221
- const lastFailedLoginAt = new Date();
222
- lastFailedLoginAt.setMinutes(lastFailedLoginAt.getMinutes() - 3); // Set last failed login time to 3 minutes ago
223
-
224
- // Act
225
- const result = LoginUser.shouldReleaseLock(lastFailedLoginAt);
226
-
227
- // Assert
228
- expect(result).toBe(false);
229
- });
230
-
231
- it('should return false if autoReleaseYN is "N"', async () => {
232
- // Arrange
233
- const lastFailedLoginAt = new Date();
234
-
235
- // Act
236
- const result = LoginUser.shouldReleaseLock(lastFailedLoginAt);
237
-
238
- // Assert
239
- expect(result).toBe(false);
240
- });
241
- });
242
-
243
- describe('releaseLock', () => {
244
- it('should release the lock for a user', async () => {
245
- // Mock the necessary dependencies and setup the test data
246
- const UserId = 1;
247
- const dbTransaction = null;
248
-
249
- const updateMock = jest
250
- .spyOn(LoginUser['_Repository'], 'update')
251
- .mockImplementationOnce(() => Promise.resolve({}) as any);
252
-
253
- // Call the method under test
254
- LoginUser['releaseLock'](UserId, dbTransaction);
255
-
256
- // Verify the expected behavior
257
- expect(updateMock).toHaveBeenCalledTimes(1);
258
- expect(updateMock).toHaveBeenCalledWith(
259
- {
260
- FailedLoginAttemptCount: 0,
261
- Status: 'Active',
262
- },
263
- {
264
- where: {
265
- UserId,
266
- },
267
- transaction: dbTransaction,
268
- },
269
- );
270
- });
271
- });
272
-
273
- describe('checkUserInfoDuplicated', () => {
274
- it('should throw an error if duplicate user info is found', async () => {
275
- // Mock the dependencies and setup the test data
276
- const dbTransaction = null;
277
- const query = {
278
- Email: 'test@example.com',
279
- IdType: 'passport',
280
- IdNo: '123456789',
281
- ContactNo: '1234567890',
282
- };
283
-
284
- // Mock the LoginUser['_Repository'].findAll method to return a user
285
- jest
286
- .spyOn(LoginUser['_Repository'], 'findAll')
287
- .mockResolvedValueOnce([{ id: 1 }] as any);
288
-
289
- // Assert that the method throws an error
290
- await expect(
291
- LoginUser['checkUserInfoDuplicated'](dbTransaction, query),
292
- ).rejects.toThrowError();
293
- });
294
-
295
- it('should not throw an error if duplicate user info is not found', async () => {
296
- // Mock the dependencies and setup the test data
297
- const dbTransaction = null;
298
- const query = {
299
- Email: 'test@example.com',
300
- IdType: 'passport',
301
- IdNo: '123456789',
302
- ContactNo: '1234567890',
303
- };
304
-
305
- // Mock the LoginUser['_Repository'].findAll method to return an empty array
306
- jest.spyOn(LoginUser['_Repository'], 'findAll').mockResolvedValueOnce([]);
307
-
308
- // Assert that the method does not throw an error
309
- await expect(
310
- LoginUser['checkUserInfoDuplicated'](dbTransaction, query),
311
- ).resolves.not.toThrowError();
312
- });
313
- });
314
-
315
- describe('generateDefaultPassword', () => {
316
- const passwordPolicy = {
317
- minLen: 6,
318
- maxLen: 10,
319
- nonAcceptableChar: 'i,l,o',
320
- numOfCapitalLetters: 1,
321
- numOfNumbers: 1,
322
- numOfSpecialChars: 1,
323
- };
324
- beforeEach(() => {
325
- jest
326
- .spyOn(ComponentConfig, 'getComponentConfigValue')
327
- .mockImplementation((componentName: string, configKey: string) => {
328
- if (configKey === 'passwordPolicy') {
329
- return passwordPolicy as any;
330
- }
331
- });
332
- });
333
-
334
- it('should generate a default password with the specified length', () => {
335
- const password = LoginUser['generateDefaultPassword']();
336
- expect(password.length).toBeGreaterThanOrEqual(6);
337
- expect(password.length).toBeLessThanOrEqual(10);
338
- });
339
-
340
- it('should generate a default password with at least one capital letter', () => {
341
- const password = LoginUser['generateDefaultPassword']();
342
- expect(/[A-Z]/.test(password)).toBe(true);
343
- });
344
-
345
- it('should generate a default password with at least one number', () => {
346
- const password = LoginUser['generateDefaultPassword']();
347
- expect(/[0-9]/.test(password)).toBe(true);
348
- });
349
-
350
- it('should generate a default password with at least one special character', () => {
351
- const password = LoginUser['generateDefaultPassword']();
352
- expect(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?~`]/.test(password)).toBe(true);
353
- });
354
-
355
- it('should generate a default password without any non-acceptable characters', () => {
356
- const password = LoginUser['generateDefaultPassword']();
357
- const nonAcceptableChars = ['i', 'l', 'o'];
358
- expect(nonAcceptableChars.some((char) => password.includes(char))).toBe(
359
- false,
360
- );
361
- });
362
- });
363
-
364
- describe('setPassword', () => {
365
- const passwordPolicy = {
366
- minLen: 6,
367
- maxLen: 10,
368
- nonAcceptableChar: 'i,l,o',
369
- numOfCapitalLetters: 1,
370
- numOfNumbers: 1,
371
- numOfSpecialChars: 1,
372
- };
373
- beforeEach(() => {
374
- jest
375
- .spyOn(ComponentConfig, 'getComponentConfigValue')
376
- .mockImplementation((componentName: string, configKey: string) => {
377
- if (configKey === 'passwordPolicy') {
378
- return passwordPolicy as any;
379
- }
380
- });
381
- });
382
-
383
- it('should set the password for the user', async () => {
384
- // Arrange
385
- const dbTransaction = null;
386
- const sessionService = await SessionService.init();
387
- const user = await LoginUser.init(sessionService);
388
- const password = 'N3wP@ssw0';
389
-
390
- // Act
391
- const result = await LoginUser['setPassword'](
392
- dbTransaction,
393
- user,
394
- password,
395
- );
396
-
397
- // Assert
398
- expect(result).toBeInstanceOf(LoginUser);
399
- await expect(
400
- LoginUser['setPassword'](dbTransaction, user, password),
401
- ).resolves.not.toThrowError();
402
- expect(result.Password).toBeDefined();
403
- });
404
-
405
- it('should throw an error if the password does not meet the security requirements', async () => {
406
- // Arrange
407
- const dbTransaction = null;
408
- const sessionService = await SessionService.init();
409
- const user = await LoginUser.init(sessionService);
410
- const password = 'weakpassword';
411
-
412
- // Act & Assert
413
- await expect(
414
- LoginUser['setPassword'](dbTransaction, user, password),
415
- ).rejects.toThrow();
416
- });
417
- });
418
-
419
- // describe('create', () => {
420
- // let loginUser: LoginUser;
421
- // let dbTransaction: any;
422
- // let user: LoginUser;
423
- // let newUser: any;
424
-
425
- // beforeEach(async () => {
426
- // const sessionService = await SessionService.init();
427
- // loginUser = await LoginUser.init(sessionService);
428
- // dbTransaction = null;
429
- // newUser = {
430
- // UserId: 1,
431
- // FullName: 'John Doe',
432
- // Email: 'john.doe@example.com',
433
- // Password: 'password',
434
- // Status: 'Active',
435
- // DefaultPasswordChangedYN: 'N',
436
- // FirstLoginAt: null,
437
- // LastLoginAt: null,
438
- // MFAEnabled: null,
439
- // MFAConfig: null,
440
- // RecoveryEmail: null,
441
- // FailedLoginAttemptCount: 0,
442
- // LastFailedLoginAt: null,
443
- // LastPasswordChangedAt: new Date(),
444
- // NeedToChangePasswordYN: 'N',
445
- // CreatedById: 1,
446
- // CreatedAt: new Date(),
447
- // UpdatedById: 1,
448
- // UpdatedAt: new Date(),
449
- // Staff: {
450
- // FullName: 'John Doe',
451
- // IdNo: '1234567890',
452
- // Mobile: '1234567890',
453
- // },
454
- // };
455
- // user = new (LoginUser as any)(sessionService, null, newUser);
456
- // });
457
-
458
- // afterEach(() => {
459
- // jest.clearAllMocks();
460
- // });
461
-
462
- // it('should create a new user record', async () => {
463
- // const checkPrivilegesMock = jest
464
- // .spyOn(loginUser, 'checkPrivileges')
465
- // .mockResolvedValueOnce(true);
466
-
467
- // const checkUserInfoDuplicatedMock = jest
468
- // .spyOn(LoginUser as any, 'checkUserInfoDuplicated')
469
- // .mockResolvedValueOnce(undefined);
470
-
471
- // const generateDefaultPasswordMock = jest
472
- // .spyOn(LoginUser as any, 'generateDefaultPassword')
473
- // .mockReturnValueOnce('defaultPassword');
474
-
475
- // const setPasswordMock = jest
476
- // .spyOn(LoginUser as any, 'setPassword')
477
- // .mockResolvedValueOnce(user);
478
-
479
- // const createMock = jest
480
- // .spyOn((LoginUser as any)['_Repository'], 'create')
481
- // .mockResolvedValueOnce({
482
- // ...newUser,
483
- // get: () => newUser,
484
- // });
485
-
486
- // const activityCreateMock = jest
487
- // .spyOn((Activity as any).prototype, 'create')
488
- // .mockResolvedValueOnce(undefined);
489
-
490
- // jest
491
- // .spyOn(ApplicationConfig, 'getComponentConfigValue')
492
- // .mockImplementation((configKey: string) => {
493
- // if (configKey === 'system-code') {
494
- // return 'SC';
495
- // }
496
- // });
497
-
498
- // const result = await LoginUser.create(loginUser, dbTransaction, user);
499
-
500
- // expect(checkPrivilegesMock).toHaveBeenCalledTimes(1);
501
- // expect(checkPrivilegesMock).toHaveBeenCalledWith(
502
- // ApplicationConfig.getComponentConfigValue('system-code'),
503
- // 'User - Create',
504
- // );
505
-
506
- // expect(checkUserInfoDuplicatedMock).toHaveBeenCalledTimes(1);
507
- // expect(checkUserInfoDuplicatedMock).toHaveBeenCalledWith(dbTransaction, {
508
- // Email: user.Email,
509
- // IdType: user.IDType,
510
- // IdNo: user.IDNo,
511
- // ContactNo: user.ContactNo,
512
- // });
513
-
514
- // expect(generateDefaultPasswordMock).toHaveBeenCalledTimes(1);
515
-
516
- // expect(setPasswordMock).toHaveBeenCalledTimes(1);
517
- // expect(setPasswordMock).toHaveBeenCalledWith(
518
- // dbTransaction,
519
- // user,
520
- // 'defaultPassword',
521
- // );
522
-
523
- // expect(createMock).toHaveBeenCalledTimes(1);
524
-
525
- // const userInfo = {
526
- // FullName: user.FullName,
527
- // IDNo: user.IDNo,
528
- // Email: user.Email,
529
- // ContactNo: user.ContactNo,
530
- // Password: user.Password,
531
- // Status: UserStatus.ACTIVE,
532
- // FirstLoginAt: null,
533
- // LastLoginAt: null,
534
- // MFAEnabled: null,
535
- // MFAConfig: null,
536
- // RecoveryEmail: null,
537
- // FailedLoginAttemptCount: 0,
538
- // LastFailedLoginAt: null,
539
- // LastPasswordChangedAt: null,
540
- // DefaultPasswordChangedYN: YN.No,
541
- // NeedToChangePasswordYN: YN.Yes,
542
- // CreatedById: loginUser.UserId,
543
- // CreatedAt: new Date(),
544
- // UpdatedById: loginUser.UserId,
545
- // UpdatedAt: new Date(),
546
- // UserId: null,
547
- // };
548
-
549
- // expect(createMock).toHaveBeenCalledWith(
550
- // {
551
- // Email: userInfo.Email,
552
- // Password: userInfo.Password,
553
- // Status: userInfo.Status,
554
- // DefaultPasswordChangedYN: userInfo.DefaultPasswordChangedYN,
555
- // FirstLoginAt: userInfo.FirstLoginAt,
556
- // LastLoginAt: userInfo.LastLoginAt,
557
- // MFAEnabled: userInfo.MFAEnabled,
558
- // MFAConfig: userInfo.MFAConfig,
559
- // RecoveryEmail: userInfo.RecoveryEmail,
560
- // FailedLoginAttemptCount: userInfo.FailedLoginAttemptCount,
561
- // LastFailedLoginAt: userInfo.LastFailedLoginAt,
562
- // LastPasswordChangedAt: userInfo.LastPasswordChangedAt,
563
- // NeedToChangePasswordYN: userInfo.NeedToChangePasswordYN,
564
- // CreatedById: userInfo.CreatedById,
565
- // CreatedAt: expect.any(Date),
566
- // UpdatedById: userInfo.UpdatedById,
567
- // UpdatedAt: expect.any(Date),
568
- // },
569
- // {
570
- // transaction: dbTransaction,
571
- // },
572
- // );
573
-
574
- // expect(activityCreateMock).toHaveBeenCalledTimes(1);
575
-
576
- // expect(result).toBeInstanceOf(LoginUser);
577
- // expect(result.Email).toBe(userInfo.Email);
578
- // expect(result.Password).toBe(userInfo.Password);
579
- // expect(result.Status).toBe(userInfo.Status);
580
- // expect(result.DefaultPasswordChangedYN).toBe(
581
- // userInfo.DefaultPasswordChangedYN,
582
- // );
583
- // expect(result.FirstLoginAt).toBe(null);
584
- // expect(result.LastLoginAt).toBe(null);
585
- // expect(result.MFAEnabled).toBe(userInfo.MFAEnabled);
586
- // expect(result.MFAConfig).toBe(userInfo.MFAConfig);
587
- // expect(result.RecoveryEmail).toBe(userInfo.RecoveryEmail);
588
- // expect(result.FailedLoginAttemptCount).toBe(
589
- // userInfo.FailedLoginAttemptCount,
590
- // );
591
- // expect(result.LastFailedLoginAt).toBe(userInfo.LastFailedLoginAt);
592
- // expect(result.LastPasswordChangedAt).toBe(userInfo.LastPasswordChangedAt);
593
- // expect(result.NeedToChangePasswordYN).toBe(
594
- // userInfo.NeedToChangePasswordYN,
595
- // );
596
- // expect(result.CreatedById).toBe(userInfo.CreatedById);
597
- // expect(result.UpdatedById).toBe(userInfo.UpdatedById);
598
- // });
599
-
600
- // it('should throw an error if user dont have the privilege to create new user', async () => {
601
- // jest.spyOn(loginUser, 'checkPrivileges').mockResolvedValueOnce(false);
602
-
603
- // await expect(
604
- // LoginUser.create(loginUser, dbTransaction, user),
605
- // ).rejects.toThrow(ClassError);
606
- // });
607
-
608
- // it('should throw an error if user email is missing', async () => {
609
- // user.Email = undefined;
610
-
611
- // jest.spyOn(loginUser, 'checkPrivileges').mockResolvedValueOnce(true);
612
-
613
- // await expect(
614
- // LoginUser.create(loginUser, dbTransaction, user),
615
- // ).rejects.toThrow(ClassError);
616
- // });
617
- // });
618
-
619
- describe('incrementFailedLoginAttemptCount', () => {
620
- afterAll(() => {
621
- jest.restoreAllMocks();
622
- });
623
-
624
- it('should increment FailedLoginAttemptCount and update user status', async () => {
625
- // Arrange
626
- const sessionService = await SessionService.init();
627
- const loginUser = await LoginUser.init(sessionService);
628
- loginUser['FailedLoginAttemptCount'] = 2;
629
- loginUser['LastFailedLoginAt'] = new Date();
630
- loginUser['Status'] = UserStatus.ACTIVE;
631
-
632
- const dbTransaction = null;
633
-
634
- // Mock the static methods and properties
635
- jest
636
- .spyOn((LoginUser as any)['_Repository'], 'update')
637
- .mockReturnValueOnce(null);
638
-
639
- jest
640
- .spyOn(ComponentConfig, 'getComponentConfigValue')
641
- .mockImplementation((componentName: string, configKey: string) => {
642
- if (configKey === 'maxFailedLoginAttempts') {
643
- return 3;
644
- }
645
- if (configKey === 'autoReleaseYN') {
646
- return 'Y';
647
- }
648
- });
649
-
650
- // Act
651
- await loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
652
-
653
- // Assert
654
- expect(LoginUser['_Repository'].update).toHaveBeenCalledWith(
655
- {
656
- FailedLoginAttemptCount: 3,
657
- LastFailedLoginAt: expect.any(Date),
658
- Status: UserStatus.ACTIVE,
659
- },
660
- {
661
- where: {
662
- UserId: loginUser.UserId,
663
- },
664
- transaction: dbTransaction,
665
- },
666
- );
667
- });
668
-
669
- it('should throw an error if maxFailedLoginAttempts or autoReleaseYN is missing', async () => {
670
- // Arrange
671
- const sessionService = await SessionService.init();
672
- const loginUser = await LoginUser.init(sessionService);
673
- loginUser['FailedLoginAttemptCount'] = 2;
674
- loginUser['LastFailedLoginAt'] = new Date();
675
- loginUser['Status'] = UserStatus.ACTIVE;
676
-
677
- const dbTransaction = null;
678
-
679
- // Mock the static methods and properties
680
- jest
681
- .spyOn((LoginUser as any)['_Repository'], 'update')
682
- .mockReturnValueOnce(null);
683
-
684
- jest
685
- .spyOn(ComponentConfig, 'getComponentConfigValue')
686
- .mockImplementationOnce((componentName: string, configKey: string) => {
687
- if (configKey === 'maxFailedLoginAttempts') {
688
- return undefined;
689
- }
690
- if (configKey === 'autoReleaseYN') {
691
- return undefined;
692
- }
693
- });
694
-
695
- // Act and Assert
696
- await expect(
697
- loginUser['incrementFailedLoginAttemptCount'](dbTransaction),
698
- ).rejects.toThrow(
699
- new ClassError(
700
- 'LoginUser',
701
- 'LoginUserErrMsg0X',
702
- 'Missing maxFailedLoginAttempts and or autoReleaseYN. Please set in config file.',
703
- ),
704
- );
705
- });
706
-
707
- it('should lock the user account if the failed login attempts exceed the maximum allowed', async () => {
708
- // Arrange
709
- const sessionService = await SessionService.init();
710
- const loginUser = await LoginUser.init(sessionService);
711
- loginUser['FailedLoginAttemptCount'] = 3;
712
- loginUser['LastFailedLoginAt'] = new Date();
713
- loginUser['Status'] = UserStatus.ACTIVE;
714
-
715
- const dbTransaction = null;
716
-
717
- // Mock the static methods and properties
718
- jest
719
- .spyOn((LoginUser as any)['_Repository'], 'update')
720
- .mockReturnValueOnce(null);
721
-
722
- jest
723
- .spyOn(ComponentConfig, 'getComponentConfigValue')
724
- .mockImplementation((componentName: string, configKey: string) => {
725
- if (configKey === 'maxFailedLoginAttempts') {
726
- return 3;
727
- }
728
- if (configKey === 'autoReleaseYN') {
729
- return 'Y';
730
- }
731
- });
732
-
733
- // Act
734
- try {
735
- await loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
736
- expect(false).toBe(true);
737
- } catch (error) {
738
- // Assert
739
- expect(LoginUser['_Repository'].update).toHaveBeenCalledWith(
740
- {
741
- FailedLoginAttemptCount: 4,
742
- LastFailedLoginAt: expect.any(Date),
743
- Status: UserStatus.LOCKED,
744
- },
745
- {
746
- where: {
747
- UserId: loginUser.UserId,
748
- },
749
- transaction: dbTransaction,
750
- },
751
- );
752
- expect(error).toBeInstanceOf(ClassError);
753
- expect(error.message).toBe(
754
- 'Your account has been temporarily locked due to too many failed login attempts, please try again later.',
755
- );
756
- }
757
- });
758
-
759
- it('should permanently lock the user account if the failed login attempts exceed the maximum allowed and autoReleaseYN is N', async () => {
760
- // Arrange
761
- const sessionService = await SessionService.init();
762
- const loginUser = await LoginUser.init(sessionService);
763
- loginUser['FailedLoginAttemptCount'] = 3;
764
- loginUser['LastFailedLoginAt'] = new Date();
765
- loginUser['Status'] = UserStatus.ACTIVE;
766
-
767
- const dbTransaction = null;
768
-
769
- // Mock the static methods and properties
770
- jest
771
- .spyOn((LoginUser as any)['_Repository'], 'update')
772
- .mockReturnValueOnce(null);
773
-
774
- jest
775
- .spyOn(ComponentConfig, 'getComponentConfigValue')
776
- .mockImplementation((componentName: string, configKey: string) => {
777
- if (configKey === 'maxFailedLoginAttempts') {
778
- return 3;
779
- }
780
- if (configKey === 'autoReleaseYN') {
781
- return 'N';
782
- }
783
- });
784
-
785
- // Act
786
- try {
787
- await loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
788
- expect(false).toBe(true);
789
- } catch (error) {
790
- // Assert
791
- expect(LoginUser['_Repository'].update).toHaveBeenCalledWith(
792
- {
793
- FailedLoginAttemptCount: 4,
794
- LastFailedLoginAt: expect.any(Date),
795
- Status: UserStatus.LOCKED,
796
- },
797
- {
798
- where: {
799
- UserId: loginUser.UserId,
800
- },
801
- transaction: dbTransaction,
802
- },
803
- );
804
- expect(error).toBeInstanceOf(ClassError);
805
- expect(error.message).toBe(
806
- 'Your account has been locked due to too many failed login attempts, please contact IT Support for instructions on how to unlock your account',
807
- );
808
- }
809
- });
810
- });
811
-
812
- describe('combineSystemAccess', () => {
813
- it('should combine user and group system access and remove duplicates', async () => {
814
- // Mock the necessary dependencies
815
- const sessionService = await SessionService.init();
816
- const loginUser = await LoginUser.init(sessionService);
817
- const dbTransaction = null;
818
- const groups = [
819
- { InheritParentSystemAccessYN: true },
820
- { InheritParentSystemAccessYN: false },
821
- ];
822
-
823
- // Mock the necessary repository methods
824
- jest
825
- .spyOn(LoginUser as any, 'getInheritedSystemAccess')
826
- .mockResolvedValueOnce([
827
- { SystemCode: 'system1' },
828
- { SystemCode: 'system2' },
829
- ]);
830
- jest
831
- .spyOn((LoginUser as any)['_UserSystemAccessRepo'], 'findAll')
832
- .mockResolvedValueOnce([{ SystemCode: 'system3' }]);
833
-
834
- // Call the method
835
- const result = await LoginUser['combineSystemAccess'](
836
- loginUser,
837
- dbTransaction,
838
- groups,
839
- );
840
-
841
- // Assert the result
842
- expect(result).toEqual([
843
- { SystemCode: 'system3' },
844
- { SystemCode: 'system1' },
845
- { SystemCode: 'system2' },
846
- ]);
847
- });
848
- });
849
-
850
- describe('checkPrivileges', () => {
851
- it('should return true if user has the specified privilege', async () => {
852
- // Arrange
853
- const systemCode = 'SS';
854
- const privilegeName = 'Privilege 1';
855
- const sessionService = await SessionService.init();
856
- const loginUser = await LoginUser.init(sessionService);
857
- loginUser.ObjectId = '1';
858
-
859
- // Mock the necessary methods
860
- const rus = jest
861
- .spyOn(SessionService.prototype, 'retrieveUserSession')
862
- .mockResolvedValueOnce({
863
- systemLogins: [
864
- {
865
- id: '1',
866
- sessionId: 'sessionId',
867
- code: systemCode,
868
- privileges: [privilegeName],
869
- },
870
- ],
871
- });
872
- // Act
873
- const hasPrivilege = await loginUser.checkPrivileges(
874
- systemCode,
875
- privilegeName,
876
- );
877
-
878
- // Assert
879
- expect(hasPrivilege).toBe(true);
880
- expect(rus).toHaveBeenCalledWith(loginUser.ObjectId);
881
- });
882
-
883
- it('should return false if user does not have the specified privilege', async () => {
884
- // Arrange
885
- const systemCode = 'SS';
886
- const privilegeName = 'Privilege 1';
887
- const sessionService = await SessionService.init();
888
- const loginUser = await LoginUser.init(sessionService);
889
- loginUser.ObjectId = '1';
890
-
891
- // Mock the necessary methods
892
- const rus = jest
893
- .spyOn(SessionService.prototype, 'retrieveUserSession')
894
- .mockResolvedValueOnce({
895
- systemLogins: [
896
- {
897
- id: '1',
898
- sessionId: 'sessionId',
899
- code: systemCode,
900
- privileges: [],
901
- },
902
- ],
903
- });
904
- // Act
905
- const hasPrivilege = await loginUser.checkPrivileges(
906
- systemCode,
907
- privilegeName,
908
- );
909
-
910
- // Assert
911
- expect(hasPrivilege).toBe(false);
912
- expect(rus).toHaveBeenCalledWith(loginUser.ObjectId);
913
- });
914
-
915
- it('should throw an error if ObjectId is not set', async () => {
916
- // Arrange
917
- const systemCode = 'SS';
918
- const privilegeName = 'Privilege 1';
919
- const sessionService = await SessionService.init();
920
- const loginUser = await LoginUser.init(sessionService);
921
- loginUser.ObjectId = null;
922
-
923
- // Act & Assert
924
- await expect(
925
- loginUser.checkPrivileges(systemCode, privilegeName),
926
- ).rejects.toThrowError();
927
- });
928
- });
929
-
930
- describe('getObjectPrivileges', () => {
931
- it('should return an array of privileges', async () => {
932
- // Mock the dependencies and setup the test data
933
- const systemCode = 'system1';
934
- const dbTransaction = null;
935
- const sessionService = await SessionService.init();
936
- const loginUser = await LoginUser.init(sessionService);
937
-
938
- // Mock the UserObjectPrivilegeRepo findAll method
939
- const findAllMock = jest
940
- .spyOn(LoginUser['_UserObjectPrivilegeRepo'], 'findAll')
941
- .mockResolvedValue([
942
- {
943
- PrivilegeCode: 'privilege1',
944
- Privilege: {
945
- PrivilegeCode: 'privilege1',
946
- SystemCode: systemCode,
947
- Name: 'privilege1',
948
- },
949
- },
950
- {
951
- PrivilegeCode: 'privilege2',
952
- Privilege: {
953
- PrivilegeCode: 'privilege2',
954
- Name: 'privilege2',
955
- },
956
- },
957
- ] as any);
958
-
959
- // Call the getObjectPrivileges method
960
- const result = await loginUser['getObjectPrivileges'](
961
- systemCode,
962
- dbTransaction,
963
- );
964
-
965
- // Assertions
966
- expect(findAllMock).toHaveBeenCalledTimes(1);
967
- expect(findAllMock).toHaveBeenCalledWith({
968
- where: {
969
- UserId: loginUser.UserId,
970
- },
971
- include: {
972
- model: SystemPrivilegeModel,
973
- where: {
974
- SystemCode: systemCode,
975
- Status: 'Active',
976
- },
977
- },
978
- transaction: dbTransaction,
979
- });
980
- expect(result).toEqual(['privilege1', 'privilege2']);
981
- });
982
-
983
- it('should throw an error if an exception occurs', async () => {
984
- // Mock the dependencies and setup the test data
985
- const systemCode = 'system1';
986
- const dbTransaction = null;
987
- const sessionService = await SessionService.init();
988
- const loginUser = await LoginUser.init(sessionService);
989
-
990
- // Mock the UserObjectPrivilegeRepo findAll method to throw an error
991
- jest
992
- .spyOn(LoginUser['_UserObjectPrivilegeRepo'], 'findAll')
993
- .mockRejectedValue(new Error('Database error'));
994
-
995
- // Call the getObjectPrivileges method and expect it to throw an error
996
- await expect(
997
- loginUser['getObjectPrivileges'](systemCode, dbTransaction),
998
- ).rejects.toThrow(Error);
999
- });
1000
- });
1001
-
1002
- describe('getUserPersonalPrivileges', () => {
1003
- it('should return an array of privileges', async () => {
1004
- // Arrange
1005
- const sessionService = await SessionService.init();
1006
- const loginUser = await LoginUser.init(sessionService);
1007
- const systemCode = 'system1';
1008
- const dbTransaction = null;
1009
-
1010
- // Mock the findAll method of UserPrivilegeRepo
1011
- const findAllMock = jest.spyOn(
1012
- LoginUser['_UserPrivilegeRepo'],
1013
- 'findAll',
1014
- );
1015
- findAllMock.mockResolvedValue([
1016
- { Privilege: { Name: 'privilege1' } },
1017
- { Privilege: { Name: 'privilege2' } },
1018
- ] as any);
1019
-
1020
- // Act
1021
- const privileges = await loginUser['getUserPersonalPrivileges'](
1022
- systemCode,
1023
- dbTransaction,
1024
- );
1025
-
1026
- // Assert
1027
- expect(privileges).toEqual(['privilege1', 'privilege2']);
1028
- expect(findAllMock).toHaveBeenCalledTimes(1);
1029
- expect(findAllMock).toHaveBeenCalledWith({
1030
- where: {
1031
- UserId: loginUser.UserId,
1032
- Status: 'Active',
1033
- },
1034
- include: {
1035
- model: SystemPrivilegeModel,
1036
- where: {
1037
- SystemCode: systemCode,
1038
- Status: 'Active',
1039
- },
1040
- },
1041
- transaction: dbTransaction,
1042
- });
1043
- });
1044
-
1045
- it('should throw an error if an error occurs', async () => {
1046
- // Arrange
1047
- const sessionService = await SessionService.init();
1048
- const loginUser = await LoginUser.init(sessionService);
1049
- const systemCode = 'system1';
1050
- const dbTransaction = null;
1051
-
1052
- // Mock the findAll method of UserPrivilegeRepo to throw an error
1053
- const findAllMock = jest.spyOn(
1054
- LoginUser['_UserPrivilegeRepo'],
1055
- 'findAll',
1056
- );
1057
- findAllMock.mockRejectedValue(new Error('Database error'));
1058
-
1059
- // Act and Assert
1060
- await expect(
1061
- loginUser['getUserPersonalPrivileges'](systemCode, dbTransaction),
1062
- ).rejects.toThrow(Error);
1063
-
1064
- expect(findAllMock).toHaveBeenCalledTimes(1);
1065
- expect(findAllMock).toHaveBeenCalledWith({
1066
- where: {
1067
- UserId: loginUser.UserId,
1068
- Status: 'Active',
1069
- },
1070
- include: {
1071
- model: SystemPrivilegeModel,
1072
- where: {
1073
- SystemCode: systemCode,
1074
- Status: 'Active',
1075
- },
1076
- },
1077
- transaction: dbTransaction,
1078
- });
1079
- });
1080
- });
1081
-
1082
- describe('getInheritedSystemAccess', () => {
1083
- it('should return group system access with its parent group system access if applicable', async () => {
1084
- // Mock the necessary dependencies
1085
- const dbTransaction = null;
1086
- const group = {
1087
- GroupCode: 'group1',
1088
- InheritParentPrivilegeYN: 'Y',
1089
- ParentGroupCode: 'parentGroup',
1090
- } as any;
1091
- const parentGroup = {
1092
- GroupCode: 'parentGroup',
1093
- InheritParentPrivilegeYN: 'N',
1094
- ParentGroupCode: null,
1095
- } as any;
1096
-
1097
- const systemAccess = [
1098
- {
1099
- SystemCode: 'system1',
1100
- GroupCode: 'group1',
1101
- System: { SystemCode: 'system1' },
1102
- },
1103
- {
1104
- SystemCode: 'system2',
1105
- GroupCode: 'group1',
1106
- System: { SystemCode: 'system1' },
1107
- },
1108
- ] as any;
1109
-
1110
- const parentSystemAccess = [
1111
- {
1112
- SystemCode: 'system3',
1113
- GroupCode: 'parentGroup',
1114
- System: { SystemCode: 'system3' },
1115
- },
1116
- ] as any;
1117
-
1118
- // Mock the necessary repository methods
1119
- const groupFindByPkMock = jest
1120
- .spyOn(GroupRepository.prototype, 'findByPk')
1121
- .mockResolvedValueOnce(parentGroup as any);
1122
- const systemAccessFindAllMock = jest
1123
- .spyOn(GroupSystemAccessRepository.prototype, 'findAll')
1124
- .mockImplementation((options: any) => {
1125
- if (options.where.GroupCode === group.GroupCode) {
1126
- return Promise.resolve(systemAccess);
1127
- } else if (options.where.GroupCode === parentGroup.GroupCode) {
1128
- return Promise.resolve(parentSystemAccess);
1129
- }
1130
- });
1131
-
1132
- // Call the method
1133
- const result = await LoginUser['getInheritedSystemAccess'](
1134
- dbTransaction,
1135
- group,
1136
- );
1137
-
1138
- console.log(result);
1139
- // Assert the result
1140
- expect(result).toEqual([
1141
- {
1142
- SystemCode: 'system1',
1143
- GroupCode: 'group1',
1144
- System: { SystemCode: 'system1' },
1145
- },
1146
- {
1147
- SystemCode: 'system2',
1148
- GroupCode: 'group1',
1149
- System: { SystemCode: 'system1' },
1150
- },
1151
- {
1152
- SystemCode: 'system3',
1153
- GroupCode: 'parentGroup',
1154
- System: { SystemCode: 'system3' },
1155
- },
1156
- ]);
1157
- expect(groupFindByPkMock).toHaveBeenCalledWith(
1158
- group.ParentGroupCode,
1159
- dbTransaction,
1160
- );
1161
- expect(systemAccessFindAllMock).toHaveBeenCalledTimes(2);
1162
- });
1163
- });
1164
- });
1
+ import { SessionService } from '../../../../src/session/session.service';
2
+ import { LoginUser } from '../../../../src/components/login-user/login-user';
3
+ import { ApplicationConfig, ComponentConfig } from '@tomei/config';
4
+ import { UserRepository } from '../../../../src/components/login-user/user.repository';
5
+ import { ClassError } from '@tomei/general';
6
+ import { Activity } from '@tomei/activity-history';
7
+ import { UserStatus } from '../../../../src/enum/user-status.enum';
8
+ import { YN } from '../../../../src/enum/yn.enum';
9
+ import SystemPrivilegeModel from '../../../../src/models/system-privilege.entity';
10
+ import { GroupSystemAccessRepository } from '../../../../src/components/group-system-access/group-system-access.repository';
11
+ import { GroupRepository } from '../../../../src/components/group/group.repository';
12
+
13
+ // describe('LoginUser', () => {
14
+ // afterAll(() => {
15
+ // jest.restoreAllMocks();
16
+ // });
17
+
18
+ // describe('init', () => {
19
+ // let sessionService: any;
20
+ // let userId: number;
21
+ // let dbTransaction: any;
22
+
23
+ // beforeEach(() => {
24
+ // sessionService = {};
25
+ // userId = 1;
26
+ // dbTransaction = null;
27
+ // });
28
+
29
+ // it('should initialize LoginUser with valid userId', async () => {
30
+ // const user = {
31
+ // UserId: 1,
32
+ // FullName: 'John Doe',
33
+ // Email: 'john.doe@example.com',
34
+ // Password: 'password',
35
+ // Status: 'active',
36
+ // DefaultPasswordChangedYN: 'yes',
37
+ // FirstLoginAt: new Date(),
38
+ // LastLoginAt: new Date(),
39
+ // MFAEnabled: 1,
40
+ // MFAConfig: 'config',
41
+ // RecoveryEmail: 'john.doe@example.com',
42
+ // FailedLoginAttemptCount: 0,
43
+ // LastFailedLoginAt: null,
44
+ // LastPasswordChangedAt: new Date(),
45
+ // NeedToChangePasswordYN: 'no',
46
+ // CreatedById: 1,
47
+ // CreatedAt: new Date(),
48
+ // UpdatedById: 1,
49
+ // UpdatedAt: new Date(),
50
+ // Staff: {
51
+ // FullName: 'John Doe',
52
+ // IdNo: '1234567890',
53
+ // Mobile: '1234567890',
54
+ // },
55
+ // };
56
+
57
+ // const findOneMock = jest
58
+ // .spyOn(UserRepository.prototype, 'findOne')
59
+ // .mockResolvedValueOnce(user as any);
60
+
61
+ // const result = await LoginUser.init(
62
+ // sessionService,
63
+ // userId,
64
+ // dbTransaction,
65
+ // );
66
+
67
+ // expect(findOneMock).toHaveBeenCalledTimes(1);
68
+ // expect(findOneMock).toHaveBeenCalledWith({
69
+ // where: {
70
+ // UserId: userId,
71
+ // },
72
+ // include: [
73
+ // {
74
+ // model: expect.anything(),
75
+ // },
76
+ // ],
77
+ // });
78
+ // expect(result).toBeInstanceOf(LoginUser);
79
+ // expect(result.UserId).toBe(user.UserId);
80
+ // expect(result.FullName).toBe(user.FullName);
81
+ // expect(result.Email).toBe(user.Email);
82
+ // expect(result.Password).toBe(user.Password);
83
+ // expect(result.Status).toBe(user.Status);
84
+ // expect(result.DefaultPasswordChangedYN).toBe(
85
+ // user.DefaultPasswordChangedYN,
86
+ // );
87
+ // expect(result.FirstLoginAt).toBe(user.FirstLoginAt);
88
+ // expect(result.LastLoginAt).toBe(user.LastLoginAt);
89
+ // expect(result.MFAEnabled).toBe(user.MFAEnabled);
90
+ // expect(result.MFAConfig).toBe(user.MFAConfig);
91
+ // expect(result.RecoveryEmail).toBe(user.RecoveryEmail);
92
+ // expect(result.FailedLoginAttemptCount).toBe(user.FailedLoginAttemptCount);
93
+ // expect(result.LastFailedLoginAt).toBe(user.LastFailedLoginAt);
94
+ // expect(result.LastPasswordChangedAt).toBe(user.LastPasswordChangedAt);
95
+ // expect(result.NeedToChangePasswordYN).toBe(user.NeedToChangePasswordYN);
96
+ // expect(result.CreatedById).toBe(user.CreatedById);
97
+ // expect(result.CreatedAt).toBe(user.CreatedAt);
98
+ // expect(result.UpdatedById).toBe(user.UpdatedById);
99
+ // expect(result.UpdatedAt).toBe(user.UpdatedAt);
100
+ // });
101
+
102
+ // it('should throw an error when user is not found', async () => {
103
+ // const findOneMock = jest
104
+ // .spyOn(UserRepository.prototype, 'findOne')
105
+ // .mockResolvedValueOnce(null);
106
+
107
+ // await expect(
108
+ // LoginUser.init(sessionService, userId, dbTransaction),
109
+ // ).rejects.toThrow(Error);
110
+
111
+ // expect(findOneMock).toHaveBeenCalledTimes(1);
112
+ // expect(findOneMock).toHaveBeenCalledWith({
113
+ // where: {
114
+ // UserId: userId,
115
+ // },
116
+ // include: [
117
+ // {
118
+ // model: expect.anything(),
119
+ // },
120
+ // ],
121
+ // });
122
+ // });
123
+ // });
124
+
125
+ // // describe('checkSession', () => {
126
+ // // it('should throw an error if session expired', async () => {
127
+ // // // Arrange
128
+ // // const systemCode = 'EZC';
129
+ // // const sessionId = 'ckymxuh8t000137t011w89zgk';
130
+ // // const userId = '755';
131
+ // // const sessionService = await SessionService.init();
132
+ // // const loginUser = await LoginUser.init(sessionService);
133
+
134
+ // // // Act
135
+ // // const checkSessionPromise = loginUser.checkSession(
136
+ // // systemCode,
137
+ // // sessionId,
138
+ // // userId,
139
+ // // );
140
+
141
+ // // // Assert
142
+ // // await expect(checkSessionPromise).rejects.toThrow('Session expired.');
143
+ // // });
144
+
145
+ // // it('should refresh the session duration if session is valid', async () => {
146
+ // // // Arrange
147
+ // // const systemCode = 'EZC';
148
+ // // const sessionId = 'ckymxuh8t000137t011w89zgk';
149
+ // // const userId = '755';
150
+ // // const sessionService = await SessionService.init();
151
+ // // const loginUser = await LoginUser.init(sessionService);
152
+
153
+ // // // Mock the _SessionService.retrieveUserSession method
154
+ // // loginUser['_SessionService'].retrieveUserSession = jest
155
+ // // .fn()
156
+ // // .mockResolvedValue({
157
+ // // systemLogins: [
158
+ // // {
159
+ // // code: systemCode,
160
+ // // sessionId: sessionId,
161
+ // // privileges: [],
162
+ // // },
163
+ // // ],
164
+ // // });
165
+
166
+ // // // Mock the _SessionService.refreshDuration method
167
+ // // loginUser['_SessionService'].refreshDuration = jest.fn();
168
+
169
+ // // // Act
170
+ // // const systemLogin = await loginUser.checkSession(
171
+ // // systemCode,
172
+ // // sessionId,
173
+ // // userId,
174
+ // // );
175
+
176
+ // // // Assert
177
+ // // expect(
178
+ // // loginUser['_SessionService'].retrieveUserSession,
179
+ // // ).toHaveBeenCalledWith(userId);
180
+ // // expect(loginUser['_SessionService'].refreshDuration).toHaveBeenCalledWith(
181
+ // // userId,
182
+ // // );
183
+ // // expect(systemLogin).toEqual({
184
+ // // code: systemCode,
185
+ // // sessionId: sessionId,
186
+ // // privileges: [],
187
+ // // });
188
+ // // });
189
+ // // });
190
+
191
+ // describe('shouldReleaseLock', () => {
192
+ // const minuteToAutoRelease = 5;
193
+ // const autoReleaseYN = 'Y';
194
+
195
+ // beforeEach(() => {
196
+ // jest
197
+ // .spyOn(ComponentConfig, 'getComponentConfigValue')
198
+ // .mockImplementation((componentName: string, configKey: string) => {
199
+ // if (configKey === 'minuteToAutoRelease') {
200
+ // return minuteToAutoRelease as any;
201
+ // }
202
+ // if (configKey === 'autoReleaseYN') {
203
+ // return autoReleaseYN as any;
204
+ // }
205
+ // });
206
+ // });
207
+
208
+ // it('should return true if autoReleaseYN is "Y" and time difference is greater than minuteToAutoRelease', async () => {
209
+ // // Arrange
210
+ // const lastFailedLoginAt = new Date();
211
+ // lastFailedLoginAt.setMinutes(lastFailedLoginAt.getMinutes() - 10); // Set last failed login time to 10 minutes ago
212
+ // // Act
213
+ // const result = LoginUser.shouldReleaseLock(lastFailedLoginAt);
214
+
215
+ // // Assert
216
+ // expect(result).toBe(true);
217
+ // });
218
+
219
+ // it('should return false if autoReleaseYN is "Y" and time difference is less than or equal to minuteToAutoRelease', async () => {
220
+ // // Arrange
221
+ // const lastFailedLoginAt = new Date();
222
+ // lastFailedLoginAt.setMinutes(lastFailedLoginAt.getMinutes() - 3); // Set last failed login time to 3 minutes ago
223
+
224
+ // // Act
225
+ // const result = LoginUser.shouldReleaseLock(lastFailedLoginAt);
226
+
227
+ // // Assert
228
+ // expect(result).toBe(false);
229
+ // });
230
+
231
+ // it('should return false if autoReleaseYN is "N"', async () => {
232
+ // // Arrange
233
+ // const lastFailedLoginAt = new Date();
234
+
235
+ // // Act
236
+ // const result = LoginUser.shouldReleaseLock(lastFailedLoginAt);
237
+
238
+ // // Assert
239
+ // expect(result).toBe(false);
240
+ // });
241
+ // });
242
+
243
+ // describe('releaseLock', () => {
244
+ // it('should release the lock for a user', async () => {
245
+ // // Mock the necessary dependencies and setup the test data
246
+ // const UserId = 1;
247
+ // const dbTransaction = null;
248
+
249
+ // const updateMock = jest
250
+ // .spyOn(LoginUser['_Repository'], 'update')
251
+ // .mockImplementationOnce(() => Promise.resolve({}) as any);
252
+
253
+ // // Call the method under test
254
+ // LoginUser['releaseLock'](UserId, dbTransaction);
255
+
256
+ // // Verify the expected behavior
257
+ // expect(updateMock).toHaveBeenCalledTimes(1);
258
+ // expect(updateMock).toHaveBeenCalledWith(
259
+ // {
260
+ // FailedLoginAttemptCount: 0,
261
+ // Status: 'Active',
262
+ // },
263
+ // {
264
+ // where: {
265
+ // UserId,
266
+ // },
267
+ // transaction: dbTransaction,
268
+ // },
269
+ // );
270
+ // });
271
+ // });
272
+
273
+ // describe('checkUserInfoDuplicated', () => {
274
+ // it('should throw an error if duplicate user info is found', async () => {
275
+ // // Mock the dependencies and setup the test data
276
+ // const dbTransaction = null;
277
+ // const query = {
278
+ // Email: 'test@example.com',
279
+ // IdType: 'passport',
280
+ // IdNo: '123456789',
281
+ // ContactNo: '1234567890',
282
+ // };
283
+
284
+ // // Mock the LoginUser['_Repository'].findAll method to return a user
285
+ // jest
286
+ // .spyOn(LoginUser['_Repository'], 'findAll')
287
+ // .mockResolvedValueOnce([{ id: 1 }] as any);
288
+
289
+ // // Assert that the method throws an error
290
+ // await expect(
291
+ // LoginUser['checkUserInfoDuplicated'](dbTransaction, query),
292
+ // ).rejects.toThrowError();
293
+ // });
294
+
295
+ // it('should not throw an error if duplicate user info is not found', async () => {
296
+ // // Mock the dependencies and setup the test data
297
+ // const dbTransaction = null;
298
+ // const query = {
299
+ // Email: 'test@example.com',
300
+ // IdType: 'passport',
301
+ // IdNo: '123456789',
302
+ // ContactNo: '1234567890',
303
+ // };
304
+
305
+ // // Mock the LoginUser['_Repository'].findAll method to return an empty array
306
+ // jest.spyOn(LoginUser['_Repository'], 'findAll').mockResolvedValueOnce([]);
307
+
308
+ // // Assert that the method does not throw an error
309
+ // await expect(
310
+ // LoginUser['checkUserInfoDuplicated'](dbTransaction, query),
311
+ // ).resolves.not.toThrowError();
312
+ // });
313
+ // });
314
+
315
+ // describe('generateDefaultPassword', () => {
316
+ // const passwordPolicy = {
317
+ // minLen: 6,
318
+ // maxLen: 10,
319
+ // nonAcceptableChar: 'i,l,o',
320
+ // numOfCapitalLetters: 1,
321
+ // numOfNumbers: 1,
322
+ // numOfSpecialChars: 1,
323
+ // };
324
+ // beforeEach(() => {
325
+ // jest
326
+ // .spyOn(ComponentConfig, 'getComponentConfigValue')
327
+ // .mockImplementation((componentName: string, configKey: string) => {
328
+ // if (configKey === 'passwordPolicy') {
329
+ // return passwordPolicy as any;
330
+ // }
331
+ // });
332
+ // });
333
+
334
+ // it('should generate a default password with the specified length', () => {
335
+ // const password = LoginUser['generateDefaultPassword']();
336
+ // expect(password.length).toBeGreaterThanOrEqual(6);
337
+ // expect(password.length).toBeLessThanOrEqual(10);
338
+ // });
339
+
340
+ // it('should generate a default password with at least one capital letter', () => {
341
+ // const password = LoginUser['generateDefaultPassword']();
342
+ // expect(/[A-Z]/.test(password)).toBe(true);
343
+ // });
344
+
345
+ // it('should generate a default password with at least one number', () => {
346
+ // const password = LoginUser['generateDefaultPassword']();
347
+ // expect(/[0-9]/.test(password)).toBe(true);
348
+ // });
349
+
350
+ // it('should generate a default password with at least one special character', () => {
351
+ // const password = LoginUser['generateDefaultPassword']();
352
+ // expect(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?~`]/.test(password)).toBe(true);
353
+ // });
354
+
355
+ // it('should generate a default password without any non-acceptable characters', () => {
356
+ // const password = LoginUser['generateDefaultPassword']();
357
+ // const nonAcceptableChars = ['i', 'l', 'o'];
358
+ // expect(nonAcceptableChars.some((char) => password.includes(char))).toBe(
359
+ // false,
360
+ // );
361
+ // });
362
+ // });
363
+
364
+ // describe('setPassword', () => {
365
+ // const passwordPolicy = {
366
+ // minLen: 6,
367
+ // maxLen: 10,
368
+ // nonAcceptableChar: 'i,l,o',
369
+ // numOfCapitalLetters: 1,
370
+ // numOfNumbers: 1,
371
+ // numOfSpecialChars: 1,
372
+ // };
373
+ // beforeEach(() => {
374
+ // jest
375
+ // .spyOn(ComponentConfig, 'getComponentConfigValue')
376
+ // .mockImplementation((componentName: string, configKey: string) => {
377
+ // if (configKey === 'passwordPolicy') {
378
+ // return passwordPolicy as any;
379
+ // }
380
+ // });
381
+ // });
382
+
383
+ // it('should set the password for the user', async () => {
384
+ // // Arrange
385
+ // const dbTransaction = null;
386
+ // const sessionService = await SessionService.init();
387
+ // const user = await LoginUser.init(sessionService);
388
+ // const password = 'N3wP@ssw0';
389
+
390
+ // // Act
391
+ // const result = await LoginUser['setPassword'](
392
+ // dbTransaction,
393
+ // user,
394
+ // password,
395
+ // );
396
+
397
+ // // Assert
398
+ // expect(result).toBeInstanceOf(LoginUser);
399
+ // await expect(
400
+ // LoginUser['setPassword'](dbTransaction, user, password),
401
+ // ).resolves.not.toThrowError();
402
+ // expect(result.Password).toBeDefined();
403
+ // });
404
+
405
+ // it('should throw an error if the password does not meet the security requirements', async () => {
406
+ // // Arrange
407
+ // const dbTransaction = null;
408
+ // const sessionService = await SessionService.init();
409
+ // const user = await LoginUser.init(sessionService);
410
+ // const password = 'weakpassword';
411
+
412
+ // // Act & Assert
413
+ // await expect(
414
+ // LoginUser['setPassword'](dbTransaction, user, password),
415
+ // ).rejects.toThrow();
416
+ // });
417
+ // });
418
+
419
+ // // describe('create', () => {
420
+ // // let loginUser: LoginUser;
421
+ // // let dbTransaction: any;
422
+ // // let user: LoginUser;
423
+ // // let newUser: any;
424
+
425
+ // // beforeEach(async () => {
426
+ // // const sessionService = await SessionService.init();
427
+ // // loginUser = await LoginUser.init(sessionService);
428
+ // // dbTransaction = null;
429
+ // // newUser = {
430
+ // // UserId: 1,
431
+ // // FullName: 'John Doe',
432
+ // // Email: 'john.doe@example.com',
433
+ // // Password: 'password',
434
+ // // Status: 'Active',
435
+ // // DefaultPasswordChangedYN: 'N',
436
+ // // FirstLoginAt: null,
437
+ // // LastLoginAt: null,
438
+ // // MFAEnabled: null,
439
+ // // MFAConfig: null,
440
+ // // RecoveryEmail: null,
441
+ // // FailedLoginAttemptCount: 0,
442
+ // // LastFailedLoginAt: null,
443
+ // // LastPasswordChangedAt: new Date(),
444
+ // // NeedToChangePasswordYN: 'N',
445
+ // // CreatedById: 1,
446
+ // // CreatedAt: new Date(),
447
+ // // UpdatedById: 1,
448
+ // // UpdatedAt: new Date(),
449
+ // // Staff: {
450
+ // // FullName: 'John Doe',
451
+ // // IdNo: '1234567890',
452
+ // // Mobile: '1234567890',
453
+ // // },
454
+ // // };
455
+ // // user = new (LoginUser as any)(sessionService, null, newUser);
456
+ // // });
457
+
458
+ // // afterEach(() => {
459
+ // // jest.clearAllMocks();
460
+ // // });
461
+
462
+ // // it('should create a new user record', async () => {
463
+ // // const checkPrivilegesMock = jest
464
+ // // .spyOn(loginUser, 'checkPrivileges')
465
+ // // .mockResolvedValueOnce(true);
466
+
467
+ // // const checkUserInfoDuplicatedMock = jest
468
+ // // .spyOn(LoginUser as any, 'checkUserInfoDuplicated')
469
+ // // .mockResolvedValueOnce(undefined);
470
+
471
+ // // const generateDefaultPasswordMock = jest
472
+ // // .spyOn(LoginUser as any, 'generateDefaultPassword')
473
+ // // .mockReturnValueOnce('defaultPassword');
474
+
475
+ // // const setPasswordMock = jest
476
+ // // .spyOn(LoginUser as any, 'setPassword')
477
+ // // .mockResolvedValueOnce(user);
478
+
479
+ // // const createMock = jest
480
+ // // .spyOn((LoginUser as any)['_Repository'], 'create')
481
+ // // .mockResolvedValueOnce({
482
+ // // ...newUser,
483
+ // // get: () => newUser,
484
+ // // });
485
+
486
+ // // const activityCreateMock = jest
487
+ // // .spyOn((Activity as any).prototype, 'create')
488
+ // // .mockResolvedValueOnce(undefined);
489
+
490
+ // // jest
491
+ // // .spyOn(ApplicationConfig, 'getComponentConfigValue')
492
+ // // .mockImplementation((configKey: string) => {
493
+ // // if (configKey === 'system-code') {
494
+ // // return 'SC';
495
+ // // }
496
+ // // });
497
+
498
+ // // const result = await LoginUser.create(loginUser, dbTransaction, user);
499
+
500
+ // // expect(checkPrivilegesMock).toHaveBeenCalledTimes(1);
501
+ // // expect(checkPrivilegesMock).toHaveBeenCalledWith(
502
+ // // ApplicationConfig.getComponentConfigValue('system-code'),
503
+ // // 'User - Create',
504
+ // // );
505
+
506
+ // // expect(checkUserInfoDuplicatedMock).toHaveBeenCalledTimes(1);
507
+ // // expect(checkUserInfoDuplicatedMock).toHaveBeenCalledWith(dbTransaction, {
508
+ // // Email: user.Email,
509
+ // // IdType: user.IDType,
510
+ // // IdNo: user.IDNo,
511
+ // // ContactNo: user.ContactNo,
512
+ // // });
513
+
514
+ // // expect(generateDefaultPasswordMock).toHaveBeenCalledTimes(1);
515
+
516
+ // // expect(setPasswordMock).toHaveBeenCalledTimes(1);
517
+ // // expect(setPasswordMock).toHaveBeenCalledWith(
518
+ // // dbTransaction,
519
+ // // user,
520
+ // // 'defaultPassword',
521
+ // // );
522
+
523
+ // // expect(createMock).toHaveBeenCalledTimes(1);
524
+
525
+ // // const userInfo = {
526
+ // // FullName: user.FullName,
527
+ // // IDNo: user.IDNo,
528
+ // // Email: user.Email,
529
+ // // ContactNo: user.ContactNo,
530
+ // // Password: user.Password,
531
+ // // Status: UserStatus.ACTIVE,
532
+ // // FirstLoginAt: null,
533
+ // // LastLoginAt: null,
534
+ // // MFAEnabled: null,
535
+ // // MFAConfig: null,
536
+ // // RecoveryEmail: null,
537
+ // // FailedLoginAttemptCount: 0,
538
+ // // LastFailedLoginAt: null,
539
+ // // LastPasswordChangedAt: null,
540
+ // // DefaultPasswordChangedYN: YN.No,
541
+ // // NeedToChangePasswordYN: YN.Yes,
542
+ // // CreatedById: loginUser.UserId,
543
+ // // CreatedAt: new Date(),
544
+ // // UpdatedById: loginUser.UserId,
545
+ // // UpdatedAt: new Date(),
546
+ // // UserId: null,
547
+ // // };
548
+
549
+ // // expect(createMock).toHaveBeenCalledWith(
550
+ // // {
551
+ // // Email: userInfo.Email,
552
+ // // Password: userInfo.Password,
553
+ // // Status: userInfo.Status,
554
+ // // DefaultPasswordChangedYN: userInfo.DefaultPasswordChangedYN,
555
+ // // FirstLoginAt: userInfo.FirstLoginAt,
556
+ // // LastLoginAt: userInfo.LastLoginAt,
557
+ // // MFAEnabled: userInfo.MFAEnabled,
558
+ // // MFAConfig: userInfo.MFAConfig,
559
+ // // RecoveryEmail: userInfo.RecoveryEmail,
560
+ // // FailedLoginAttemptCount: userInfo.FailedLoginAttemptCount,
561
+ // // LastFailedLoginAt: userInfo.LastFailedLoginAt,
562
+ // // LastPasswordChangedAt: userInfo.LastPasswordChangedAt,
563
+ // // NeedToChangePasswordYN: userInfo.NeedToChangePasswordYN,
564
+ // // CreatedById: userInfo.CreatedById,
565
+ // // CreatedAt: expect.any(Date),
566
+ // // UpdatedById: userInfo.UpdatedById,
567
+ // // UpdatedAt: expect.any(Date),
568
+ // // },
569
+ // // {
570
+ // // transaction: dbTransaction,
571
+ // // },
572
+ // // );
573
+
574
+ // // expect(activityCreateMock).toHaveBeenCalledTimes(1);
575
+
576
+ // // expect(result).toBeInstanceOf(LoginUser);
577
+ // // expect(result.Email).toBe(userInfo.Email);
578
+ // // expect(result.Password).toBe(userInfo.Password);
579
+ // // expect(result.Status).toBe(userInfo.Status);
580
+ // // expect(result.DefaultPasswordChangedYN).toBe(
581
+ // // userInfo.DefaultPasswordChangedYN,
582
+ // // );
583
+ // // expect(result.FirstLoginAt).toBe(null);
584
+ // // expect(result.LastLoginAt).toBe(null);
585
+ // // expect(result.MFAEnabled).toBe(userInfo.MFAEnabled);
586
+ // // expect(result.MFAConfig).toBe(userInfo.MFAConfig);
587
+ // // expect(result.RecoveryEmail).toBe(userInfo.RecoveryEmail);
588
+ // // expect(result.FailedLoginAttemptCount).toBe(
589
+ // // userInfo.FailedLoginAttemptCount,
590
+ // // );
591
+ // // expect(result.LastFailedLoginAt).toBe(userInfo.LastFailedLoginAt);
592
+ // // expect(result.LastPasswordChangedAt).toBe(userInfo.LastPasswordChangedAt);
593
+ // // expect(result.NeedToChangePasswordYN).toBe(
594
+ // // userInfo.NeedToChangePasswordYN,
595
+ // // );
596
+ // // expect(result.CreatedById).toBe(userInfo.CreatedById);
597
+ // // expect(result.UpdatedById).toBe(userInfo.UpdatedById);
598
+ // // });
599
+
600
+ // // it('should throw an error if user dont have the privilege to create new user', async () => {
601
+ // // jest.spyOn(loginUser, 'checkPrivileges').mockResolvedValueOnce(false);
602
+
603
+ // // await expect(
604
+ // // LoginUser.create(loginUser, dbTransaction, user),
605
+ // // ).rejects.toThrow(ClassError);
606
+ // // });
607
+
608
+ // // it('should throw an error if user email is missing', async () => {
609
+ // // user.Email = undefined;
610
+
611
+ // // jest.spyOn(loginUser, 'checkPrivileges').mockResolvedValueOnce(true);
612
+
613
+ // // await expect(
614
+ // // LoginUser.create(loginUser, dbTransaction, user),
615
+ // // ).rejects.toThrow(ClassError);
616
+ // // });
617
+ // // });
618
+
619
+ // describe('incrementFailedLoginAttemptCount', () => {
620
+ // afterAll(() => {
621
+ // jest.restoreAllMocks();
622
+ // });
623
+
624
+ // it('should increment FailedLoginAttemptCount and update user status', async () => {
625
+ // // Arrange
626
+ // const sessionService = await SessionService.init();
627
+ // const loginUser = await LoginUser.init(sessionService);
628
+ // loginUser['FailedLoginAttemptCount'] = 2;
629
+ // loginUser['LastFailedLoginAt'] = new Date();
630
+ // loginUser['Status'] = UserStatus.ACTIVE;
631
+
632
+ // const dbTransaction = null;
633
+
634
+ // // Mock the static methods and properties
635
+ // jest
636
+ // .spyOn((LoginUser as any)['_Repository'], 'update')
637
+ // .mockReturnValueOnce(null);
638
+
639
+ // jest
640
+ // .spyOn(ComponentConfig, 'getComponentConfigValue')
641
+ // .mockImplementation((componentName: string, configKey: string) => {
642
+ // if (configKey === 'maxFailedLoginAttempts') {
643
+ // return 3;
644
+ // }
645
+ // if (configKey === 'autoReleaseYN') {
646
+ // return 'Y';
647
+ // }
648
+ // });
649
+
650
+ // // Act
651
+ // await loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
652
+
653
+ // // Assert
654
+ // expect(LoginUser['_Repository'].update).toHaveBeenCalledWith(
655
+ // {
656
+ // FailedLoginAttemptCount: 3,
657
+ // LastFailedLoginAt: expect.any(Date),
658
+ // Status: UserStatus.ACTIVE,
659
+ // },
660
+ // {
661
+ // where: {
662
+ // UserId: loginUser.UserId,
663
+ // },
664
+ // transaction: dbTransaction,
665
+ // },
666
+ // );
667
+ // });
668
+
669
+ // it('should throw an error if maxFailedLoginAttempts or autoReleaseYN is missing', async () => {
670
+ // // Arrange
671
+ // const sessionService = await SessionService.init();
672
+ // const loginUser = await LoginUser.init(sessionService);
673
+ // loginUser['FailedLoginAttemptCount'] = 2;
674
+ // loginUser['LastFailedLoginAt'] = new Date();
675
+ // loginUser['Status'] = UserStatus.ACTIVE;
676
+
677
+ // const dbTransaction = null;
678
+
679
+ // // Mock the static methods and properties
680
+ // jest
681
+ // .spyOn((LoginUser as any)['_Repository'], 'update')
682
+ // .mockReturnValueOnce(null);
683
+
684
+ // jest
685
+ // .spyOn(ComponentConfig, 'getComponentConfigValue')
686
+ // .mockImplementationOnce((componentName: string, configKey: string) => {
687
+ // if (configKey === 'maxFailedLoginAttempts') {
688
+ // return undefined;
689
+ // }
690
+ // if (configKey === 'autoReleaseYN') {
691
+ // return undefined;
692
+ // }
693
+ // });
694
+
695
+ // // Act and Assert
696
+ // await expect(
697
+ // loginUser['incrementFailedLoginAttemptCount'](dbTransaction),
698
+ // ).rejects.toThrow(
699
+ // new ClassError(
700
+ // 'LoginUser',
701
+ // 'LoginUserErrMsg0X',
702
+ // 'Missing maxFailedLoginAttempts and or autoReleaseYN. Please set in config file.',
703
+ // ),
704
+ // );
705
+ // });
706
+
707
+ // it('should lock the user account if the failed login attempts exceed the maximum allowed', async () => {
708
+ // // Arrange
709
+ // const sessionService = await SessionService.init();
710
+ // const loginUser = await LoginUser.init(sessionService);
711
+ // loginUser['FailedLoginAttemptCount'] = 3;
712
+ // loginUser['LastFailedLoginAt'] = new Date();
713
+ // loginUser['Status'] = UserStatus.ACTIVE;
714
+
715
+ // const dbTransaction = null;
716
+
717
+ // // Mock the static methods and properties
718
+ // jest
719
+ // .spyOn((LoginUser as any)['_Repository'], 'update')
720
+ // .mockReturnValueOnce(null);
721
+
722
+ // jest
723
+ // .spyOn(ComponentConfig, 'getComponentConfigValue')
724
+ // .mockImplementation((componentName: string, configKey: string) => {
725
+ // if (configKey === 'maxFailedLoginAttempts') {
726
+ // return 3;
727
+ // }
728
+ // if (configKey === 'autoReleaseYN') {
729
+ // return 'Y';
730
+ // }
731
+ // });
732
+
733
+ // // Act
734
+ // try {
735
+ // await loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
736
+ // expect(false).toBe(true);
737
+ // } catch (error) {
738
+ // // Assert
739
+ // expect(LoginUser['_Repository'].update).toHaveBeenCalledWith(
740
+ // {
741
+ // FailedLoginAttemptCount: 4,
742
+ // LastFailedLoginAt: expect.any(Date),
743
+ // Status: UserStatus.LOCKED,
744
+ // },
745
+ // {
746
+ // where: {
747
+ // UserId: loginUser.UserId,
748
+ // },
749
+ // transaction: dbTransaction,
750
+ // },
751
+ // );
752
+ // expect(error).toBeInstanceOf(ClassError);
753
+ // expect(error.message).toBe(
754
+ // 'Your account has been temporarily locked due to too many failed login attempts, please try again later.',
755
+ // );
756
+ // }
757
+ // });
758
+
759
+ // it('should permanently lock the user account if the failed login attempts exceed the maximum allowed and autoReleaseYN is N', async () => {
760
+ // // Arrange
761
+ // const sessionService = await SessionService.init();
762
+ // const loginUser = await LoginUser.init(sessionService);
763
+ // loginUser['FailedLoginAttemptCount'] = 3;
764
+ // loginUser['LastFailedLoginAt'] = new Date();
765
+ // loginUser['Status'] = UserStatus.ACTIVE;
766
+
767
+ // const dbTransaction = null;
768
+
769
+ // // Mock the static methods and properties
770
+ // jest
771
+ // .spyOn((LoginUser as any)['_Repository'], 'update')
772
+ // .mockReturnValueOnce(null);
773
+
774
+ // jest
775
+ // .spyOn(ComponentConfig, 'getComponentConfigValue')
776
+ // .mockImplementation((componentName: string, configKey: string) => {
777
+ // if (configKey === 'maxFailedLoginAttempts') {
778
+ // return 3;
779
+ // }
780
+ // if (configKey === 'autoReleaseYN') {
781
+ // return 'N';
782
+ // }
783
+ // });
784
+
785
+ // // Act
786
+ // try {
787
+ // await loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
788
+ // expect(false).toBe(true);
789
+ // } catch (error) {
790
+ // // Assert
791
+ // expect(LoginUser['_Repository'].update).toHaveBeenCalledWith(
792
+ // {
793
+ // FailedLoginAttemptCount: 4,
794
+ // LastFailedLoginAt: expect.any(Date),
795
+ // Status: UserStatus.LOCKED,
796
+ // },
797
+ // {
798
+ // where: {
799
+ // UserId: loginUser.UserId,
800
+ // },
801
+ // transaction: dbTransaction,
802
+ // },
803
+ // );
804
+ // expect(error).toBeInstanceOf(ClassError);
805
+ // expect(error.message).toBe(
806
+ // 'Your account has been locked due to too many failed login attempts, please contact IT Support for instructions on how to unlock your account',
807
+ // );
808
+ // }
809
+ // });
810
+ // });
811
+
812
+ // describe('combineSystemAccess', () => {
813
+ // it('should combine user and group system access and remove duplicates', async () => {
814
+ // // Mock the necessary dependencies
815
+ // const sessionService = await SessionService.init();
816
+ // const loginUser = await LoginUser.init(sessionService);
817
+ // const dbTransaction = null;
818
+ // const groups = [
819
+ // { InheritParentSystemAccessYN: true },
820
+ // { InheritParentSystemAccessYN: false },
821
+ // ];
822
+
823
+ // // Mock the necessary repository methods
824
+ // jest
825
+ // .spyOn(LoginUser as any, 'getInheritedSystemAccess')
826
+ // .mockResolvedValueOnce([
827
+ // { SystemCode: 'system1' },
828
+ // { SystemCode: 'system2' },
829
+ // ]);
830
+ // jest
831
+ // .spyOn((LoginUser as any)['_UserSystemAccessRepo'], 'findAll')
832
+ // .mockResolvedValueOnce([{ SystemCode: 'system3' }]);
833
+
834
+ // // Call the method
835
+ // const result = await LoginUser['combineSystemAccess'](
836
+ // loginUser,
837
+ // dbTransaction,
838
+ // groups,
839
+ // );
840
+
841
+ // // Assert the result
842
+ // expect(result).toEqual([
843
+ // { SystemCode: 'system3' },
844
+ // { SystemCode: 'system1' },
845
+ // { SystemCode: 'system2' },
846
+ // ]);
847
+ // });
848
+ // });
849
+
850
+ // describe('checkPrivileges', () => {
851
+ // it('should return true if user has the specified privilege', async () => {
852
+ // // Arrange
853
+ // const systemCode = 'SS';
854
+ // const privilegeName = 'Privilege 1';
855
+ // const sessionService = await SessionService.init();
856
+ // const loginUser = await LoginUser.init(sessionService);
857
+ // loginUser.ObjectId = '1';
858
+
859
+ // // Mock the necessary methods
860
+ // const rus = jest
861
+ // .spyOn(SessionService.prototype, 'retrieveUserSession')
862
+ // .mockResolvedValueOnce({
863
+ // systemLogins: [
864
+ // {
865
+ // id: '1',
866
+ // sessionId: 'sessionId',
867
+ // code: systemCode,
868
+ // privileges: [privilegeName],
869
+ // },
870
+ // ],
871
+ // });
872
+ // // Act
873
+ // const hasPrivilege = await loginUser.checkPrivileges(
874
+ // systemCode,
875
+ // privilegeName,
876
+ // );
877
+
878
+ // // Assert
879
+ // expect(hasPrivilege).toBe(true);
880
+ // expect(rus).toHaveBeenCalledWith(loginUser.ObjectId);
881
+ // });
882
+
883
+ // it('should return false if user does not have the specified privilege', async () => {
884
+ // // Arrange
885
+ // const systemCode = 'SS';
886
+ // const privilegeName = 'Privilege 1';
887
+ // const sessionService = await SessionService.init();
888
+ // const loginUser = await LoginUser.init(sessionService);
889
+ // loginUser.ObjectId = '1';
890
+
891
+ // // Mock the necessary methods
892
+ // const rus = jest
893
+ // .spyOn(SessionService.prototype, 'retrieveUserSession')
894
+ // .mockResolvedValueOnce({
895
+ // systemLogins: [
896
+ // {
897
+ // id: '1',
898
+ // sessionId: 'sessionId',
899
+ // code: systemCode,
900
+ // privileges: [],
901
+ // },
902
+ // ],
903
+ // });
904
+ // // Act
905
+ // const hasPrivilege = await loginUser.checkPrivileges(
906
+ // systemCode,
907
+ // privilegeName,
908
+ // );
909
+
910
+ // // Assert
911
+ // expect(hasPrivilege).toBe(false);
912
+ // expect(rus).toHaveBeenCalledWith(loginUser.ObjectId);
913
+ // });
914
+
915
+ // it('should throw an error if ObjectId is not set', async () => {
916
+ // // Arrange
917
+ // const systemCode = 'SS';
918
+ // const privilegeName = 'Privilege 1';
919
+ // const sessionService = await SessionService.init();
920
+ // const loginUser = await LoginUser.init(sessionService);
921
+ // loginUser.ObjectId = null;
922
+
923
+ // // Act & Assert
924
+ // await expect(
925
+ // loginUser.checkPrivileges(systemCode, privilegeName),
926
+ // ).rejects.toThrowError();
927
+ // });
928
+ // });
929
+
930
+ // describe('getObjectPrivileges', () => {
931
+ // it('should return an array of privileges', async () => {
932
+ // // Mock the dependencies and setup the test data
933
+ // const systemCode = 'system1';
934
+ // const dbTransaction = null;
935
+ // const sessionService = await SessionService.init();
936
+ // const loginUser = await LoginUser.init(sessionService);
937
+
938
+ // // Mock the UserObjectPrivilegeRepo findAll method
939
+ // const findAllMock = jest
940
+ // .spyOn(LoginUser['_UserObjectPrivilegeRepo'], 'findAll')
941
+ // .mockResolvedValue([
942
+ // {
943
+ // PrivilegeCode: 'privilege1',
944
+ // Privilege: {
945
+ // PrivilegeCode: 'privilege1',
946
+ // SystemCode: systemCode,
947
+ // Name: 'privilege1',
948
+ // },
949
+ // },
950
+ // {
951
+ // PrivilegeCode: 'privilege2',
952
+ // Privilege: {
953
+ // PrivilegeCode: 'privilege2',
954
+ // Name: 'privilege2',
955
+ // },
956
+ // },
957
+ // ] as any);
958
+
959
+ // // Call the getObjectPrivileges method
960
+ // const result = await loginUser['getObjectPrivileges'](
961
+ // systemCode,
962
+ // dbTransaction,
963
+ // );
964
+
965
+ // // Assertions
966
+ // expect(findAllMock).toHaveBeenCalledTimes(1);
967
+ // expect(findAllMock).toHaveBeenCalledWith({
968
+ // where: {
969
+ // UserId: loginUser.UserId,
970
+ // },
971
+ // include: {
972
+ // model: SystemPrivilegeModel,
973
+ // where: {
974
+ // SystemCode: systemCode,
975
+ // Status: 'Active',
976
+ // },
977
+ // },
978
+ // transaction: dbTransaction,
979
+ // });
980
+ // expect(result).toEqual(['privilege1', 'privilege2']);
981
+ // });
982
+
983
+ // it('should throw an error if an exception occurs', async () => {
984
+ // // Mock the dependencies and setup the test data
985
+ // const systemCode = 'system1';
986
+ // const dbTransaction = null;
987
+ // const sessionService = await SessionService.init();
988
+ // const loginUser = await LoginUser.init(sessionService);
989
+
990
+ // // Mock the UserObjectPrivilegeRepo findAll method to throw an error
991
+ // jest
992
+ // .spyOn(LoginUser['_UserObjectPrivilegeRepo'], 'findAll')
993
+ // .mockRejectedValue(new Error('Database error'));
994
+
995
+ // // Call the getObjectPrivileges method and expect it to throw an error
996
+ // await expect(
997
+ // loginUser['getObjectPrivileges'](systemCode, dbTransaction),
998
+ // ).rejects.toThrow(Error);
999
+ // });
1000
+ // });
1001
+
1002
+ // describe('getUserPersonalPrivileges', () => {
1003
+ // it('should return an array of privileges', async () => {
1004
+ // // Arrange
1005
+ // const sessionService = await SessionService.init();
1006
+ // const loginUser = await LoginUser.init(sessionService);
1007
+ // const systemCode = 'system1';
1008
+ // const dbTransaction = null;
1009
+
1010
+ // // Mock the findAll method of UserPrivilegeRepo
1011
+ // const findAllMock = jest.spyOn(
1012
+ // LoginUser['_UserPrivilegeRepo'],
1013
+ // 'findAll',
1014
+ // );
1015
+ // findAllMock.mockResolvedValue([
1016
+ // { Privilege: { Name: 'privilege1' } },
1017
+ // { Privilege: { Name: 'privilege2' } },
1018
+ // ] as any);
1019
+
1020
+ // // Act
1021
+ // const privileges = await loginUser['getUserPersonalPrivileges'](
1022
+ // systemCode,
1023
+ // dbTransaction,
1024
+ // );
1025
+
1026
+ // // Assert
1027
+ // expect(privileges).toEqual(['privilege1', 'privilege2']);
1028
+ // expect(findAllMock).toHaveBeenCalledTimes(1);
1029
+ // expect(findAllMock).toHaveBeenCalledWith({
1030
+ // where: {
1031
+ // UserId: loginUser.UserId,
1032
+ // Status: 'Active',
1033
+ // },
1034
+ // include: {
1035
+ // model: SystemPrivilegeModel,
1036
+ // where: {
1037
+ // SystemCode: systemCode,
1038
+ // Status: 'Active',
1039
+ // },
1040
+ // },
1041
+ // transaction: dbTransaction,
1042
+ // });
1043
+ // });
1044
+
1045
+ // it('should throw an error if an error occurs', async () => {
1046
+ // // Arrange
1047
+ // const sessionService = await SessionService.init();
1048
+ // const loginUser = await LoginUser.init(sessionService);
1049
+ // const systemCode = 'system1';
1050
+ // const dbTransaction = null;
1051
+
1052
+ // // Mock the findAll method of UserPrivilegeRepo to throw an error
1053
+ // const findAllMock = jest.spyOn(
1054
+ // LoginUser['_UserPrivilegeRepo'],
1055
+ // 'findAll',
1056
+ // );
1057
+ // findAllMock.mockRejectedValue(new Error('Database error'));
1058
+
1059
+ // // Act and Assert
1060
+ // await expect(
1061
+ // loginUser['getUserPersonalPrivileges'](systemCode, dbTransaction),
1062
+ // ).rejects.toThrow(Error);
1063
+
1064
+ // expect(findAllMock).toHaveBeenCalledTimes(1);
1065
+ // expect(findAllMock).toHaveBeenCalledWith({
1066
+ // where: {
1067
+ // UserId: loginUser.UserId,
1068
+ // Status: 'Active',
1069
+ // },
1070
+ // include: {
1071
+ // model: SystemPrivilegeModel,
1072
+ // where: {
1073
+ // SystemCode: systemCode,
1074
+ // Status: 'Active',
1075
+ // },
1076
+ // },
1077
+ // transaction: dbTransaction,
1078
+ // });
1079
+ // });
1080
+ // });
1081
+
1082
+ // describe('getInheritedSystemAccess', () => {
1083
+ // it('should return group system access with its parent group system access if applicable', async () => {
1084
+ // // Mock the necessary dependencies
1085
+ // const dbTransaction = null;
1086
+ // const group = {
1087
+ // GroupCode: 'group1',
1088
+ // InheritParentPrivilegeYN: 'Y',
1089
+ // ParentGroupCode: 'parentGroup',
1090
+ // } as any;
1091
+ // const parentGroup = {
1092
+ // GroupCode: 'parentGroup',
1093
+ // InheritParentPrivilegeYN: 'N',
1094
+ // ParentGroupCode: null,
1095
+ // } as any;
1096
+
1097
+ // const systemAccess = [
1098
+ // {
1099
+ // SystemCode: 'system1',
1100
+ // GroupCode: 'group1',
1101
+ // System: { SystemCode: 'system1' },
1102
+ // },
1103
+ // {
1104
+ // SystemCode: 'system2',
1105
+ // GroupCode: 'group1',
1106
+ // System: { SystemCode: 'system1' },
1107
+ // },
1108
+ // ] as any;
1109
+
1110
+ // const parentSystemAccess = [
1111
+ // {
1112
+ // SystemCode: 'system3',
1113
+ // GroupCode: 'parentGroup',
1114
+ // System: { SystemCode: 'system3' },
1115
+ // },
1116
+ // ] as any;
1117
+
1118
+ // // Mock the necessary repository methods
1119
+ // const groupFindByPkMock = jest
1120
+ // .spyOn(GroupRepository.prototype, 'findByPk')
1121
+ // .mockResolvedValueOnce(parentGroup as any);
1122
+ // const systemAccessFindAllMock = jest
1123
+ // .spyOn(GroupSystemAccessRepository.prototype, 'findAll')
1124
+ // .mockImplementation((options: any) => {
1125
+ // if (options.where.GroupCode === group.GroupCode) {
1126
+ // return Promise.resolve(systemAccess);
1127
+ // } else if (options.where.GroupCode === parentGroup.GroupCode) {
1128
+ // return Promise.resolve(parentSystemAccess);
1129
+ // }
1130
+ // });
1131
+
1132
+ // // Call the method
1133
+ // const result = await LoginUser['getInheritedSystemAccess'](
1134
+ // dbTransaction,
1135
+ // group,
1136
+ // );
1137
+
1138
+ // console.log(result);
1139
+ // // Assert the result
1140
+ // expect(result).toEqual([
1141
+ // {
1142
+ // SystemCode: 'system1',
1143
+ // GroupCode: 'group1',
1144
+ // System: { SystemCode: 'system1' },
1145
+ // },
1146
+ // {
1147
+ // SystemCode: 'system2',
1148
+ // GroupCode: 'group1',
1149
+ // System: { SystemCode: 'system1' },
1150
+ // },
1151
+ // {
1152
+ // SystemCode: 'system3',
1153
+ // GroupCode: 'parentGroup',
1154
+ // System: { SystemCode: 'system3' },
1155
+ // },
1156
+ // ]);
1157
+ // expect(groupFindByPkMock).toHaveBeenCalledWith(
1158
+ // group.ParentGroupCode,
1159
+ // dbTransaction,
1160
+ // );
1161
+ // expect(systemAccessFindAllMock).toHaveBeenCalledTimes(2);
1162
+ // });
1163
+ // });
1164
+ // });