@stamhoofd/backend 2.103.0 → 2.104.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -10
- package/src/endpoints/global/events/PatchEventsEndpoint.test.ts +264 -2
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +15 -4
- package/src/endpoints/global/files/ExportToExcelEndpoint.ts +1 -1
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +130 -2
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +17 -3
- package/src/endpoints/organization/dashboard/registration-periods/MoveRegistrationPeriods.test.ts +486 -0
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +130 -10
- package/src/helpers/AdminPermissionChecker.ts +15 -7
- package/src/helpers/PeriodHelper.ts +1 -1
- package/src/helpers/fetchToAsyncIterator.ts +7 -0
- package/src/services/PaymentService.ts +1 -1
- package/tests/assertions/assertBalances.ts +13 -1
- package/tests/helpers/PayconiqMocker.ts +8 -0
- package/tests/jest.setup.ts +0 -1
package/src/endpoints/organization/dashboard/registration-periods/MoveRegistrationPeriods.test.ts
ADDED
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import { Request } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { GroupFactory, MemberFactory, Organization, OrganizationFactory, OrganizationRegistrationPeriod, OrganizationRegistrationPeriodFactory, Registration, RegistrationFactory, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
|
|
3
|
+
import { Group, GroupType, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, PermissionLevel, Permissions, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
|
|
4
|
+
import { PatchOrganizationRegistrationPeriodsEndpoint } from './PatchOrganizationRegistrationPeriodsEndpoint';
|
|
5
|
+
|
|
6
|
+
import { PatchableArray, PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
|
|
7
|
+
|
|
8
|
+
import { testServer } from '../../../../../tests/helpers/TestServer';
|
|
9
|
+
import { STExpect, TestUtils } from '@stamhoofd/test-utils';
|
|
10
|
+
|
|
11
|
+
const endpoint = new PatchOrganizationRegistrationPeriodsEndpoint();
|
|
12
|
+
|
|
13
|
+
describe('Endpoint.PatchOrganizationRegistrationPeriodsEndpoint.MoveRegistrationPeriods', () => {
|
|
14
|
+
let period: RegistrationPeriod;
|
|
15
|
+
let organization: Organization;
|
|
16
|
+
let organizationRegistrationPeriod: OrganizationRegistrationPeriod;
|
|
17
|
+
let token: Token;
|
|
18
|
+
let allGroupsToken: Token;
|
|
19
|
+
|
|
20
|
+
describe('Organization mode', () => {
|
|
21
|
+
beforeEach(async () => {
|
|
22
|
+
TestUtils.setEnvironment('userMode', 'organization');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
period = await new RegistrationPeriodFactory({}).create();
|
|
27
|
+
organization = await new OrganizationFactory({ period }).create();
|
|
28
|
+
period.organizationId = organization.id;
|
|
29
|
+
await period.save();
|
|
30
|
+
organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period }).create();
|
|
31
|
+
|
|
32
|
+
const user = await new UserFactory({
|
|
33
|
+
organization,
|
|
34
|
+
permissions: Permissions.create({
|
|
35
|
+
level: PermissionLevel.Full,
|
|
36
|
+
}),
|
|
37
|
+
}).create();
|
|
38
|
+
token = await Token.createToken(user);
|
|
39
|
+
|
|
40
|
+
const allGroupsUser = await new UserFactory({
|
|
41
|
+
organization,
|
|
42
|
+
permissions: Permissions.create({
|
|
43
|
+
resources: new Map([[
|
|
44
|
+
PermissionsResourceType.Groups,
|
|
45
|
+
new Map([[
|
|
46
|
+
'', ResourcePermissions.create({
|
|
47
|
+
level: PermissionLevel.Full,
|
|
48
|
+
}),
|
|
49
|
+
]]),
|
|
50
|
+
]]),
|
|
51
|
+
}),
|
|
52
|
+
}).create();
|
|
53
|
+
allGroupsToken = await Token.createToken(allGroupsUser);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const patchOrganizationRegistrationPeriods = async ({ patch, organization, token }: { patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> | OrganizationRegistrationPeriodStruct[]; organization: Organization; token: Token }) => {
|
|
57
|
+
const request = Request.buildJson('PATCH', `/v${Version}/organization/registration-periods`, organization.getApiHost(), patch);
|
|
58
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
59
|
+
return await testServer.test(endpoint, request);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
test('Moving group to a different period is possible', async () => {
|
|
63
|
+
const group = await new GroupFactory({ organization }).create();
|
|
64
|
+
|
|
65
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
66
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
67
|
+
|
|
68
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
69
|
+
|
|
70
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
71
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
72
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
73
|
+
|
|
74
|
+
body.addPatch(periodPatch);
|
|
75
|
+
|
|
76
|
+
const result = await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
77
|
+
|
|
78
|
+
expect(result.body).toHaveLength(1);
|
|
79
|
+
expect(result.body[0].groups).toHaveLength(1);
|
|
80
|
+
expect(result.body[0].groups[0].id).toBe(group.id);
|
|
81
|
+
expect(result.body[0].groups[0].periodId).toBe(otherPeriod.id);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('Moving group to a different period is possible as non-full admin', async () => {
|
|
85
|
+
const group = await new GroupFactory({ organization }).create();
|
|
86
|
+
|
|
87
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
88
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
89
|
+
|
|
90
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
91
|
+
|
|
92
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
93
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
94
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
95
|
+
|
|
96
|
+
body.addPatch(periodPatch);
|
|
97
|
+
|
|
98
|
+
const result = await patchOrganizationRegistrationPeriods({ patch: body, organization, token: allGroupsToken });
|
|
99
|
+
|
|
100
|
+
expect(result.body).toHaveLength(1);
|
|
101
|
+
expect(result.body[0].groups).toHaveLength(1);
|
|
102
|
+
expect(result.body[0].groups[0].id).toBe(group.id);
|
|
103
|
+
expect(result.body[0].groups[0].periodId).toBe(otherPeriod.id);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('Move group to period of other organization should fail', async () => {
|
|
107
|
+
const group = await new GroupFactory({ organization }).create();
|
|
108
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
109
|
+
|
|
110
|
+
const otherOrganization = await new OrganizationFactory({}).create();
|
|
111
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization: otherOrganization }).create();
|
|
112
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
113
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
114
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
115
|
+
|
|
116
|
+
body.addPatch(periodPatch);
|
|
117
|
+
|
|
118
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow('Cannot patch periodId to a different period then the one being patched');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('Move group to other period than period being patched should fail', async () => {
|
|
122
|
+
const group = await new GroupFactory({ organization }).create();
|
|
123
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
124
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
125
|
+
|
|
126
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
127
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
128
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
129
|
+
|
|
130
|
+
body.addPatch(periodPatch);
|
|
131
|
+
|
|
132
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow('Cannot patch periodId to a different period then the one being patched');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('Moving group TO locked period should fail as normal admin', async () => {
|
|
136
|
+
const group = await new GroupFactory({ organization }).create();
|
|
137
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
138
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization, locked: true }).create();
|
|
139
|
+
const organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
140
|
+
|
|
141
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
142
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
143
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
144
|
+
|
|
145
|
+
body.addPatch(periodPatch);
|
|
146
|
+
|
|
147
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token: allGroupsToken })).rejects.toThrow(STExpect.simpleError({
|
|
148
|
+
code: 'locked_period',
|
|
149
|
+
message: 'This period is locked',
|
|
150
|
+
}));
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('Moving group FROM locked period should fail as normal admin', async () => {
|
|
154
|
+
const initialPeriod = await new RegistrationPeriodFactory({ organization, locked: true }).create();
|
|
155
|
+
await new OrganizationRegistrationPeriodFactory({ organization, period: initialPeriod }).create();
|
|
156
|
+
const group = await new GroupFactory({ organization, period: initialPeriod }).create();
|
|
157
|
+
|
|
158
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
159
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
160
|
+
const organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
161
|
+
|
|
162
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
163
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
164
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
165
|
+
|
|
166
|
+
body.addPatch(periodPatch);
|
|
167
|
+
|
|
168
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token: allGroupsToken })).rejects.toThrow(STExpect.simpleError({
|
|
169
|
+
code: 'permission_denied',
|
|
170
|
+
}));
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('Moving group TO locked period should not fail as full admin', async () => {
|
|
174
|
+
const group = await new GroupFactory({ organization }).create();
|
|
175
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
176
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization, locked: true }).create();
|
|
177
|
+
const organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
178
|
+
|
|
179
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
180
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
181
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
182
|
+
|
|
183
|
+
body.addPatch(periodPatch);
|
|
184
|
+
|
|
185
|
+
const result = await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
186
|
+
|
|
187
|
+
expect(result.body).toHaveLength(1);
|
|
188
|
+
expect(result.body[0].groups).toHaveLength(1);
|
|
189
|
+
expect(result.body[0].groups[0].id).toBe(group.id);
|
|
190
|
+
expect(result.body[0].groups[0].periodId).toBe(otherPeriod.id);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('Moving group FROM locked period should not fail as full admin', async () => {
|
|
194
|
+
const initialPeriod = await new RegistrationPeriodFactory({ organization, locked: true }).create();
|
|
195
|
+
await new OrganizationRegistrationPeriodFactory({ organization, period: initialPeriod }).create();
|
|
196
|
+
const group = await new GroupFactory({ organization, period: initialPeriod }).create();
|
|
197
|
+
|
|
198
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
199
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
200
|
+
const organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
201
|
+
|
|
202
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
203
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
204
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
205
|
+
|
|
206
|
+
body.addPatch(periodPatch);
|
|
207
|
+
|
|
208
|
+
const result = await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
209
|
+
|
|
210
|
+
expect(result.body).toHaveLength(1);
|
|
211
|
+
expect(result.body[0].groups).toHaveLength(1);
|
|
212
|
+
expect(result.body[0].groups[0].id).toBe(group.id);
|
|
213
|
+
expect(result.body[0].groups[0].periodId).toBe(otherPeriod.id);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test('Move group to period if waiting list linked to other groups should fail', async () => {
|
|
217
|
+
const waitingList = await new GroupFactory({ organization, type: GroupType.WaitingList }).create();
|
|
218
|
+
const group = await new GroupFactory({ organization, waitingListId: waitingList.id }).create();
|
|
219
|
+
// link other group to waiting list
|
|
220
|
+
await new GroupFactory({ organization, waitingListId: waitingList.id }).create();
|
|
221
|
+
|
|
222
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
223
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
224
|
+
|
|
225
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
226
|
+
|
|
227
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
228
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
229
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
230
|
+
|
|
231
|
+
body.addPatch(periodPatch);
|
|
232
|
+
|
|
233
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow('Group has waiting list with other groups in the current period');
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('Move group with other type than Membership should fail', async () => {
|
|
237
|
+
const group = await new GroupFactory({ organization, type: GroupType.EventRegistration }).create();
|
|
238
|
+
|
|
239
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
240
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
241
|
+
|
|
242
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
243
|
+
|
|
244
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
245
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
246
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
247
|
+
|
|
248
|
+
body.addPatch(periodPatch);
|
|
249
|
+
|
|
250
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow(`Moving group with type ${GroupType.EventRegistration} to a different period is not supported`);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test('Move group to period if waiting list only linked to this group should also update waiting list period', async () => {
|
|
254
|
+
const waitingList = await new GroupFactory({ organization, type: GroupType.WaitingList }).create();
|
|
255
|
+
const group = await new GroupFactory({ organization, waitingListId: waitingList.id }).create();
|
|
256
|
+
|
|
257
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
258
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
259
|
+
|
|
260
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
261
|
+
|
|
262
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
263
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
264
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
265
|
+
|
|
266
|
+
body.addPatch(periodPatch);
|
|
267
|
+
|
|
268
|
+
const result = await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
269
|
+
|
|
270
|
+
expect(result.body).toHaveLength(1);
|
|
271
|
+
expect(result.body[0].groups).toHaveLength(2);
|
|
272
|
+
expect(result.body[0].groups).toEqual(
|
|
273
|
+
expect.arrayContaining([expect.objectContaining({ id: group.id, periodId: otherPeriod.id }), expect.objectContaining({ id: waitingList.id, periodId: otherPeriod.id })]),
|
|
274
|
+
);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test('Move group to period should also update period of registrations in group', async () => {
|
|
278
|
+
const group = await new GroupFactory({ organization }).create();
|
|
279
|
+
const member = await new MemberFactory({ organization }).create();
|
|
280
|
+
const registration = await new RegistrationFactory({ group, member }).create();
|
|
281
|
+
|
|
282
|
+
const otherPeriod = await new RegistrationPeriodFactory({ organization }).create();
|
|
283
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
284
|
+
|
|
285
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
286
|
+
|
|
287
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
288
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
289
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
290
|
+
|
|
291
|
+
body.addPatch(periodPatch);
|
|
292
|
+
|
|
293
|
+
await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
294
|
+
|
|
295
|
+
const updatedRegistration = await Registration.getByID(registration.id);
|
|
296
|
+
|
|
297
|
+
expect(updatedRegistration!.periodId).toBe(otherPeriod.id);
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
describe('Platform mode', () => {
|
|
302
|
+
beforeEach(async () => {
|
|
303
|
+
TestUtils.setEnvironment('userMode', 'platform');
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
beforeAll(async () => {
|
|
307
|
+
period = await new RegistrationPeriodFactory({}).create();
|
|
308
|
+
organization = await new OrganizationFactory({ period }).create();
|
|
309
|
+
await period.save();
|
|
310
|
+
organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period }).create();
|
|
311
|
+
|
|
312
|
+
const user = await new UserFactory({
|
|
313
|
+
organization,
|
|
314
|
+
permissions: Permissions.create({
|
|
315
|
+
level: PermissionLevel.Full,
|
|
316
|
+
}),
|
|
317
|
+
}).create();
|
|
318
|
+
token = await Token.createToken(user);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
const patchOrganizationRegistrationPeriods = async ({ patch, organization, token }: { patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> | OrganizationRegistrationPeriodStruct[]; organization: Organization; token: Token }) => {
|
|
322
|
+
const request = Request.buildJson('PATCH', `/v${Version}/organization/registration-periods`, organization.getApiHost(), patch);
|
|
323
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
324
|
+
return await testServer.test(endpoint, request);
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
test('Moving group to a different period is possible', async () => {
|
|
328
|
+
const group = await new GroupFactory({ organization }).create();
|
|
329
|
+
|
|
330
|
+
const otherPeriod = await new RegistrationPeriodFactory({ }).create();
|
|
331
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
332
|
+
|
|
333
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
334
|
+
|
|
335
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
336
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
337
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
338
|
+
|
|
339
|
+
body.addPatch(periodPatch);
|
|
340
|
+
|
|
341
|
+
const result = await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
342
|
+
|
|
343
|
+
expect(result.body).toHaveLength(1);
|
|
344
|
+
expect(result.body[0].groups).toHaveLength(1);
|
|
345
|
+
expect(result.body[0].groups[0].id).toBe(group.id);
|
|
346
|
+
expect(result.body[0].groups[0].periodId).toBe(otherPeriod.id);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
test('Move group to other period than period being patched should fail', async () => {
|
|
350
|
+
const group = await new GroupFactory({ organization }).create();
|
|
351
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
352
|
+
const otherPeriod = await new RegistrationPeriodFactory({ }).create();
|
|
353
|
+
|
|
354
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
355
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
356
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
357
|
+
|
|
358
|
+
body.addPatch(periodPatch);
|
|
359
|
+
|
|
360
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow('Cannot patch periodId to a different period then the one being patched');
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
test('Moving group TO locked period should fail', async () => {
|
|
364
|
+
const group = await new GroupFactory({ organization }).create();
|
|
365
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
366
|
+
const otherPeriod = await new RegistrationPeriodFactory({ locked: true }).create();
|
|
367
|
+
const organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
368
|
+
|
|
369
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
370
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
371
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
372
|
+
|
|
373
|
+
body.addPatch(periodPatch);
|
|
374
|
+
|
|
375
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow(STExpect.simpleError({
|
|
376
|
+
code: 'locked_period',
|
|
377
|
+
message: 'This period is locked',
|
|
378
|
+
}));
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
test('Moving group FROM locked period should fail', async () => {
|
|
382
|
+
const initialPeriod = await new RegistrationPeriodFactory({ locked: true }).create();
|
|
383
|
+
await new OrganizationRegistrationPeriodFactory({ organization, period: initialPeriod }).create();
|
|
384
|
+
const group = await new GroupFactory({ organization, period: initialPeriod }).create();
|
|
385
|
+
|
|
386
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
387
|
+
const otherPeriod = await new RegistrationPeriodFactory({ }).create();
|
|
388
|
+
const organizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
389
|
+
|
|
390
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: organizationRegistrationPeriod.id });
|
|
391
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
392
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
393
|
+
|
|
394
|
+
body.addPatch(periodPatch);
|
|
395
|
+
|
|
396
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow(STExpect.simpleError({
|
|
397
|
+
code: 'locked_period',
|
|
398
|
+
message: 'This period is locked',
|
|
399
|
+
}));
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
test('Move group to period if waiting list linked to other groups should fail', async () => {
|
|
403
|
+
const waitingList = await new GroupFactory({ organization, type: GroupType.WaitingList }).create();
|
|
404
|
+
const group = await new GroupFactory({ organization, waitingListId: waitingList.id }).create();
|
|
405
|
+
// link other group to waiting list
|
|
406
|
+
await new GroupFactory({ organization, waitingListId: waitingList.id }).create();
|
|
407
|
+
|
|
408
|
+
const otherPeriod = await new RegistrationPeriodFactory({ }).create();
|
|
409
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
410
|
+
|
|
411
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
412
|
+
|
|
413
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
414
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
415
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
416
|
+
|
|
417
|
+
body.addPatch(periodPatch);
|
|
418
|
+
|
|
419
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow('Group has waiting list with other groups in the current period');
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
test('Move group with other type than Membership should fail', async () => {
|
|
423
|
+
const group = await new GroupFactory({ organization, type: GroupType.EventRegistration }).create();
|
|
424
|
+
|
|
425
|
+
const otherPeriod = await new RegistrationPeriodFactory({ }).create();
|
|
426
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
427
|
+
|
|
428
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
429
|
+
|
|
430
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
431
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
432
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
433
|
+
|
|
434
|
+
body.addPatch(periodPatch);
|
|
435
|
+
|
|
436
|
+
await expect(patchOrganizationRegistrationPeriods({ patch: body, organization, token })).rejects.toThrow(`Moving group with type ${GroupType.EventRegistration} to a different period is not supported`);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
test('Move group to period if waiting list only linked to this group should also update waiting list period', async () => {
|
|
440
|
+
const waitingList = await new GroupFactory({ organization, type: GroupType.WaitingList }).create();
|
|
441
|
+
const group = await new GroupFactory({ organization, waitingListId: waitingList.id }).create();
|
|
442
|
+
|
|
443
|
+
const otherPeriod = await new RegistrationPeriodFactory({ }).create();
|
|
444
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
445
|
+
|
|
446
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
447
|
+
|
|
448
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
449
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
450
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
451
|
+
|
|
452
|
+
body.addPatch(periodPatch);
|
|
453
|
+
|
|
454
|
+
const result = await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
455
|
+
|
|
456
|
+
expect(result.body).toHaveLength(1);
|
|
457
|
+
expect(result.body[0].groups).toHaveLength(2);
|
|
458
|
+
expect(result.body[0].groups).toEqual(
|
|
459
|
+
expect.arrayContaining([expect.objectContaining({ id: group.id, periodId: otherPeriod.id }), expect.objectContaining({ id: waitingList.id, periodId: otherPeriod.id })]),
|
|
460
|
+
);
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
test('Move group to period should also update period of registrations in group', async () => {
|
|
464
|
+
const group = await new GroupFactory({ organization }).create();
|
|
465
|
+
const member = await new MemberFactory({ organization }).create();
|
|
466
|
+
const registration = await new RegistrationFactory({ group, member }).create();
|
|
467
|
+
|
|
468
|
+
const otherPeriod = await new RegistrationPeriodFactory({ }).create();
|
|
469
|
+
const otherOrganizationRegistrationPeriod = await new OrganizationRegistrationPeriodFactory({ organization, period: otherPeriod }).create();
|
|
470
|
+
|
|
471
|
+
const body = new PatchableArray() as PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
472
|
+
|
|
473
|
+
const periodPatch = OrganizationRegistrationPeriodStruct.patch({ id: otherOrganizationRegistrationPeriod.id });
|
|
474
|
+
const groupPatch = Group.patch({ id: group.id, periodId: otherPeriod.id });
|
|
475
|
+
periodPatch.groups.addPatch(groupPatch);
|
|
476
|
+
|
|
477
|
+
body.addPatch(periodPatch);
|
|
478
|
+
|
|
479
|
+
await patchOrganizationRegistrationPeriods({ patch: body, organization, token });
|
|
480
|
+
|
|
481
|
+
const updatedRegistration = await Registration.getByID(registration.id);
|
|
482
|
+
|
|
483
|
+
expect(updatedRegistration!.periodId).toBe(otherPeriod.id);
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
});
|