@tomei/sso 0.64.1 → 0.65.1-test.1

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 (147) hide show
  1. package/.commitlintrc.json +22 -22
  2. package/.gitlab-ci.yml +237 -16
  3. package/.husky/commit-msg +15 -15
  4. package/.husky/pre-commit +7 -7
  5. package/.prettierrc +4 -4
  6. package/Jenkinsfile +57 -57
  7. package/README.md +23 -23
  8. package/__tests__/unit/components/api-key/api-key.spec.ts +201 -0
  9. package/__tests__/unit/components/group/group.spec.ts +85 -79
  10. package/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.ts +88 -88
  11. package/__tests__/unit/components/group-privilege/group-privilege.spec.ts +68 -68
  12. package/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.ts +74 -66
  13. package/__tests__/unit/components/group-system-access/group-system-access.spec.ts +83 -83
  14. package/__tests__/unit/components/login-user/l.spec.ts +746 -746
  15. package/__tests__/unit/components/login-user/login.spec.ts +2358 -1164
  16. package/__tests__/unit/components/password-hash/password-hash.service.spec.ts +31 -31
  17. package/__tests__/unit/components/system/system.spec.ts +255 -254
  18. package/__tests__/unit/components/system-privilege/system-privilege.spec.ts +83 -83
  19. package/__tests__/unit/components/user-group/user-group.spec.ts +86 -86
  20. package/__tests__/unit/components/user-object-privilege/user-object-privilege.spec.ts +78 -78
  21. package/__tests__/unit/components/user-password-history/user-password-history.spec.ts +165 -0
  22. package/__tests__/unit/components/user-privilege/user-privilege.spec.ts +72 -72
  23. package/__tests__/unit/components/user-reporting-hierarchy/user-reporting-hierarchy.spec.ts +233 -0
  24. package/__tests__/unit/components/user-system-access/user-system-access.spec.ts +89 -89
  25. package/__tests__/unit/redis-client/redis.service.spec.ts +23 -23
  26. package/__tests__/unit/session/session.service.spec.ts +47 -47
  27. package/__tests__/unit/system-privilege/system-privilage.spec.ts +91 -91
  28. package/coverage/cobertura-coverage.xml +6837 -0
  29. package/coverage/test-report.xml +130 -40
  30. package/create-sso-user.sql +39 -39
  31. package/dist/__tests__/unit/components/{group-privilege/group-privilege.test.d.ts → api-key/api-key.spec.d.ts} +1 -1
  32. package/dist/__tests__/unit/components/api-key/api-key.spec.js +158 -0
  33. package/dist/__tests__/unit/components/api-key/api-key.spec.js.map +1 -0
  34. package/dist/__tests__/unit/components/group/group.spec.js +4 -0
  35. package/dist/__tests__/unit/components/group/group.spec.js.map +1 -1
  36. package/dist/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.js +9 -1
  37. package/dist/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.js.map +1 -1
  38. package/dist/__tests__/unit/components/login-user/login.spec.js +703 -0
  39. package/dist/__tests__/unit/components/login-user/login.spec.js.map +1 -1
  40. package/dist/__tests__/unit/components/system/system.spec.js +1 -0
  41. package/dist/__tests__/unit/components/system/system.spec.js.map +1 -1
  42. package/dist/__tests__/unit/components/user-password-history/user-password-history.spec.d.ts +1 -0
  43. package/dist/__tests__/unit/components/user-password-history/user-password-history.spec.js +138 -0
  44. package/dist/__tests__/unit/components/user-password-history/user-password-history.spec.js.map +1 -0
  45. package/dist/__tests__/unit/components/user-reporting-hierarchy/user-reporting-hierarchy.spec.d.ts +1 -0
  46. package/dist/__tests__/unit/components/user-reporting-hierarchy/user-reporting-hierarchy.spec.js +182 -0
  47. package/dist/__tests__/unit/components/user-reporting-hierarchy/user-reporting-hierarchy.spec.js.map +1 -0
  48. package/dist/src/components/login-user/user.js +1 -1
  49. package/dist/src/components/login-user/user.js.map +1 -1
  50. package/dist/tsconfig.tsbuildinfo +1 -1
  51. package/eslint.config.mjs +58 -58
  52. package/jest.config.js +16 -14
  53. package/migrations/20240314080602-create-user-table.js +124 -124
  54. package/migrations/20240314080603-create-user-group-table.js +85 -85
  55. package/migrations/20240314080604-create-user-user-group-table.js +55 -55
  56. package/migrations/20240314080605-create-login-history-table.js +53 -53
  57. package/migrations/20240527064925-create-system-table.js +78 -78
  58. package/migrations/20240527064926-create-system-privilege-table.js +71 -71
  59. package/migrations/20240527065342-create-group-table.js +93 -93
  60. package/migrations/20240527065633-create-group-reporting-user-table.js +76 -76
  61. package/migrations/20240528011551-create-group-system-access-table.js +72 -72
  62. package/migrations/20240528023018-user-system-access-table.js +75 -75
  63. package/migrations/20240528032229-user-privilege-table.js +76 -76
  64. package/migrations/20240528063003-create-group-privilege-table.js +76 -76
  65. package/migrations/20240528063051-create-group-object-privilege-table.js +84 -84
  66. package/migrations/20240528063107-create-user-object-privilege-table.js +84 -84
  67. package/migrations/20240528063108-create-api-key-table.js +85 -85
  68. package/migrations/20241104104802-create-building-table.js +95 -95
  69. package/migrations/20250108091132-add-area-manager-user-id-to-building-table.js +14 -14
  70. package/migrations/20250108091133-add-passcode-to-user-table.js +36 -36
  71. package/migrations/20250210115636-create-user-reporting-hierarchy.js +76 -76
  72. package/migrations/20250326043818-crate-user-password-history.js +42 -42
  73. package/migrations/20250610070720-added-MFBypassYN-to-sso-user.js +30 -30
  74. package/migrations/20250805085707-add-bulk-approval-code-to-sso-user.js +29 -0
  75. package/package.json +87 -87
  76. package/sampledotenv +7 -7
  77. package/src/components/login-user/user.ts +1 -1
  78. package/tsconfig.build.json +5 -5
  79. package/tsconfig.json +23 -23
  80. package/coverage/clover.xml +0 -1380
  81. package/coverage/coverage-final.json +0 -39
  82. package/coverage/lcov-report/base.css +0 -224
  83. package/coverage/lcov-report/block-navigation.js +0 -87
  84. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.repository.ts.html +0 -160
  85. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.ts.html +0 -919
  86. package/coverage/lcov-report/components/group-object-privilege/index.html +0 -131
  87. package/coverage/lcov-report/components/group-privilege/group-privilege.repository.ts.html +0 -172
  88. package/coverage/lcov-report/components/group-privilege/group-privilege.ts.html +0 -337
  89. package/coverage/lcov-report/components/group-privilege/index.html +0 -131
  90. package/coverage/lcov-report/components/group-system-access/group-system-access.repository.ts.html +0 -214
  91. package/coverage/lcov-report/components/group-system-access/group-system-access.ts.html +0 -355
  92. package/coverage/lcov-report/components/group-system-access/index.html +0 -131
  93. package/coverage/lcov-report/components/password-hash/index.html +0 -116
  94. package/coverage/lcov-report/components/password-hash/password-hash.service.ts.html +0 -127
  95. package/coverage/lcov-report/components/system-privilege/index.html +0 -116
  96. package/coverage/lcov-report/components/system-privilege/system-privilege.repository.ts.html +0 -139
  97. package/coverage/lcov-report/components/user-group/index.html +0 -131
  98. package/coverage/lcov-report/components/user-group/user-group.repository.ts.html +0 -142
  99. package/coverage/lcov-report/components/user-group/user-group.ts.html +0 -2377
  100. package/coverage/lcov-report/components/user-object-privilege/index.html +0 -131
  101. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.repository.ts.html +0 -118
  102. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.ts.html +0 -322
  103. package/coverage/lcov-report/components/user-privilege/index.html +0 -131
  104. package/coverage/lcov-report/components/user-privilege/user-privilege.repository.ts.html +0 -160
  105. package/coverage/lcov-report/components/user-privilege/user-privilege.ts.html +0 -2071
  106. package/coverage/lcov-report/components/user-system-access/index.html +0 -131
  107. package/coverage/lcov-report/components/user-system-access/user-system-access.repository.ts.html +0 -208
  108. package/coverage/lcov-report/components/user-system-access/user-system-access.ts.html +0 -2236
  109. package/coverage/lcov-report/enum/api-key.enum.ts.html +0 -100
  110. package/coverage/lcov-report/enum/group-type.enum.ts.html +0 -109
  111. package/coverage/lcov-report/enum/index.html +0 -206
  112. package/coverage/lcov-report/enum/index.ts.html +0 -103
  113. package/coverage/lcov-report/enum/login-status.enum.ts.html +0 -97
  114. package/coverage/lcov-report/enum/object-status.enum.ts.html +0 -97
  115. package/coverage/lcov-report/enum/user-status.enum.ts.html +0 -106
  116. package/coverage/lcov-report/enum/yn.enum.ts.html +0 -97
  117. package/coverage/lcov-report/favicon.png +0 -0
  118. package/coverage/lcov-report/index.html +0 -296
  119. package/coverage/lcov-report/models/group-object-privilege.entity.ts.html +0 -358
  120. package/coverage/lcov-report/models/group-privilege.entity.ts.html +0 -319
  121. package/coverage/lcov-report/models/group-reporting-user.entity.ts.html +0 -370
  122. package/coverage/lcov-report/models/group-system-access.entity.ts.html +0 -328
  123. package/coverage/lcov-report/models/group.entity.ts.html +0 -466
  124. package/coverage/lcov-report/models/index.html +0 -296
  125. package/coverage/lcov-report/models/staff.entity.ts.html +0 -358
  126. package/coverage/lcov-report/models/system-privilege.entity.ts.html +0 -355
  127. package/coverage/lcov-report/models/system.entity.ts.html +0 -424
  128. package/coverage/lcov-report/models/user-group.entity.ts.html +0 -358
  129. package/coverage/lcov-report/models/user-object-privilege.entity.ts.html +0 -355
  130. package/coverage/lcov-report/models/user-privilege.entity.ts.html +0 -319
  131. package/coverage/lcov-report/models/user-system-access.entity.ts.html +0 -346
  132. package/coverage/lcov-report/models/user.entity.ts.html +0 -685
  133. package/coverage/lcov-report/prettify.css +0 -1
  134. package/coverage/lcov-report/prettify.js +0 -2
  135. package/coverage/lcov-report/redis-client/index.html +0 -116
  136. package/coverage/lcov-report/redis-client/redis.service.ts.html +0 -310
  137. package/coverage/lcov-report/session/index.html +0 -116
  138. package/coverage/lcov-report/session/session.service.ts.html +0 -373
  139. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  140. package/coverage/lcov-report/sorter.js +0 -210
  141. package/coverage/lcov.info +0 -2223
  142. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js +0 -71
  143. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js.map +0 -1
  144. package/dist/__tests__/unit/components/login-user/login-user.spec.d.ts +0 -0
  145. package/dist/__tests__/unit/components/login-user/login-user.spec.js +0 -6
  146. package/dist/__tests__/unit/components/login-user/login-user.spec.js.map +0 -1
  147. package/sonar-project.properties +0 -23
