Mirror of https://github.com/roostorg/coop
github.com/roostorg/coop
1import { uid } from 'uid';
2
3import getBottle, { type Dependencies } from '../../iocContainer/index.js';
4import { type UserStrikeService } from './index.js';
5
6describe('Item Investigation Service', () => {
7 let container: Dependencies;
8 let userStrikeService: UserStrikeService;
9
10 beforeAll(async () => {
11 // The mutation should be ok here since this is initial setup in a
12 // beforeAll; it doesn't involve reset state for each test in the suite
13
14 ({ container } = await getBottle());
15 userStrikeService = container.UserStrikeService;
16 });
17 afterAll(async () => {
18 await container.closeSharedResourcesForShutdown();
19 });
20
21 test('Should properly calculate strike counts for a given user', async () => {
22 const fakeUserId = { id: uid(), typeId: uid() };
23 const fakeOrgId = uid();
24 await userStrikeService.applyUserStrike(
25 fakeOrgId,
26 fakeUserId,
27 'fakePolicyId',
28 1,
29 );
30 const strikeCount1 = await userStrikeService.getUserStrikeValue(
31 fakeOrgId,
32 fakeUserId,
33 );
34 expect(strikeCount1).toEqual(1);
35 await userStrikeService.applyUserStrike(
36 fakeOrgId,
37 fakeUserId,
38 'fakePolicyId1',
39 1,
40 );
41 const strikeCount2 = await userStrikeService.getUserStrikeValue(
42 fakeOrgId,
43 fakeUserId,
44 );
45 expect(strikeCount2).toEqual(2);
46 await userStrikeService.applyUserStrike(
47 fakeOrgId,
48 fakeUserId,
49 'fakePolicyId2',
50 10,
51 );
52 const strikeCount3 = await userStrikeService.getUserStrikeValue(
53 fakeOrgId,
54 fakeUserId,
55 );
56 expect(strikeCount3).toEqual(12);
57 });
58
59 test('Should only apply strike for most severe policy violation', async () => {
60 const testActions = [
61 {
62 orgId: 'fakeOrgId',
63 action: {
64 id: 'fakeActionId1',
65 name: 'testAction1',
66 description: null,
67 applyUserStrikes: true,
68 orgId: 'fakeOrgId',
69 penalty: 'NONE' as const,
70 callbackUrl: 'fakeCallbackUrl1',
71 callbackUrlHeaders: null,
72 callbackUrlBody: null,
73 customMrtApiParams: null,
74 actionType: 'CUSTOM_ACTION' as const,
75 },
76 targetItem: { itemId: 'fakeItemId1', itemType: 'fakeItemType1' },
77 matchingRules: undefined,
78 ruleEnvironment: undefined,
79 policies: [
80 {
81 id: 'fakePolicyId1',
82 name: 'testPolicy1',
83 userStrikeCount: 1,
84 penalty: 'LOW' as const,
85 },
86 {
87 id: 'severePolicyId',
88 name: 'testPolicy2',
89 userStrikeCount: 2,
90 penalty: 'LOW' as const,
91 },
92 ],
93 },
94 ];
95 const mostSeverePolicyViolation =
96 userStrikeService.findMostSeverePolicyViolationFromActions(testActions);
97 if (mostSeverePolicyViolation === undefined) {
98 throw new Error('mostSeverePolicyViolation is undefined');
99 }
100 expect(mostSeverePolicyViolation.id).toEqual('severePolicyId');
101 });
102 test('findMostSeverePolicyViolationFromActions should return undefined if no actions apply user strikes', async () => {
103 const testActions = [
104 {
105 orgId: 'fakeOrgId',
106 action: {
107 id: 'fakeActionId1',
108 name: 'testAction1',
109 description: null,
110 applyUserStrikes: false,
111 orgId: 'fakeOrgId',
112 penalty: 'NONE' as const,
113 callbackUrl: 'fakeCallbackUrl1',
114 callbackUrlHeaders: null,
115 callbackUrlBody: null,
116 customMrtApiParams: null,
117 actionType: 'CUSTOM_ACTION' as const,
118 },
119 targetItem: { itemId: 'fakeItemId1', itemType: 'fakeItemType1' },
120 matchingRules: undefined,
121 ruleEnvironment: undefined,
122 policies: [
123 {
124 id: 'fakePolicyId1',
125 name: 'testPolicy1',
126 userStrikeCount: 1,
127 penalty: 'LOW' as const,
128 },
129 {
130 id: 'severePolicyId',
131 name: 'testPolicy2',
132 userStrikeCount: 2,
133 penalty: 'LOW' as const,
134 },
135 ],
136 },
137 {
138 orgId: 'fakeOrgId',
139 action: {
140 id: 'fakeActionId1',
141 name: 'testAction1',
142 description: null,
143 applyUserStrikes: false,
144 orgId: 'fakeOrgId',
145 penalty: 'NONE' as const,
146 callbackUrl: 'fakeCallbackUrl1',
147 callbackUrlHeaders: null,
148 callbackUrlBody: null,
149 customMrtApiParams: null,
150 actionType: 'CUSTOM_ACTION' as const,
151 },
152 targetItem: { itemId: 'fakeItemId1', itemType: 'fakeItemType1' },
153 matchingRules: undefined,
154 ruleEnvironment: undefined,
155 policies: [
156 {
157 id: 'fakePolicyId1',
158 name: 'testPolicy1',
159 userStrikeCount: 1,
160 penalty: 'LOW' as const,
161 },
162 {
163 id: 'severePolicyId',
164 name: 'testPolicy2',
165 userStrikeCount: 2,
166 penalty: 'LOW' as const,
167 },
168 ],
169 },
170 ];
171 const mostSeverePolicyViolation =
172 userStrikeService.findMostSeverePolicyViolationFromActions(testActions);
173 expect(mostSeverePolicyViolation).toBeUndefined();
174 });
175
176 test('Should properly calculate strike values using getAllUserStrikeCountsForOrg', async () => {
177 const fakeTypeId = uid();
178 const fakeUserId1 = { id: uid(), typeId: fakeTypeId };
179 const fakeUserId2 = { id: uid(), typeId: fakeTypeId };
180 const fakeUserId3 = { id: uid(), typeId: fakeTypeId };
181 const fakeOrgId = uid();
182 // 1 strike for user 1
183 await userStrikeService.applyUserStrike(
184 fakeOrgId,
185 fakeUserId1,
186 'fakePolicyId',
187 1,
188 );
189 // 2 strikes for user 2
190 await userStrikeService.applyUserStrike(
191 fakeOrgId,
192 fakeUserId2,
193 'fakePolicyId',
194 1,
195 );
196 await userStrikeService.applyUserStrike(
197 fakeOrgId,
198 fakeUserId2,
199 'fakePolicyId1',
200 1,
201 );
202 // 3 strikes for user 3
203 await userStrikeService.applyUserStrike(
204 fakeOrgId,
205 fakeUserId3,
206 'fakePolicyId1',
207 1,
208 );
209 await userStrikeService.applyUserStrike(
210 fakeOrgId,
211 fakeUserId3,
212 'fakePolicyId2',
213 1,
214 );
215 await userStrikeService.applyUserStrike(
216 fakeOrgId,
217 fakeUserId3,
218 'fakePolicyId3',
219 1,
220 );
221
222 const userStrikesForOrg =
223 await userStrikeService.getAllUserStrikeCountsForOrg(fakeOrgId);
224 const user1 = userStrikesForOrg.find(
225 (it) => it.user_identifier.id === fakeUserId1.id,
226 );
227 expect(user1?.strike_count).toEqual(1);
228 const user2 = userStrikesForOrg.find(
229 (it) => it.user_identifier.id === fakeUserId2.id,
230 );
231 expect(user2?.strike_count).toEqual(2);
232 const user3 = userStrikesForOrg.find(
233 (it) => it.user_identifier.id === fakeUserId3.id,
234 );
235 expect(user3?.strike_count).toEqual(3);
236 });
237});