@@ -1,73 +1,73 @@
1
- import { UserPrivilege } from '../../../../src/components/user-privilege/user-privilege';
2
- import { UserPrivilegeRepository } from '../../../../src/components/user-privilege/user-privilege.repository';
3
- import { ClassError } from '@tomei/general';
4
-
5
- describe('UserPrivilege', () => {
6
- let userPrivilege: UserPrivilege;
7
- const userPrivilegeAttr = {
8
- UserPrivilegeId: 1,
9
- UserId: 1,
10
- SystemPrivilegeId: 'privilege1',
11
- Status: 'active',
12
- CreatedById: 1,
13
- CreatedAt: new Date(),
14
- UpdatedById: 1,
15
- UpdatedAt: new Date(),
16
- };
17
-
18
- beforeEach(() => {
19
- userPrivilege = new (UserPrivilege as any)(userPrivilegeAttr);
20
- });
21
-
22
- afterEach(() => {
23
- jest.clearAllMocks();
24
- });
25
-
26
- describe('constructor', () => {
27
- it('should create a new UserPrivilege instance', () => {
28
- expect(userPrivilege).toBeDefined();
29
- expect(userPrivilege).toBeInstanceOf(UserPrivilege);
30
- expect(userPrivilege.UserPrivilegeId).toBe(userPrivilegeAttr.UserPrivilegeId);
31
- expect(userPrivilege.UserId).toBe(userPrivilegeAttr.UserId);
32
- expect(userPrivilege.SystemPrivilegeId).toBe(userPrivilegeAttr.SystemPrivilegeId);
33
- expect(userPrivilege.Status).toBe(userPrivilegeAttr.Status);
34
- expect(userPrivilege.CreatedById).toBe(userPrivilegeAttr.CreatedById);
35
- expect(userPrivilege.CreatedAt).toBe(userPrivilegeAttr.CreatedAt);
36
- expect(userPrivilege.UpdatedById).toBe(userPrivilegeAttr.UpdatedById);
37
- expect(userPrivilege.UpdatedAt).toBe(userPrivilegeAttr.UpdatedAt);
38
- });
39
- });
40
-
41
- describe('init', () => {
42
- it('should initialize UserPrivilege with valid UserPrivilegeId', async () => {
43
- const findOneMock = jest
44
- .spyOn(UserPrivilegeRepository.prototype, 'findOne')
45
- .mockResolvedValueOnce(userPrivilegeAttr as any);
46
-
47
- const result = await UserPrivilege.init(null, 1);
48
-
49
- expect(findOneMock).toHaveBeenCalledTimes(1);
50
- expect(findOneMock).toHaveBeenCalledWith({
51
- where: { UserPrivilegeId: 1 },
52
- transaction: null,
53
- });
54
- expect(result).toBeInstanceOf(UserPrivilege);
55
- expect(result.UserPrivilegeId).toBe(userPrivilegeAttr.UserPrivilegeId);
56
- expect(result.UserId).toBe(userPrivilegeAttr.UserId);
57
- expect(result.SystemPrivilegeId).toBe(userPrivilegeAttr.SystemPrivilegeId);
58
- expect(result.Status).toBe(userPrivilegeAttr.Status);
59
- expect(result.CreatedById).toBe(userPrivilegeAttr.CreatedById);
60
- expect(result.CreatedAt).toBe(userPrivilegeAttr.CreatedAt);
61
- expect(result.UpdatedById).toBe(userPrivilegeAttr.UpdatedById);
62
- expect(result.UpdatedAt).toBe(userPrivilegeAttr.UpdatedAt);
63
- });
64
-
65
- it('should throw ClassError when UserPrivilegeId is not found', async () => {
66
- jest
67
- .spyOn(UserPrivilegeRepository.prototype, 'findOne')
68
- .mockResolvedValueOnce(null);
69
-
70
- await expect(UserPrivilege.init(null, 1)).rejects.toThrow(ClassError);
71
- });
72
- });
1
+ import { UserPrivilege } from '../../../../src/components/user-privilege/user-privilege';
2
+ import { UserPrivilegeRepository } from '../../../../src/components/user-privilege/user-privilege.repository';
3
+ import { ClassError } from '@tomei/general';
4
+
5
+ describe('UserPrivilege', () => {
6
+ let userPrivilege: UserPrivilege;
7
+ const userPrivilegeAttr = {
8
+ UserPrivilegeId: 1,
9
+ UserId: 1,
10
+ SystemPrivilegeId: 'privilege1',
11
+ Status: 'active',
12
+ CreatedById: 1,
13
+ CreatedAt: new Date(),
14
+ UpdatedById: 1,
15
+ UpdatedAt: new Date(),
16
+ };
17
+
18
+ beforeEach(() => {
19
+ userPrivilege = new (UserPrivilege as any)(userPrivilegeAttr);
20
+ });
21
+
22
+ afterEach(() => {
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ describe('constructor', () => {
27
+ it('should create a new UserPrivilege instance', () => {
28
+ expect(userPrivilege).toBeDefined();
29
+ expect(userPrivilege).toBeInstanceOf(UserPrivilege);
30
+ expect(userPrivilege.UserPrivilegeId).toBe(userPrivilegeAttr.UserPrivilegeId);
31
+ expect(userPrivilege.UserId).toBe(userPrivilegeAttr.UserId);
32
+ expect(userPrivilege.SystemPrivilegeId).toBe(userPrivilegeAttr.SystemPrivilegeId);
33
+ expect(userPrivilege.Status).toBe(userPrivilegeAttr.Status);
34
+ expect(userPrivilege.CreatedById).toBe(userPrivilegeAttr.CreatedById);
35
+ expect(userPrivilege.CreatedAt).toBe(userPrivilegeAttr.CreatedAt);
36
+ expect(userPrivilege.UpdatedById).toBe(userPrivilegeAttr.UpdatedById);
37
+ expect(userPrivilege.UpdatedAt).toBe(userPrivilegeAttr.UpdatedAt);
38
+ });
39
+ });
40
+
41
+ describe('init', () => {
42
+ it('should initialize UserPrivilege with valid UserPrivilegeId', async () => {
43
+ const findOneMock = jest
44
+ .spyOn(UserPrivilegeRepository.prototype, 'findOne')
45
+ .mockResolvedValueOnce(userPrivilegeAttr as any);
46
+
47
+ const result = await UserPrivilege.init(null, 1);
48
+
49
+ expect(findOneMock).toHaveBeenCalledTimes(1);
50
+ expect(findOneMock).toHaveBeenCalledWith({
51
+ where: { UserPrivilegeId: 1 },
52
+ transaction: null,
53
+ });
54
+ expect(result).toBeInstanceOf(UserPrivilege);
55
+ expect(result.UserPrivilegeId).toBe(userPrivilegeAttr.UserPrivilegeId);
56
+ expect(result.UserId).toBe(userPrivilegeAttr.UserId);
57
+ expect(result.SystemPrivilegeId).toBe(userPrivilegeAttr.SystemPrivilegeId);
58
+ expect(result.Status).toBe(userPrivilegeAttr.Status);
59
+ expect(result.CreatedById).toBe(userPrivilegeAttr.CreatedById);
60
+ expect(result.CreatedAt).toBe(userPrivilegeAttr.CreatedAt);
61
+ expect(result.UpdatedById).toBe(userPrivilegeAttr.UpdatedById);
62
+ expect(result.UpdatedAt).toBe(userPrivilegeAttr.UpdatedAt);
63
+ });
64
+
65
+ it('should throw ClassError when UserPrivilegeId is not found', async () => {
66
+ jest
67
+ .spyOn(UserPrivilegeRepository.prototype, 'findOne')
68
+ .mockResolvedValueOnce(null);
69
+
70
+ await expect(UserPrivilege.init(null, 1)).rejects.toThrow(ClassError);
71
+ });
72
+ });
73
73
  });
@@ -0,0 +1,233 @@
1
+ // LoginUser must be imported first to prime the module cache and avoid circular dependency
2
+ // (user-reporting-hierarchy → user.ts → login-user.ts → user.ts circular)
3
+ import { LoginUser } from '../../../../src/components/login-user/login-user';
4
+ import { User } from '../../../../src/components/login-user/user';
5
+ import { UserReportingHierarchy } from '../../../../src/components/user-reporting-hierarchy/user-reporting-hierarchy';
6
+ import { UserReportingHierarchyRepository } from '../../../../src/components/user-reporting-hierarchy/user-reporting-hierarchy.repository';
7
+ import { ApplicationConfig } from '@tomei/config';
8
+ import { Activity } from '@tomei/activity-history';
9
+ import { ClassError } from '@tomei/general';
10
+
11
+ describe('UserReportingHierarchy', () => {
12
+ const loginUser = new (LoginUser.prototype as any).constructor();
13
+ loginUser.ObjectId = '1';
14
+ loginUser.UserId = 1;
15
+
16
+ const hierarchyData = {
17
+ UserReportingHierarchyId: 1,
18
+ ReportingUserId: 10,
19
+ UserId: 20,
20
+ Rank: 1,
21
+ Status: 'Active',
22
+ CreatedById: 1,
23
+ CreatedAt: new Date('2024-01-01'),
24
+ UpdatedById: 1,
25
+ UpdatedAt: new Date('2024-01-01'),
26
+ get: (opts?: any) => ({
27
+ UserReportingHierarchyId: 1,
28
+ ReportingUserId: 10,
29
+ UserId: 20,
30
+ Rank: 1,
31
+ Status: 'Active',
32
+ CreatedById: 1,
33
+ CreatedAt: new Date('2024-01-01'),
34
+ UpdatedById: 1,
35
+ UpdatedAt: new Date('2024-01-01'),
36
+ }),
37
+ };
38
+
39
+ afterEach(() => {
40
+ jest.clearAllMocks();
41
+ });
42
+
43
+ beforeEach(() => {
44
+ jest
45
+ .spyOn(ApplicationConfig, 'getComponentConfigValue')
46
+ .mockReturnValue('TST' as any);
47
+ jest
48
+ .spyOn(Activity.prototype, 'create')
49
+ .mockResolvedValue(undefined as any);
50
+ jest
51
+ .spyOn(LoginUser.prototype, 'checkPrivileges')
52
+ .mockResolvedValue(true as any);
53
+ });
54
+
55
+ describe('init', () => {
56
+ it('should return a new instance when no id is provided', async () => {
57
+ const result = await UserReportingHierarchy.init();
58
+ expect(result).toBeInstanceOf(UserReportingHierarchy);
59
+ expect(result.UserReportingHierarchyId).toBeNaN();
60
+ });
61
+
62
+ it('should initialize with valid id', async () => {
63
+ jest
64
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findByPk')
65
+ .mockResolvedValueOnce(hierarchyData as any);
66
+
67
+ const result = await UserReportingHierarchy.init(1);
68
+
69
+ expect(result).toBeInstanceOf(UserReportingHierarchy);
70
+ expect(result.ReportingUserId).toBe(10);
71
+ expect(result.UserId).toBe(20);
72
+ expect(result.Rank).toBe(1);
73
+ });
74
+
75
+ it('should throw ClassError when id is not found', async () => {
76
+ jest
77
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findByPk')
78
+ .mockResolvedValueOnce(null);
79
+
80
+ await expect(UserReportingHierarchy.init(999)).rejects.toThrow(
81
+ 'UserReportingHierarchy not found',
82
+ );
83
+ });
84
+ });
85
+
86
+ describe('createUserReportingHierarchy', () => {
87
+ it('should throw when user lacks USER_REPORTING_HIERARCHY_CREATE privilege', async () => {
88
+ jest
89
+ .spyOn(LoginUser.prototype, 'checkPrivileges')
90
+ .mockResolvedValueOnce(false as any);
91
+ jest.spyOn(User, 'init').mockResolvedValue(loginUser as any);
92
+
93
+ const hierarchy = await UserReportingHierarchy.init();
94
+ await expect(
95
+ hierarchy.createUserReportingHierarchy(loginUser, null, 10, 20, 1, 'Active'),
96
+ ).rejects.toThrow('User does not have the required privileges');
97
+ });
98
+
99
+ it('should throw when relationship already exists', async () => {
100
+ jest.spyOn(User, 'init').mockResolvedValue(loginUser as any);
101
+ jest
102
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findOne')
103
+ .mockResolvedValueOnce(hierarchyData as any);
104
+
105
+ const hierarchy = await UserReportingHierarchy.init();
106
+ await expect(
107
+ hierarchy.createUserReportingHierarchy(loginUser, null, 10, 20, 1, 'Active'),
108
+ ).rejects.toThrow('Relationship already exists');
109
+ });
110
+
111
+ it('should throw when rank already exists', async () => {
112
+ jest.spyOn(User, 'init').mockResolvedValue(loginUser as any);
113
+ jest
114
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findOne')
115
+ .mockResolvedValueOnce(null) // no existing relationship
116
+ .mockResolvedValueOnce(hierarchyData as any); // rank exists
117
+
118
+ const hierarchy = await UserReportingHierarchy.init();
119
+ await expect(
120
+ hierarchy.createUserReportingHierarchy(loginUser, null, 10, 20, 1, 'Active'),
121
+ ).rejects.toThrow('Rank already exists');
122
+ });
123
+
124
+ it('should throw when previous rank is not yet assigned (rank > 1)', async () => {
125
+ jest.spyOn(User, 'init').mockResolvedValue(loginUser as any);
126
+ jest
127
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findOne')
128
+ .mockResolvedValueOnce(null) // no existing relationship
129
+ .mockResolvedValueOnce(null) // rank 2 not taken
130
+ .mockResolvedValueOnce(null); // rank 1 (predecessor) not found
131
+
132
+ const hierarchy = await UserReportingHierarchy.init();
133
+ await expect(
134
+ hierarchy.createUserReportingHierarchy(loginUser, null, 10, 20, 2, 'Active'),
135
+ ).rejects.toThrow('Rank before the new rank is not yet assigned to the user');
136
+ });
137
+
138
+ it('should create hierarchy successfully', async () => {
139
+ jest.spyOn(User, 'init').mockResolvedValue(loginUser as any);
140
+ jest
141
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findOne')
142
+ .mockResolvedValueOnce(null) // no existing relationship
143
+ .mockResolvedValueOnce(null); // rank 1 not taken
144
+ const createSpy = jest
145
+ .spyOn(UserReportingHierarchyRepository.prototype, 'create')
146
+ .mockResolvedValueOnce(hierarchyData as any);
147
+
148
+ const hierarchy = await UserReportingHierarchy.init();
149
+ const result = await hierarchy.createUserReportingHierarchy(
150
+ loginUser,
151
+ null,
152
+ 10,
153
+ 20,
154
+ 1,
155
+ 'Active',
156
+ );
157
+
158
+ expect(createSpy).toHaveBeenCalledTimes(1);
159
+ expect(result).toBeInstanceOf(UserReportingHierarchy);
160
+ });
161
+ });
162
+
163
+ describe('updateUserReportingHierarchy', () => {
164
+ it('should throw when user lacks USER_REPORTING_HIERARCHY_UPDATE privilege', async () => {
165
+ jest.spyOn(User, 'init').mockResolvedValue(loginUser as any);
166
+ jest
167
+ .spyOn(LoginUser.prototype, 'checkPrivileges')
168
+ .mockResolvedValueOnce(false as any);
169
+
170
+ jest
171
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findByPk')
172
+ .mockResolvedValueOnce(hierarchyData as any);
173
+
174
+ const hierarchy = await UserReportingHierarchy.init(1);
175
+ await expect(
176
+ hierarchy.updateUserReportingHierarchy(loginUser, null, 10, 20, 1, 'Active'),
177
+ ).rejects.toThrow('User does not have the required privileges');
178
+ });
179
+
180
+ it('should update successfully', async () => {
181
+ jest.spyOn(User, 'init').mockResolvedValue(loginUser as any);
182
+ jest
183
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findByPk')
184
+ .mockResolvedValueOnce(hierarchyData as any);
185
+ jest
186
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findOne')
187
+ .mockResolvedValueOnce(null) // no duplicate relationship
188
+ .mockResolvedValueOnce(null); // rank 1 not taken by other
189
+ const updateSpy = jest
190
+ .spyOn(UserReportingHierarchyRepository.prototype, 'update')
191
+ .mockResolvedValueOnce(undefined as any);
192
+
193
+ const hierarchy = await UserReportingHierarchy.init(1);
194
+ const result = await hierarchy.updateUserReportingHierarchy(
195
+ loginUser,
196
+ null,
197
+ 10,
198
+ 20,
199
+ 1,
200
+ 'Active',
201
+ );
202
+
203
+ expect(updateSpy).toHaveBeenCalledTimes(1);
204
+ expect(result).toBeInstanceOf(UserReportingHierarchy);
205
+ });
206
+ });
207
+
208
+ describe('removeUserReportingHierarchy', () => {
209
+ it('should throw when user lacks USER_REPORTING_HIERARCHY_REMOVE privilege', async () => {
210
+ jest
211
+ .spyOn(LoginUser.prototype, 'checkPrivileges')
212
+ .mockResolvedValueOnce(false as any);
213
+
214
+ await expect(
215
+ UserReportingHierarchy.removeUserReportingHierarchy(loginUser, null, 1),
216
+ ).rejects.toThrow('Insufficient privileges to remove reporting hierarchy');
217
+ });
218
+
219
+ it('should remove hierarchy successfully', async () => {
220
+ jest
221
+ .spyOn(UserReportingHierarchyRepository.prototype, 'findByPk')
222
+ .mockResolvedValueOnce(hierarchyData as any);
223
+ const destroySpy = jest
224
+ .spyOn(UserReportingHierarchyRepository.prototype, 'destroy')
225
+ .mockResolvedValueOnce(undefined as any);
226
+
227
+ await UserReportingHierarchy.removeUserReportingHierarchy(loginUser, null, 1);
228
+
229
+ expect(destroySpy).toHaveBeenCalledTimes(1);
230
+ expect(destroySpy).toHaveBeenCalledWith(1, null);
231
+ });
232
+ });
233
+ });
@@ -1,90 +1,90 @@
1
- import { UserSystemAccess } from '../../../../src/components/user-system-access/user-system-access';
2
- import { UserSystemAccessRepository } from '../../../../src/components/user-system-access/user-system-access.repository';
3
- import { ClassError } from '@tomei/general';
4
-
5
- describe('UserSystemAccess', () => {
6
- let userSystemAccess: UserSystemAccess;
7
- const userSystemAccessAttr = {
8
- UserSystemAccessId: 1,
9
- UserId: 1,
10
- SystemCode: 'system1',
11
- Status: 'active',
12
- CreatedById: 1,
13
- CreatedAt: new Date(),
14
- UpdatedById: 1,
15
- UpdatedAt: new Date(),
16
- };
17
-
18
- beforeEach(() => {
19
- userSystemAccess = new (UserSystemAccess as any)(userSystemAccessAttr);
20
- });
21
-
22
- afterEach(() => {
23
- jest.clearAllMocks();
24
- });
25
-
26
- describe('constructor', () => {
27
- it('should create a new UserSystemAccess instance', () => {
28
- expect(userSystemAccess).toBeDefined();
29
- expect(userSystemAccess).toBeInstanceOf(UserSystemAccess);
30
- expect(userSystemAccess.UserSystemAccessId).toBe(
31
- userSystemAccessAttr.UserSystemAccessId
32
- );
33
- expect(userSystemAccess.UserId).toBe(userSystemAccessAttr.UserId);
34
- expect(userSystemAccess.SystemCode).toBe(userSystemAccessAttr.SystemCode);
35
- expect(userSystemAccess.Status).toBe(userSystemAccessAttr.Status);
36
- expect(userSystemAccess.CreatedById).toBe(
37
- userSystemAccessAttr.CreatedById
38
- );
39
- expect(userSystemAccess.CreatedAt).toBe(userSystemAccessAttr.CreatedAt);
40
- expect(userSystemAccess.UpdatedById).toBe(
41
- userSystemAccessAttr.UpdatedById
42
- );
43
- expect(userSystemAccess.UpdatedAt).toBe(userSystemAccessAttr.UpdatedAt);
44
- });
45
- });
46
-
47
- describe('init', () => {
48
- it('should initialize UserSystemAccess with valid UserSystemAccessId', async () => {
49
- const findOneMock = jest
50
- .spyOn(UserSystemAccessRepository.prototype, 'findOne')
51
- .mockResolvedValueOnce({
52
- ...userSystemAccessAttr,
53
- get: () => userSystemAccessAttr,
54
- } as any);
55
-
56
- const result = await UserSystemAccess.init(null, 1);
57
-
58
- expect(findOneMock).toHaveBeenCalledTimes(1);
59
- expect(findOneMock).toHaveBeenCalledWith({
60
- where: { UserSystemAccessId: 1 },
61
- transaction: null,
62
- });
63
- expect(result).toBeInstanceOf(UserSystemAccess);
64
- expect(result.UserSystemAccessId).toBe(
65
- userSystemAccessAttr.UserSystemAccessId
66
- );
67
- expect(result.UserId).toBe(userSystemAccessAttr.UserId);
68
- expect(result.SystemCode).toBe(userSystemAccessAttr.SystemCode);
69
- expect(result.Status).toBe(userSystemAccessAttr.Status);
70
- expect(result.CreatedById).toBe(userSystemAccessAttr.CreatedById);
71
- expect(result.CreatedAt).toBe(userSystemAccessAttr.CreatedAt);
72
- expect(result.UpdatedById).toBe(userSystemAccessAttr.UpdatedById);
73
- expect(result.UpdatedAt).toBe(userSystemAccessAttr.UpdatedAt);
74
- });
75
-
76
- it('should throw ClassError when UserSystemAccessId is not found', async () => {
77
- jest
78
- .spyOn(UserSystemAccessRepository.prototype, 'findOne')
79
- .mockResolvedValueOnce(null);
80
-
81
- try {
82
- await UserSystemAccess.init(null, 1)
83
- expect(false).toBe(true);
84
- } catch (error) {
85
- expect(error).toBeInstanceOf(ClassError);
86
- expect(error.message).toBe('UserSystemAccess not found');
87
- }
88
- });
89
- });
1
+ import { UserSystemAccess } from '../../../../src/components/user-system-access/user-system-access';
2
+ import { UserSystemAccessRepository } from '../../../../src/components/user-system-access/user-system-access.repository';
3
+ import { ClassError } from '@tomei/general';
4
+
5
+ describe('UserSystemAccess', () => {
6
+ let userSystemAccess: UserSystemAccess;
7
+ const userSystemAccessAttr = {
8
+ UserSystemAccessId: 1,
9
+ UserId: 1,
10
+ SystemCode: 'system1',
11
+ Status: 'active',
12
+ CreatedById: 1,
13
+ CreatedAt: new Date(),
14
+ UpdatedById: 1,
15
+ UpdatedAt: new Date(),
16
+ };
17
+
18
+ beforeEach(() => {
19
+ userSystemAccess = new (UserSystemAccess as any)(userSystemAccessAttr);
20
+ });
21
+
22
+ afterEach(() => {
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ describe('constructor', () => {
27
+ it('should create a new UserSystemAccess instance', () => {
28
+ expect(userSystemAccess).toBeDefined();
29
+ expect(userSystemAccess).toBeInstanceOf(UserSystemAccess);
30
+ expect(userSystemAccess.UserSystemAccessId).toBe(
31
+ userSystemAccessAttr.UserSystemAccessId
32
+ );
33
+ expect(userSystemAccess.UserId).toBe(userSystemAccessAttr.UserId);
34
+ expect(userSystemAccess.SystemCode).toBe(userSystemAccessAttr.SystemCode);
35
+ expect(userSystemAccess.Status).toBe(userSystemAccessAttr.Status);
36
+ expect(userSystemAccess.CreatedById).toBe(
37
+ userSystemAccessAttr.CreatedById
38
+ );
39
+ expect(userSystemAccess.CreatedAt).toBe(userSystemAccessAttr.CreatedAt);
40
+ expect(userSystemAccess.UpdatedById).toBe(
41
+ userSystemAccessAttr.UpdatedById
42
+ );
43
+ expect(userSystemAccess.UpdatedAt).toBe(userSystemAccessAttr.UpdatedAt);
44
+ });
45
+ });
46
+
47
+ describe('init', () => {
48
+ it('should initialize UserSystemAccess with valid UserSystemAccessId', async () => {
49
+ const findOneMock = jest
50
+ .spyOn(UserSystemAccessRepository.prototype, 'findOne')
51
+ .mockResolvedValueOnce({
52
+ ...userSystemAccessAttr,
53
+ get: () => userSystemAccessAttr,
54
+ } as any);
55
+
56
+ const result = await UserSystemAccess.init(null, 1);
57
+
58
+ expect(findOneMock).toHaveBeenCalledTimes(1);
59
+ expect(findOneMock).toHaveBeenCalledWith({
60
+ where: { UserSystemAccessId: 1 },
61
+ transaction: null,
62
+ });
63
+ expect(result).toBeInstanceOf(UserSystemAccess);
64
+ expect(result.UserSystemAccessId).toBe(
65
+ userSystemAccessAttr.UserSystemAccessId
66
+ );
67
+ expect(result.UserId).toBe(userSystemAccessAttr.UserId);
68
+ expect(result.SystemCode).toBe(userSystemAccessAttr.SystemCode);
69
+ expect(result.Status).toBe(userSystemAccessAttr.Status);
70
+ expect(result.CreatedById).toBe(userSystemAccessAttr.CreatedById);
71
+ expect(result.CreatedAt).toBe(userSystemAccessAttr.CreatedAt);
72
+ expect(result.UpdatedById).toBe(userSystemAccessAttr.UpdatedById);
73
+ expect(result.UpdatedAt).toBe(userSystemAccessAttr.UpdatedAt);
74
+ });
75
+
76
+ it('should throw ClassError when UserSystemAccessId is not found', async () => {
77
+ jest
78
+ .spyOn(UserSystemAccessRepository.prototype, 'findOne')
79
+ .mockResolvedValueOnce(null);
80
+
81
+ try {
82
+ await UserSystemAccess.init(null, 1)
83
+ expect(false).toBe(true);
84
+ } catch (error) {
85
+ expect(error).toBeInstanceOf(ClassError);
86
+ expect(error.message).toBe('UserSystemAccess not found');
87
+ }
88
+ });
89
+ });
90
90
  });
@@ -1,24 +1,24 @@
1
- import { RedisService } from "../../../src/redis-client/redis.service";
2
- require('dotenv').config()
3
- // nneed to figure out how to mock redis
4
- describe('redis.service', () => {
5
-
6
- afterEach(() => {
7
- jest.restoreAllMocks()
8
- })
9
-
10
- it('should return redis service when instansiated', async () => {
11
- const redisService = await RedisService.init();
12
- expect(redisService).toBeDefined();
13
- });
14
-
15
- it('should able to write and read redis', async () => {
16
- const data = {
17
- test: 'test'
18
- }
19
- const redisService = await RedisService.init();
20
- await redisService.set("test", data, 60 * 60 * 24 * 1)
21
- const result = await redisService.get("test");
22
- expect(result).toEqual(JSON.stringify(data));
23
- });
1
+ import { RedisService } from "../../../src/redis-client/redis.service";
2
+ require('dotenv').config()
3
+ // nneed to figure out how to mock redis
4
+ describe('redis.service', () => {
5
+
6
+ afterEach(() => {
7
+ jest.restoreAllMocks()
8
+ })
9
+
10
+ it('should return redis service when instansiated', async () => {
11
+ const redisService = await RedisService.init();
12
+ expect(redisService).toBeDefined();
13
+ });
14
+
15
+ it('should able to write and read redis', async () => {
16
+ const data = {
17
+ test: 'test'
18
+ }
19
+ const redisService = await RedisService.init();
20
+ await redisService.set("test", data, 60 * 60 * 24 * 1)
21
+ const result = await redisService.get("test");
22
+ expect(result).toEqual(JSON.stringify(data));
23
+ });
24
24
  });