@stamhoofd/backend 2.74.0 → 2.75.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.
- package/index.ts +7 -2
- package/package.json +13 -13
- package/src/crons/update-cached-balances.ts +1 -2
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +2 -2
- package/src/endpoints/auth/CreateAdminEndpoint.ts +4 -15
- package/src/endpoints/auth/OpenIDConnectStartEndpoint.ts +0 -5
- package/src/endpoints/global/audit-logs/GetAuditLogsEndpoint.ts +2 -2
- package/src/endpoints/global/events/GetEventNotificationsCountEndpoint.ts +43 -0
- package/src/endpoints/global/events/GetEventNotificationsEndpoint.ts +181 -0
- package/src/endpoints/global/events/GetEventsEndpoint.ts +2 -2
- package/src/endpoints/global/events/PatchEventNotificationsEndpoint.ts +288 -0
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +2 -2
- package/src/endpoints/global/files/UploadFile.ts +56 -4
- package/src/endpoints/global/files/UploadImage.ts +9 -3
- package/src/endpoints/global/members/GetMembersEndpoint.ts +2 -2
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +10 -1
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +1 -5
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +7 -0
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +1 -1
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +2084 -164
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +2 -2
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +48 -2
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +8 -0
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +3 -3
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +2 -2
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +1 -2
- package/src/helpers/AdminPermissionChecker.ts +80 -2
- package/src/helpers/AuthenticatedStructures.ts +88 -2
- package/src/helpers/FlagMomentCleanup.ts +1 -8
- package/src/helpers/GlobalHelper.ts +15 -0
- package/src/helpers/MembershipCharger.ts +2 -1
- package/src/services/EventNotificationService.ts +201 -0
- package/src/services/FileSignService.ts +217 -0
- package/src/services/SSOService.ts +7 -2
- package/src/sql-filters/event-notifications.ts +39 -0
- package/src/sql-filters/organizations.ts +1 -1
- package/src/sql-sorters/event-notifications.ts +96 -0
- package/src/sql-sorters/events.ts +2 -2
- package/src/sql-sorters/organizations.ts +2 -2
- package/tests/e2e/private-files.test.ts +497 -0
- package/tests/e2e/register.test.ts +1197 -0
- package/tests/helpers/TestServer.ts +3 -0
- package/tests/jest.setup.ts +15 -2
- package/tsconfig.json +1 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Request } from '@simonbackx/simple-endpoints';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Email } from '@stamhoofd/email';
|
|
3
|
+
import { BalanceItemFactory, Group, GroupFactory, MemberFactory, MemberWithRegistrations, Organization, OrganizationFactory, Registration, RegistrationFactory, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
|
|
4
|
+
import { BalanceItemCartItem, BalanceItemType, Company, GroupOption, GroupOptionMenu, IDRegisterCart, IDRegisterCheckout, IDRegisterItem, OrganizationPackages, PayconiqAccount, PaymentCustomer, PaymentMethod, PermissionLevel, Permissions, ReduceablePrice, RegisterItemOption, STPackageStatus, STPackageType, UserPermissions, Version } from '@stamhoofd/structures';
|
|
4
5
|
import nock from 'nock';
|
|
5
6
|
import { v4 as uuidv4 } from 'uuid';
|
|
6
7
|
import { testServer } from '../../../../tests/helpers/TestServer';
|
|
@@ -12,17 +13,9 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
12
13
|
// #region global
|
|
13
14
|
const endpoint = new RegisterMembersEndpoint();
|
|
14
15
|
let period: RegistrationPeriod;
|
|
15
|
-
let organization: Organization;
|
|
16
|
-
let user: User;
|
|
17
|
-
let token: Token;
|
|
18
|
-
let member: MemberWithRegistrations;
|
|
19
|
-
let group1: Group;
|
|
20
|
-
let groupPrice1: GroupPrice;
|
|
21
|
-
let group2: Group;
|
|
22
|
-
let groupPrice2: GroupPrice;
|
|
23
16
|
|
|
24
17
|
// #region helpers
|
|
25
|
-
const post = async (body: IDRegisterCheckout) => {
|
|
18
|
+
const post = async (body: IDRegisterCheckout, organization: Organization, token: Token) => {
|
|
26
19
|
const request = Request.buildJson('POST', baseUrl, organization.getApiHost(), body);
|
|
27
20
|
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
28
21
|
return await testServer.test(endpoint, request);
|
|
@@ -32,54 +25,162 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
32
25
|
// #endregion
|
|
33
26
|
|
|
34
27
|
beforeAll(async () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
28
|
+
const previousPeriod = await new RegistrationPeriodFactory({
|
|
29
|
+
startDate: new Date(2022, 0, 1),
|
|
30
|
+
endDate: new Date(2022, 11, 31),
|
|
31
|
+
}).create();
|
|
32
|
+
|
|
33
|
+
period = await new RegistrationPeriodFactory({
|
|
34
|
+
startDate: new Date(2023, 0, 1),
|
|
35
|
+
endDate: new Date(2023, 11, 31),
|
|
36
|
+
}).create();
|
|
37
|
+
|
|
38
|
+
period.previousPeriodId = previousPeriod.id;
|
|
39
|
+
await period.save();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
afterEach(() => {
|
|
43
|
+
jest.restoreAllMocks();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const initOrganization = async (registrationPeriod: RegistrationPeriod = period) => {
|
|
47
|
+
return await new OrganizationFactory({ period: registrationPeriod })
|
|
48
|
+
.create();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const initData = async ({ otherMemberAmount = 0, permissionLevel = PermissionLevel.Full }: { otherMemberAmount?: number; permissionLevel?: PermissionLevel } = {}) => {
|
|
52
|
+
const organization = await initOrganization(period);
|
|
53
|
+
|
|
54
|
+
const user = await new UserFactory({
|
|
50
55
|
organization,
|
|
51
56
|
permissions: Permissions.create({
|
|
52
|
-
level:
|
|
57
|
+
level: permissionLevel,
|
|
53
58
|
}),
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
member = await new MemberFactory({ organization, user }).create();
|
|
57
|
-
});
|
|
59
|
+
})
|
|
60
|
+
.create();
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
const token = await Token.createToken(user);
|
|
63
|
+
|
|
64
|
+
const member = await new MemberFactory({ organization, user })
|
|
65
|
+
.create();
|
|
66
|
+
|
|
67
|
+
const otherMembers: MemberWithRegistrations[] = [];
|
|
68
|
+
|
|
69
|
+
for (let i = 0; i < otherMemberAmount; i++) {
|
|
70
|
+
otherMembers.push(await new MemberFactory({ organization, user })
|
|
71
|
+
.create());
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const group = await new GroupFactory({
|
|
62
75
|
organization,
|
|
63
76
|
price: 25,
|
|
64
77
|
stock: 5,
|
|
65
|
-
})
|
|
78
|
+
})
|
|
79
|
+
.create();
|
|
66
80
|
|
|
67
|
-
|
|
81
|
+
const groupPrice = group.settings.prices[0];
|
|
68
82
|
|
|
69
|
-
|
|
83
|
+
return {
|
|
70
84
|
organization,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
user,
|
|
86
|
+
token,
|
|
87
|
+
member,
|
|
88
|
+
otherMembers,
|
|
89
|
+
group,
|
|
90
|
+
groupPrice,
|
|
91
|
+
};
|
|
92
|
+
};
|
|
75
93
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
describe('Register', () => {
|
|
95
|
+
test('Should fail if cannot manage finances', async () => {
|
|
96
|
+
// #region arrange
|
|
97
|
+
const { member, group, groupPrice, organization, token } = await initData();
|
|
98
|
+
const organization2 = await initOrganization();
|
|
99
|
+
|
|
100
|
+
const registration = await new RegistrationFactory({
|
|
101
|
+
member,
|
|
102
|
+
group,
|
|
103
|
+
groupPrice,
|
|
104
|
+
}).create();
|
|
105
|
+
|
|
106
|
+
const body = IDRegisterCheckout.create({
|
|
107
|
+
cart: IDRegisterCart.create({
|
|
108
|
+
items: [
|
|
109
|
+
IDRegisterItem.create({
|
|
110
|
+
id: uuidv4(),
|
|
111
|
+
replaceRegistrationIds: [],
|
|
112
|
+
options: [],
|
|
113
|
+
groupPrice,
|
|
114
|
+
organizationId: organization.id,
|
|
115
|
+
groupId: group.id,
|
|
116
|
+
memberId: member.id,
|
|
117
|
+
}),
|
|
118
|
+
],
|
|
119
|
+
balanceItems: [],
|
|
120
|
+
deleteRegistrationIds: [registration.id],
|
|
121
|
+
}),
|
|
122
|
+
administrationFee: 0,
|
|
123
|
+
freeContribution: 0,
|
|
124
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
125
|
+
totalPrice: 5,
|
|
126
|
+
asOrganizationId: organization2.id,
|
|
127
|
+
customer: null,
|
|
128
|
+
});
|
|
129
|
+
// #endregion
|
|
130
|
+
|
|
131
|
+
// #region act and assert
|
|
132
|
+
await expect(async () => await post(body, organization, token))
|
|
133
|
+
.rejects
|
|
134
|
+
.toThrow('No permission to register as this organization for a different organization');
|
|
135
|
+
// #endregion
|
|
136
|
+
});
|
|
79
137
|
|
|
80
|
-
|
|
81
|
-
test('Should update registered mmebers', async () => {
|
|
138
|
+
test('Should fail if demo limit reached', async () => {
|
|
82
139
|
// #region arrange
|
|
140
|
+
(STAMHOOFD.userMode as string) = 'organization';
|
|
141
|
+
|
|
142
|
+
const spySendWebmaster = jest.spyOn(Email, 'sendWebmaster').mockImplementation(() => {
|
|
143
|
+
// do nothing
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const { member, group, groupPrice, organization, token, otherMembers } = await initData({ otherMemberAmount: 10 });
|
|
147
|
+
|
|
148
|
+
organization.meta.packages = OrganizationPackages.create({
|
|
149
|
+
packages: new Map([
|
|
150
|
+
[STPackageType.TrialMembers, STPackageStatus.create({
|
|
151
|
+
startDate: new Date(),
|
|
152
|
+
})],
|
|
153
|
+
]),
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
for (const member of otherMembers) {
|
|
157
|
+
const body = IDRegisterCheckout.create({
|
|
158
|
+
cart: IDRegisterCart.create({
|
|
159
|
+
items: [
|
|
160
|
+
IDRegisterItem.create({
|
|
161
|
+
id: uuidv4(),
|
|
162
|
+
replaceRegistrationIds: [],
|
|
163
|
+
options: [],
|
|
164
|
+
groupPrice,
|
|
165
|
+
organizationId: organization.id,
|
|
166
|
+
groupId: group.id,
|
|
167
|
+
memberId: member.id,
|
|
168
|
+
}),
|
|
169
|
+
],
|
|
170
|
+
balanceItems: [],
|
|
171
|
+
deleteRegistrationIds: [],
|
|
172
|
+
}),
|
|
173
|
+
administrationFee: 0,
|
|
174
|
+
freeContribution: 0,
|
|
175
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
176
|
+
totalPrice: 25,
|
|
177
|
+
asOrganizationId: organization.id,
|
|
178
|
+
customer: null,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
await post(body, organization, token);
|
|
182
|
+
}
|
|
183
|
+
|
|
83
184
|
const body = IDRegisterCheckout.create({
|
|
84
185
|
cart: IDRegisterCart.create({
|
|
85
186
|
items: [
|
|
@@ -87,9 +188,9 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
87
188
|
id: uuidv4(),
|
|
88
189
|
replaceRegistrationIds: [],
|
|
89
190
|
options: [],
|
|
90
|
-
groupPrice
|
|
191
|
+
groupPrice,
|
|
91
192
|
organizationId: organization.id,
|
|
92
|
-
groupId:
|
|
193
|
+
groupId: group.id,
|
|
93
194
|
memberId: member.id,
|
|
94
195
|
}),
|
|
95
196
|
],
|
|
@@ -105,30 +206,1665 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
105
206
|
});
|
|
106
207
|
// #endregion
|
|
107
208
|
|
|
108
|
-
// act
|
|
109
|
-
const response = await post(body);
|
|
209
|
+
// #region act and assert
|
|
110
210
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
211
|
+
await expect(async () => await post(body, organization, token))
|
|
212
|
+
.rejects
|
|
213
|
+
.toThrow('Too many e-mails limited');
|
|
214
|
+
|
|
215
|
+
expect(spySendWebmaster).toHaveBeenCalledOnce();
|
|
216
|
+
// #endregion
|
|
217
|
+
|
|
218
|
+
(STAMHOOFD.userMode as string) = 'platform';
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test('Should fail if balance items changed', async () => {
|
|
222
|
+
// #region arrange
|
|
223
|
+
const { member, group, user, groupPrice, organization, token } = await initData();
|
|
224
|
+
|
|
225
|
+
const balanceItem1 = await new BalanceItemFactory({
|
|
226
|
+
organizationId: organization.id,
|
|
227
|
+
memberId: member.id,
|
|
228
|
+
userId: user.id,
|
|
229
|
+
payingOrganizationId: organization.id,
|
|
230
|
+
type: BalanceItemType.Registration,
|
|
231
|
+
amount: 10,
|
|
232
|
+
unitPrice: 2,
|
|
233
|
+
}).create();
|
|
234
|
+
|
|
235
|
+
const cartItem = BalanceItemCartItem.create({
|
|
236
|
+
item: balanceItem1.getStructure(),
|
|
237
|
+
price: 20,
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
const body = IDRegisterCheckout.create({
|
|
241
|
+
cart: IDRegisterCart.create({
|
|
242
|
+
items: [
|
|
243
|
+
IDRegisterItem.create({
|
|
244
|
+
id: uuidv4(),
|
|
245
|
+
replaceRegistrationIds: [],
|
|
246
|
+
options: [],
|
|
247
|
+
groupPrice,
|
|
248
|
+
organizationId: organization.id,
|
|
249
|
+
groupId: group.id,
|
|
250
|
+
memberId: member.id,
|
|
251
|
+
}),
|
|
252
|
+
],
|
|
253
|
+
balanceItems: [
|
|
254
|
+
cartItem,
|
|
255
|
+
],
|
|
256
|
+
deleteRegistrationIds: [],
|
|
257
|
+
}),
|
|
258
|
+
administrationFee: 0,
|
|
259
|
+
freeContribution: 0,
|
|
260
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
261
|
+
totalPrice: 45,
|
|
262
|
+
customer: null,
|
|
263
|
+
});
|
|
264
|
+
// #endregion
|
|
265
|
+
|
|
266
|
+
// #region act and assert
|
|
267
|
+
await balanceItem1.delete();
|
|
268
|
+
|
|
269
|
+
await expect(async () => await post(body, organization, token))
|
|
270
|
+
.rejects
|
|
271
|
+
.toThrow(new RegExp('Oeps, één of meerdere openstaande bedragen in jouw winkelmandje zijn aangepast'));
|
|
272
|
+
// #endregion
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test('Should fail when pay balance item as organization', async () => {
|
|
276
|
+
// #region arrange
|
|
277
|
+
const { member, group, user, groupPrice, organization, token } = await initData();
|
|
278
|
+
|
|
279
|
+
const balanceItem1 = await new BalanceItemFactory({
|
|
280
|
+
organizationId: organization.id,
|
|
281
|
+
memberId: member.id,
|
|
282
|
+
userId: user.id,
|
|
283
|
+
payingOrganizationId: organization.id,
|
|
284
|
+
type: BalanceItemType.Registration,
|
|
285
|
+
amount: 10,
|
|
286
|
+
unitPrice: 2,
|
|
287
|
+
}).create();
|
|
288
|
+
|
|
289
|
+
const cartItem = BalanceItemCartItem.create({
|
|
290
|
+
item: balanceItem1.getStructure(),
|
|
291
|
+
price: 20,
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const body = IDRegisterCheckout.create({
|
|
295
|
+
cart: IDRegisterCart.create({
|
|
296
|
+
items: [
|
|
297
|
+
IDRegisterItem.create({
|
|
298
|
+
id: uuidv4(),
|
|
299
|
+
replaceRegistrationIds: [],
|
|
300
|
+
options: [],
|
|
301
|
+
groupPrice,
|
|
302
|
+
organizationId: organization.id,
|
|
303
|
+
groupId: group.id,
|
|
304
|
+
memberId: member.id,
|
|
305
|
+
}),
|
|
306
|
+
],
|
|
307
|
+
balanceItems: [
|
|
308
|
+
cartItem,
|
|
309
|
+
],
|
|
310
|
+
deleteRegistrationIds: [],
|
|
311
|
+
}),
|
|
312
|
+
administrationFee: 0,
|
|
313
|
+
freeContribution: 0,
|
|
314
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
315
|
+
totalPrice: 45,
|
|
316
|
+
asOrganizationId: organization.id,
|
|
317
|
+
customer: null,
|
|
318
|
+
});
|
|
319
|
+
// #endregion
|
|
320
|
+
|
|
321
|
+
// #region act and assert
|
|
322
|
+
await expect(async () => await post(body, organization, token))
|
|
323
|
+
.rejects
|
|
324
|
+
.toThrow(new RegExp('Not possible to pay balance items as the organization'));
|
|
325
|
+
// #endregion
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test('Should fail if has no write access for member', async () => {
|
|
329
|
+
// #region arrange
|
|
330
|
+
const { organization, group, groupPrice, token } = await initData();
|
|
331
|
+
const { member: member2 } = await initData();
|
|
332
|
+
|
|
333
|
+
const body = IDRegisterCheckout.create({
|
|
334
|
+
cart: IDRegisterCart.create({
|
|
335
|
+
items: [
|
|
336
|
+
IDRegisterItem.create({
|
|
337
|
+
id: uuidv4(),
|
|
338
|
+
replaceRegistrationIds: [],
|
|
339
|
+
options: [],
|
|
340
|
+
groupPrice,
|
|
341
|
+
organizationId: organization.id,
|
|
342
|
+
groupId: group.id,
|
|
343
|
+
memberId: member2.id,
|
|
344
|
+
}),
|
|
345
|
+
],
|
|
346
|
+
balanceItems: [
|
|
347
|
+
],
|
|
348
|
+
deleteRegistrationIds: [],
|
|
349
|
+
}),
|
|
350
|
+
administrationFee: 0,
|
|
351
|
+
freeContribution: 0,
|
|
352
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
353
|
+
totalPrice: 25,
|
|
354
|
+
customer: null,
|
|
355
|
+
});
|
|
356
|
+
// #endregion
|
|
357
|
+
|
|
358
|
+
// #region act and assert
|
|
359
|
+
await expect(async () => await post(body, organization, token))
|
|
360
|
+
.rejects
|
|
361
|
+
.toThrow(new RegExp('No permission to register this member'));
|
|
362
|
+
// #endregion
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test('Should fail if empty cart', async () => {
|
|
366
|
+
// #region arrange
|
|
367
|
+
const { member, user, organization, token } = await initData();
|
|
368
|
+
|
|
369
|
+
const balanceItem1 = await new BalanceItemFactory({
|
|
370
|
+
organizationId: organization.id,
|
|
371
|
+
memberId: member.id,
|
|
372
|
+
userId: user.id,
|
|
373
|
+
payingOrganizationId: organization.id,
|
|
374
|
+
type: BalanceItemType.Registration,
|
|
375
|
+
amount: 10,
|
|
376
|
+
unitPrice: 2,
|
|
377
|
+
}).create();
|
|
378
|
+
|
|
379
|
+
const body = IDRegisterCheckout.create({
|
|
380
|
+
cart: IDRegisterCart.create({
|
|
381
|
+
items: [
|
|
382
|
+
],
|
|
383
|
+
balanceItems: [
|
|
384
|
+
],
|
|
385
|
+
deleteRegistrationIds: [],
|
|
386
|
+
}),
|
|
387
|
+
administrationFee: 0,
|
|
388
|
+
freeContribution: 0,
|
|
389
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
390
|
+
totalPrice: 45,
|
|
391
|
+
customer: null,
|
|
392
|
+
});
|
|
393
|
+
// #endregion
|
|
394
|
+
|
|
395
|
+
// #region act and assert
|
|
396
|
+
await balanceItem1.delete();
|
|
397
|
+
|
|
398
|
+
await expect(async () => await post(body, organization, token))
|
|
399
|
+
.rejects
|
|
400
|
+
.toThrow(new RegExp('Oeps, jouw mandje is leeg.'));
|
|
401
|
+
// #endregion
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
test('Should fail if price changed', async () => {
|
|
405
|
+
// #region arrange
|
|
406
|
+
const { member, group, groupPrice, organization, token } = await initData();
|
|
407
|
+
|
|
408
|
+
const body = IDRegisterCheckout.create({
|
|
409
|
+
cart: IDRegisterCart.create({
|
|
410
|
+
items: [
|
|
411
|
+
IDRegisterItem.create({
|
|
412
|
+
id: uuidv4(),
|
|
413
|
+
replaceRegistrationIds: [],
|
|
414
|
+
options: [],
|
|
415
|
+
groupPrice,
|
|
416
|
+
organizationId: organization.id,
|
|
417
|
+
groupId: group.id,
|
|
418
|
+
memberId: member.id,
|
|
419
|
+
}),
|
|
420
|
+
],
|
|
421
|
+
deleteRegistrationIds: [],
|
|
422
|
+
}),
|
|
423
|
+
administrationFee: 0,
|
|
424
|
+
freeContribution: 0,
|
|
425
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
426
|
+
totalPrice: 30,
|
|
427
|
+
asOrganizationId: organization.id,
|
|
428
|
+
customer: null,
|
|
429
|
+
});
|
|
430
|
+
// #endregion
|
|
431
|
+
|
|
432
|
+
// #region act and assert
|
|
433
|
+
|
|
434
|
+
await expect(async () => await post(body, organization, token))
|
|
435
|
+
.rejects
|
|
436
|
+
.toThrow(new RegExp('Oeps! De prijs is gewijzigd terwijl je aan het afrekenen was'));
|
|
437
|
+
// #endregion
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
test('Should fail if member is already registered', async () => {
|
|
441
|
+
// #region arrange
|
|
442
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
443
|
+
|
|
444
|
+
const body = IDRegisterCheckout.create({
|
|
445
|
+
cart: IDRegisterCart.create({
|
|
446
|
+
items: [
|
|
447
|
+
IDRegisterItem.create({
|
|
448
|
+
id: uuidv4(),
|
|
449
|
+
replaceRegistrationIds: [],
|
|
450
|
+
options: [],
|
|
451
|
+
groupPrice,
|
|
452
|
+
organizationId: organization.id,
|
|
453
|
+
groupId: group.id,
|
|
454
|
+
memberId: member.id,
|
|
455
|
+
}),
|
|
456
|
+
],
|
|
457
|
+
balanceItems: [
|
|
458
|
+
],
|
|
459
|
+
deleteRegistrationIds: [],
|
|
460
|
+
}),
|
|
461
|
+
administrationFee: 0,
|
|
462
|
+
freeContribution: 0,
|
|
463
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
464
|
+
totalPrice: 25,
|
|
465
|
+
customer: null,
|
|
466
|
+
});
|
|
467
|
+
// #endregion
|
|
468
|
+
|
|
469
|
+
// #region act and assert
|
|
470
|
+
// register first time
|
|
471
|
+
await post(body, organization, token);
|
|
472
|
+
|
|
473
|
+
// second time should fail
|
|
474
|
+
await expect(async () => await post(body, organization, token))
|
|
475
|
+
.rejects
|
|
476
|
+
.toThrow(new RegExp('Already registered'));
|
|
477
|
+
// #endregion
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
test('Should fail if duplicate registration in cart', async () => {
|
|
481
|
+
// #region arrange
|
|
482
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
483
|
+
|
|
484
|
+
const body = IDRegisterCheckout.create({
|
|
485
|
+
cart: IDRegisterCart.create({
|
|
486
|
+
items: [
|
|
487
|
+
IDRegisterItem.create({
|
|
488
|
+
id: uuidv4(),
|
|
489
|
+
replaceRegistrationIds: [],
|
|
490
|
+
options: [],
|
|
491
|
+
groupPrice,
|
|
492
|
+
organizationId: organization.id,
|
|
493
|
+
groupId: group.id,
|
|
494
|
+
memberId: member.id,
|
|
495
|
+
}),
|
|
496
|
+
IDRegisterItem.create({
|
|
497
|
+
id: uuidv4(),
|
|
498
|
+
replaceRegistrationIds: [],
|
|
499
|
+
options: [],
|
|
500
|
+
groupPrice,
|
|
501
|
+
organizationId: organization.id,
|
|
502
|
+
groupId: group.id,
|
|
503
|
+
memberId: member.id,
|
|
504
|
+
}),
|
|
505
|
+
],
|
|
506
|
+
balanceItems: [
|
|
507
|
+
],
|
|
508
|
+
deleteRegistrationIds: [],
|
|
509
|
+
}),
|
|
510
|
+
administrationFee: 0,
|
|
511
|
+
freeContribution: 0,
|
|
512
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
513
|
+
totalPrice: 50,
|
|
514
|
+
customer: null,
|
|
515
|
+
});
|
|
516
|
+
// #endregion
|
|
517
|
+
|
|
518
|
+
// #region act and assert
|
|
519
|
+
await expect(async () => await post(body, organization, token))
|
|
520
|
+
.rejects
|
|
521
|
+
.toThrow(new RegExp('duplicate_register_item'));
|
|
522
|
+
// #endregion
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
test('Should fail register by other organization if disabled by group', async () => {
|
|
526
|
+
// #region arrange
|
|
527
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
528
|
+
|
|
529
|
+
const { organization: organization2 } = await initData();
|
|
530
|
+
|
|
531
|
+
user.permissions = UserPermissions.create({
|
|
532
|
+
organizationPermissions: new Map([
|
|
533
|
+
[organization2.id, Permissions.create({
|
|
534
|
+
level: PermissionLevel.Full,
|
|
535
|
+
})],
|
|
536
|
+
]),
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
await user.save();
|
|
540
|
+
|
|
541
|
+
const body = IDRegisterCheckout.create({
|
|
542
|
+
cart: IDRegisterCart.create({
|
|
543
|
+
items: [
|
|
544
|
+
IDRegisterItem.create({
|
|
545
|
+
id: uuidv4(),
|
|
546
|
+
replaceRegistrationIds: [],
|
|
547
|
+
options: [],
|
|
548
|
+
groupPrice,
|
|
549
|
+
organizationId: organization.id,
|
|
550
|
+
groupId: group.id,
|
|
551
|
+
memberId: member.id,
|
|
552
|
+
}),
|
|
553
|
+
],
|
|
554
|
+
balanceItems: [
|
|
555
|
+
],
|
|
556
|
+
deleteRegistrationIds: [],
|
|
557
|
+
}),
|
|
558
|
+
administrationFee: 0,
|
|
559
|
+
freeContribution: 0,
|
|
560
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
561
|
+
totalPrice: 25,
|
|
562
|
+
customer: null,
|
|
563
|
+
asOrganizationId: organization2.id,
|
|
564
|
+
});
|
|
565
|
+
// #endregion
|
|
566
|
+
|
|
567
|
+
// #region act and assert
|
|
568
|
+
await expect(async () => await post(body, organization, token))
|
|
569
|
+
.rejects
|
|
570
|
+
.toThrow(new RegExp('allowRegistrationsByOrganization disabled'));
|
|
571
|
+
// #endregion
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
test('Should fail if invalid payment', async () => {
|
|
575
|
+
// #region arrange
|
|
576
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
577
|
+
|
|
578
|
+
const body = IDRegisterCheckout.create({
|
|
579
|
+
cart: IDRegisterCart.create({
|
|
580
|
+
items: [
|
|
581
|
+
IDRegisterItem.create({
|
|
582
|
+
id: uuidv4(),
|
|
583
|
+
replaceRegistrationIds: [],
|
|
584
|
+
options: [],
|
|
585
|
+
groupPrice,
|
|
586
|
+
organizationId: organization.id,
|
|
587
|
+
groupId: group.id,
|
|
588
|
+
memberId: member.id,
|
|
589
|
+
}),
|
|
590
|
+
],
|
|
591
|
+
balanceItems: [
|
|
592
|
+
],
|
|
593
|
+
deleteRegistrationIds: [],
|
|
594
|
+
}),
|
|
595
|
+
administrationFee: 0,
|
|
596
|
+
freeContribution: 0,
|
|
597
|
+
paymentMethod: PaymentMethod.CreditCard,
|
|
598
|
+
totalPrice: 25,
|
|
599
|
+
customer: null,
|
|
600
|
+
});
|
|
601
|
+
// #endregion
|
|
602
|
+
|
|
603
|
+
// #region act and assert
|
|
604
|
+
await expect(async () => await post(body, organization, token))
|
|
605
|
+
.rejects
|
|
606
|
+
.toThrow(new RegExp('Oeps, je hebt geen geldige betaalmethode geselecteerd'));
|
|
607
|
+
// #endregion
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
test('Should fail if no redirect url for online payment', async () => {
|
|
611
|
+
// #region arrange
|
|
612
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
613
|
+
organization.meta.registrationPaymentConfiguration.paymentMethods.push(PaymentMethod.Bancontact);
|
|
614
|
+
await organization.save();
|
|
615
|
+
|
|
616
|
+
const body = IDRegisterCheckout.create({
|
|
617
|
+
cart: IDRegisterCart.create({
|
|
618
|
+
items: [
|
|
619
|
+
IDRegisterItem.create({
|
|
620
|
+
id: uuidv4(),
|
|
621
|
+
replaceRegistrationIds: [],
|
|
622
|
+
options: [],
|
|
623
|
+
groupPrice,
|
|
624
|
+
organizationId: organization.id,
|
|
625
|
+
groupId: group.id,
|
|
626
|
+
memberId: member.id,
|
|
627
|
+
}),
|
|
628
|
+
],
|
|
629
|
+
balanceItems: [
|
|
630
|
+
],
|
|
631
|
+
deleteRegistrationIds: [],
|
|
632
|
+
}),
|
|
633
|
+
administrationFee: 0,
|
|
634
|
+
freeContribution: 0,
|
|
635
|
+
paymentMethod: PaymentMethod.Bancontact,
|
|
636
|
+
totalPrice: 25,
|
|
637
|
+
cancelUrl: new URL('https://www.stamhoofd.be'),
|
|
638
|
+
customer: null,
|
|
639
|
+
});
|
|
640
|
+
// #endregion
|
|
641
|
+
|
|
642
|
+
// #region act and assert
|
|
643
|
+
await expect(async () => await post(body, organization, token))
|
|
644
|
+
.rejects
|
|
645
|
+
.toThrow(new RegExp('redirectUrl or cancelUrl is missing'));
|
|
646
|
+
// #endregion
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
test('Should fail if no cancel url for online payment', async () => {
|
|
650
|
+
// #region arrange
|
|
651
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
652
|
+
organization.meta.registrationPaymentConfiguration.paymentMethods.push(PaymentMethod.Bancontact);
|
|
653
|
+
await organization.save();
|
|
654
|
+
|
|
655
|
+
const body = IDRegisterCheckout.create({
|
|
656
|
+
cart: IDRegisterCart.create({
|
|
657
|
+
items: [
|
|
658
|
+
IDRegisterItem.create({
|
|
659
|
+
id: uuidv4(),
|
|
660
|
+
replaceRegistrationIds: [],
|
|
661
|
+
options: [],
|
|
662
|
+
groupPrice,
|
|
663
|
+
organizationId: organization.id,
|
|
664
|
+
groupId: group.id,
|
|
665
|
+
memberId: member.id,
|
|
666
|
+
}),
|
|
667
|
+
],
|
|
668
|
+
balanceItems: [
|
|
669
|
+
],
|
|
670
|
+
deleteRegistrationIds: [],
|
|
671
|
+
}),
|
|
672
|
+
administrationFee: 0,
|
|
673
|
+
freeContribution: 0,
|
|
674
|
+
paymentMethod: PaymentMethod.Bancontact,
|
|
675
|
+
totalPrice: 25,
|
|
676
|
+
redirectUrl: new URL('https://www.stamhoofd.be'),
|
|
677
|
+
customer: null,
|
|
678
|
+
});
|
|
679
|
+
// #endregion
|
|
680
|
+
|
|
681
|
+
// #region act and assert
|
|
682
|
+
await expect(async () => await post(body, organization, token))
|
|
683
|
+
.rejects
|
|
684
|
+
.toThrow(new RegExp('redirectUrl or cancelUrl is missing'));
|
|
685
|
+
// #endregion
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
test('Should reserve if group has max members', async () => {
|
|
689
|
+
// #region arrange
|
|
690
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
691
|
+
group.settings.maxMembers = 5;
|
|
692
|
+
await group.save();
|
|
693
|
+
|
|
694
|
+
const body = IDRegisterCheckout.create({
|
|
695
|
+
cart: IDRegisterCart.create({
|
|
696
|
+
items: [
|
|
697
|
+
IDRegisterItem.create({
|
|
698
|
+
id: uuidv4(),
|
|
699
|
+
replaceRegistrationIds: [],
|
|
700
|
+
options: [],
|
|
701
|
+
groupPrice,
|
|
702
|
+
organizationId: organization.id,
|
|
703
|
+
groupId: group.id,
|
|
704
|
+
memberId: member.id,
|
|
705
|
+
}),
|
|
706
|
+
],
|
|
707
|
+
balanceItems: [
|
|
708
|
+
],
|
|
709
|
+
deleteRegistrationIds: [],
|
|
710
|
+
}),
|
|
711
|
+
administrationFee: 0,
|
|
712
|
+
freeContribution: 0,
|
|
713
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
714
|
+
totalPrice: 25,
|
|
715
|
+
});
|
|
716
|
+
// #endregion
|
|
717
|
+
|
|
718
|
+
// #region act and assert
|
|
719
|
+
const response = await post(body, organization, token);
|
|
720
|
+
expect(response.body.registrations.length).toBe(1);
|
|
721
|
+
expect(response.body.registrations[0].reservedUntil).not.toBeNull();
|
|
722
|
+
// #endregion
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
test('Should reuse existing registration', async () => {
|
|
726
|
+
// #region arrange
|
|
727
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
728
|
+
group.settings.allowRegistrationsByOrganization = true;
|
|
729
|
+
await group.save();
|
|
730
|
+
|
|
731
|
+
user.permissions = UserPermissions.create({
|
|
732
|
+
organizationPermissions: new Map([
|
|
733
|
+
[organization.id, Permissions.create({
|
|
734
|
+
level: PermissionLevel.Full,
|
|
735
|
+
})],
|
|
736
|
+
]),
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
await user.save();
|
|
740
|
+
|
|
741
|
+
const group2 = await new GroupFactory({
|
|
742
|
+
organization,
|
|
743
|
+
price: 25,
|
|
744
|
+
stock: 5,
|
|
745
|
+
}).create();
|
|
746
|
+
|
|
747
|
+
const firstRegistration = await new RegistrationFactory({
|
|
748
|
+
member,
|
|
749
|
+
group: group2,
|
|
750
|
+
groupPrice: group2.settings.prices[0],
|
|
751
|
+
}).create();
|
|
752
|
+
|
|
753
|
+
const body = IDRegisterCheckout.create({
|
|
754
|
+
cart: IDRegisterCart.create({
|
|
755
|
+
items: [
|
|
756
|
+
IDRegisterItem.create({
|
|
757
|
+
id: uuidv4(),
|
|
758
|
+
replaceRegistrationIds: [firstRegistration.id],
|
|
759
|
+
options: [],
|
|
760
|
+
groupPrice,
|
|
761
|
+
organizationId: organization.id,
|
|
762
|
+
groupId: group.id,
|
|
763
|
+
memberId: member.id,
|
|
764
|
+
}),
|
|
765
|
+
],
|
|
766
|
+
balanceItems: [
|
|
767
|
+
],
|
|
768
|
+
deleteRegistrationIds: [],
|
|
769
|
+
}),
|
|
770
|
+
administrationFee: 0,
|
|
771
|
+
freeContribution: 0,
|
|
772
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
773
|
+
totalPrice: 0,
|
|
774
|
+
asOrganizationId: organization.id,
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
// #endregion
|
|
778
|
+
|
|
779
|
+
// #region act and assert
|
|
780
|
+
const response = await post(body, organization, token);
|
|
781
|
+
expect(response.body.registrations.length).toBe(1);
|
|
782
|
+
expect(response.body.registrations[0].id).toEqual(firstRegistration.id);
|
|
783
|
+
// #endregion
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
test('Should reuse recently deactivated registration', async () => {
|
|
787
|
+
// #region arrange
|
|
788
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
789
|
+
group.settings.allowRegistrationsByOrganization = true;
|
|
790
|
+
await group.save();
|
|
791
|
+
|
|
792
|
+
user.permissions = UserPermissions.create({
|
|
793
|
+
organizationPermissions: new Map([
|
|
794
|
+
[organization.id, Permissions.create({
|
|
795
|
+
level: PermissionLevel.Full,
|
|
796
|
+
})],
|
|
797
|
+
]),
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
await user.save();
|
|
801
|
+
|
|
802
|
+
const firstRegistration = await new RegistrationFactory({
|
|
803
|
+
member,
|
|
804
|
+
group,
|
|
805
|
+
groupPrice,
|
|
806
|
+
}).create();
|
|
807
|
+
|
|
808
|
+
firstRegistration.deactivatedAt = new Date();
|
|
809
|
+
await firstRegistration.save();
|
|
810
|
+
|
|
811
|
+
const body = IDRegisterCheckout.create({
|
|
812
|
+
cart: IDRegisterCart.create({
|
|
813
|
+
items: [
|
|
814
|
+
IDRegisterItem.create({
|
|
815
|
+
id: uuidv4(),
|
|
816
|
+
replaceRegistrationIds: [],
|
|
817
|
+
options: [],
|
|
818
|
+
groupPrice,
|
|
819
|
+
organizationId: organization.id,
|
|
820
|
+
groupId: group.id,
|
|
821
|
+
memberId: member.id,
|
|
822
|
+
}),
|
|
823
|
+
],
|
|
824
|
+
balanceItems: [
|
|
825
|
+
],
|
|
826
|
+
deleteRegistrationIds: [],
|
|
827
|
+
}),
|
|
828
|
+
administrationFee: 0,
|
|
829
|
+
freeContribution: 0,
|
|
830
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
831
|
+
totalPrice: 25,
|
|
832
|
+
asOrganizationId: organization.id,
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
// #endregion
|
|
836
|
+
|
|
837
|
+
// #region act and assert
|
|
838
|
+
const response = await post(body, organization, token);
|
|
839
|
+
expect(response.body.registrations.length).toBe(1);
|
|
840
|
+
expect(response.body.registrations[0].id).toEqual(firstRegistration.id);
|
|
841
|
+
// #endregion
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
test('Should update registered members', async () => {
|
|
845
|
+
// #region arrange
|
|
846
|
+
const { member, group, groupPrice, organization, token } = await initData();
|
|
847
|
+
|
|
848
|
+
const body = IDRegisterCheckout.create({
|
|
849
|
+
cart: IDRegisterCart.create({
|
|
850
|
+
items: [
|
|
851
|
+
IDRegisterItem.create({
|
|
852
|
+
id: uuidv4(),
|
|
853
|
+
replaceRegistrationIds: [],
|
|
854
|
+
options: [],
|
|
855
|
+
groupPrice,
|
|
856
|
+
organizationId: organization.id,
|
|
857
|
+
groupId: group.id,
|
|
858
|
+
memberId: member.id,
|
|
859
|
+
}),
|
|
860
|
+
],
|
|
861
|
+
balanceItems: [],
|
|
862
|
+
deleteRegistrationIds: [],
|
|
863
|
+
}),
|
|
864
|
+
administrationFee: 0,
|
|
865
|
+
freeContribution: 0,
|
|
866
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
867
|
+
totalPrice: 25,
|
|
868
|
+
asOrganizationId: organization.id,
|
|
869
|
+
customer: null,
|
|
870
|
+
});
|
|
871
|
+
// #endregion
|
|
872
|
+
|
|
873
|
+
// act
|
|
874
|
+
const response = await post(body, organization, token);
|
|
875
|
+
|
|
876
|
+
// assert
|
|
877
|
+
expect(response.body).toBeDefined();
|
|
878
|
+
expect(response.body.registrations.length).toBe(1);
|
|
879
|
+
|
|
880
|
+
const updatedGroup = await Group.getByID(group.id);
|
|
881
|
+
expect(updatedGroup!.settings.registeredMembers).toBe(1);
|
|
882
|
+
expect(updatedGroup!.settings.reservedMembers).toBe(0);
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
test('Should update reserved members', async () => {
|
|
886
|
+
// #region arrange
|
|
887
|
+
const { member, organization, token } = await initData();
|
|
888
|
+
|
|
889
|
+
organization.meta.registrationPaymentConfiguration.paymentMethods = [PaymentMethod.PointOfSale, PaymentMethod.Payconiq];
|
|
890
|
+
|
|
891
|
+
organization.privateMeta.payconiqAccounts = [PayconiqAccount.create({
|
|
892
|
+
id: uuidv4(),
|
|
893
|
+
apiKey: 'testKey',
|
|
894
|
+
merchantId: 'test',
|
|
895
|
+
profileId: 'test',
|
|
896
|
+
name: 'test',
|
|
897
|
+
iban: 'BE56587127952688', // = random IBAN
|
|
898
|
+
callbackUrl: 'https://www.example.com',
|
|
899
|
+
})];
|
|
900
|
+
|
|
901
|
+
await organization.save();
|
|
902
|
+
|
|
903
|
+
const group2 = await new GroupFactory({
|
|
904
|
+
organization,
|
|
905
|
+
price: 15,
|
|
906
|
+
stock: 4,
|
|
907
|
+
maxMembers: 1,
|
|
908
|
+
}).create();
|
|
909
|
+
|
|
910
|
+
const groupPrice2 = group2.settings.prices[0];
|
|
911
|
+
|
|
912
|
+
const body = IDRegisterCheckout.create({
|
|
913
|
+
cart: IDRegisterCart.create({
|
|
914
|
+
items: [
|
|
915
|
+
IDRegisterItem.create({
|
|
916
|
+
id: uuidv4(),
|
|
917
|
+
replaceRegistrationIds: [],
|
|
918
|
+
options: [],
|
|
919
|
+
groupPrice: groupPrice2,
|
|
920
|
+
organizationId: organization.id,
|
|
921
|
+
groupId: group2.id,
|
|
922
|
+
memberId: member.id,
|
|
923
|
+
}),
|
|
924
|
+
],
|
|
925
|
+
balanceItems: [],
|
|
926
|
+
deleteRegistrationIds: [],
|
|
927
|
+
}),
|
|
928
|
+
administrationFee: 0,
|
|
929
|
+
freeContribution: 0,
|
|
930
|
+
paymentMethod: PaymentMethod.Payconiq,
|
|
931
|
+
redirectUrl: new URL('https://www.example.com'),
|
|
932
|
+
cancelUrl: new URL('https://www.example.com'),
|
|
933
|
+
totalPrice: 15,
|
|
934
|
+
customer: null,
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
nock('https://api.ext.payconiq.com')
|
|
938
|
+
.post('/v3/payments')
|
|
939
|
+
.reply(200, {
|
|
940
|
+
paymentId: 'testPaymentId',
|
|
941
|
+
_links: {
|
|
942
|
+
checkout: {
|
|
943
|
+
href: 'https://www.example.com',
|
|
944
|
+
},
|
|
945
|
+
},
|
|
946
|
+
});
|
|
947
|
+
// #endregion
|
|
948
|
+
|
|
949
|
+
// act
|
|
950
|
+
const response = await post(body, organization, token);
|
|
951
|
+
|
|
952
|
+
// assert
|
|
953
|
+
expect(response.body).toBeDefined();
|
|
954
|
+
expect(response.body.registrations.length).toBe(1);
|
|
955
|
+
|
|
956
|
+
const updatedGroup = await Group.getByID(group2.id);
|
|
957
|
+
expect(updatedGroup!.settings.registeredMembers).toBe(0);
|
|
958
|
+
expect(updatedGroup!.settings.reservedMembers).toBe(1);
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
test('Register for group with trial should set trail period', async () => {
|
|
962
|
+
// #region arrange
|
|
963
|
+
const date = new Date('2023-05-14');
|
|
964
|
+
jest.useFakeTimers().setSystemTime(date);
|
|
965
|
+
|
|
966
|
+
try {
|
|
967
|
+
const { member, group, groupPrice, organization, token } = await initData();
|
|
968
|
+
group.settings.trialDays = 5;
|
|
969
|
+
await group.save();
|
|
970
|
+
|
|
971
|
+
const body = IDRegisterCheckout.create({
|
|
972
|
+
cart: IDRegisterCart.create({
|
|
973
|
+
items: [
|
|
974
|
+
IDRegisterItem.create({
|
|
975
|
+
id: uuidv4(),
|
|
976
|
+
replaceRegistrationIds: [],
|
|
977
|
+
options: [],
|
|
978
|
+
groupPrice: groupPrice,
|
|
979
|
+
organizationId: organization.id,
|
|
980
|
+
groupId: group.id,
|
|
981
|
+
memberId: member.id,
|
|
982
|
+
trial: true,
|
|
983
|
+
}),
|
|
984
|
+
],
|
|
985
|
+
balanceItems: [],
|
|
986
|
+
deleteRegistrationIds: [],
|
|
987
|
+
}),
|
|
988
|
+
administrationFee: 0,
|
|
989
|
+
freeContribution: 0,
|
|
990
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
991
|
+
totalPrice: 0,
|
|
992
|
+
asOrganizationId: organization.id,
|
|
993
|
+
customer: null,
|
|
994
|
+
});
|
|
995
|
+
// #endregion
|
|
996
|
+
|
|
997
|
+
// act
|
|
998
|
+
const response = await post(body, organization, token);
|
|
999
|
+
|
|
1000
|
+
// assert
|
|
1001
|
+
expect(response.body).toBeDefined();
|
|
1002
|
+
expect(response.body.registrations.length).toBe(1);
|
|
1003
|
+
const trialUntil = response.body.registrations[0].trialUntil;
|
|
1004
|
+
expect(trialUntil).not.toBeNull();
|
|
1005
|
+
// 2023-05-14
|
|
1006
|
+
expect(trialUntil!.getFullYear()).toBe(2023);
|
|
1007
|
+
expect(trialUntil!.getMonth()).toBe(4);
|
|
1008
|
+
expect(trialUntil!.getDate()).toBe(19);
|
|
1009
|
+
}
|
|
1010
|
+
finally {
|
|
1011
|
+
jest.useFakeTimers().resetAllMocks();
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
|
|
1015
|
+
test('Should update group stock reservations', async () => {
|
|
1016
|
+
// #region arrange
|
|
1017
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
1018
|
+
groupPrice.stock = 5;
|
|
1019
|
+
await group.save();
|
|
1020
|
+
|
|
1021
|
+
const body = IDRegisterCheckout.create({
|
|
1022
|
+
cart: IDRegisterCart.create({
|
|
1023
|
+
items: [
|
|
1024
|
+
IDRegisterItem.create({
|
|
1025
|
+
id: uuidv4(),
|
|
1026
|
+
replaceRegistrationIds: [],
|
|
1027
|
+
options: [],
|
|
1028
|
+
groupPrice,
|
|
1029
|
+
organizationId: organization.id,
|
|
1030
|
+
groupId: group.id,
|
|
1031
|
+
memberId: member.id,
|
|
1032
|
+
}),
|
|
1033
|
+
],
|
|
1034
|
+
balanceItems: [],
|
|
1035
|
+
deleteRegistrationIds: [],
|
|
1036
|
+
}),
|
|
1037
|
+
administrationFee: 0,
|
|
1038
|
+
freeContribution: 0,
|
|
1039
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1040
|
+
totalPrice: 25,
|
|
1041
|
+
asOrganizationId: organization.id,
|
|
1042
|
+
customer: null,
|
|
1043
|
+
});
|
|
1044
|
+
// #endregion
|
|
1045
|
+
|
|
1046
|
+
// #region act and assert
|
|
1047
|
+
expect(group?.stockReservations.length).toBe(0);
|
|
1048
|
+
|
|
1049
|
+
await post(body, organization, token);
|
|
1050
|
+
|
|
1051
|
+
const updatedGroup = await Group.getByID(group.id);
|
|
1052
|
+
expect(updatedGroup?.stockReservations.length).toBe(1);
|
|
1053
|
+
// #endregion
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
test('Should fail if group price stock sold out', async () => {
|
|
1057
|
+
// #region arrange
|
|
1058
|
+
const { organization, group, groupPrice, token, member, otherMembers } = await initData({
|
|
1059
|
+
permissionLevel: PermissionLevel.Read, otherMemberAmount: 3 });
|
|
1060
|
+
groupPrice.stock = 2;
|
|
1061
|
+
await group.save();
|
|
1062
|
+
|
|
1063
|
+
const body = IDRegisterCheckout.create({
|
|
1064
|
+
cart: IDRegisterCart.create({
|
|
1065
|
+
items: [
|
|
1066
|
+
IDRegisterItem.create({
|
|
1067
|
+
id: uuidv4(),
|
|
1068
|
+
replaceRegistrationIds: [],
|
|
1069
|
+
options: [],
|
|
1070
|
+
groupPrice,
|
|
1071
|
+
organizationId: organization.id,
|
|
1072
|
+
groupId: group.id,
|
|
1073
|
+
memberId: member.id,
|
|
1074
|
+
}),
|
|
1075
|
+
...otherMembers.map(m => IDRegisterItem.create({
|
|
1076
|
+
id: uuidv4(),
|
|
1077
|
+
replaceRegistrationIds: [],
|
|
1078
|
+
options: [],
|
|
1079
|
+
groupPrice,
|
|
1080
|
+
organizationId: organization.id,
|
|
1081
|
+
groupId: group.id,
|
|
1082
|
+
memberId: m.id,
|
|
1083
|
+
})),
|
|
1084
|
+
],
|
|
1085
|
+
balanceItems: [],
|
|
1086
|
+
deleteRegistrationIds: [],
|
|
1087
|
+
}),
|
|
1088
|
+
administrationFee: 0,
|
|
1089
|
+
freeContribution: 0,
|
|
1090
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1091
|
+
totalPrice: 75,
|
|
1092
|
+
customer: null,
|
|
1093
|
+
});
|
|
1094
|
+
// #endregion
|
|
1095
|
+
|
|
1096
|
+
// #region act and assert
|
|
1097
|
+
expect(group?.stockReservations.length).toBe(0);
|
|
1098
|
+
|
|
1099
|
+
await expect(async () => await post(body, organization, token))
|
|
1100
|
+
.rejects
|
|
1101
|
+
.toThrow(new RegExp('Maximum reached'));
|
|
1102
|
+
// #endregion
|
|
1103
|
+
});
|
|
1104
|
+
|
|
1105
|
+
test('Should fail if option stock sold out', async () => {
|
|
1106
|
+
// #region arrange
|
|
1107
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
1108
|
+
|
|
1109
|
+
const option1 = GroupOption.create({
|
|
1110
|
+
name: 'option 1',
|
|
1111
|
+
stock: 4,
|
|
1112
|
+
price: ReduceablePrice.create({
|
|
1113
|
+
price: 5,
|
|
1114
|
+
reducedPrice: 3,
|
|
1115
|
+
}),
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
const option2 = GroupOption.create({
|
|
1119
|
+
name: 'option 2',
|
|
1120
|
+
stock: 4,
|
|
1121
|
+
price: ReduceablePrice.create({
|
|
1122
|
+
price: 3,
|
|
1123
|
+
reducedPrice: 1,
|
|
1124
|
+
}),
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
const optionMenu = GroupOptionMenu.create({
|
|
1128
|
+
name: 'option menu 1',
|
|
1129
|
+
multipleChoice: true,
|
|
1130
|
+
options: [option1, option2],
|
|
1131
|
+
});
|
|
1132
|
+
|
|
1133
|
+
group.settings.optionMenus = [
|
|
1134
|
+
optionMenu,
|
|
1135
|
+
];
|
|
1136
|
+
|
|
1137
|
+
await group.save();
|
|
1138
|
+
|
|
1139
|
+
const body = IDRegisterCheckout.create({
|
|
1140
|
+
cart: IDRegisterCart.create({
|
|
1141
|
+
items: [
|
|
1142
|
+
IDRegisterItem.create({
|
|
1143
|
+
id: uuidv4(),
|
|
1144
|
+
replaceRegistrationIds: [],
|
|
1145
|
+
options: [
|
|
1146
|
+
RegisterItemOption.create({
|
|
1147
|
+
option: option1,
|
|
1148
|
+
amount: 2,
|
|
1149
|
+
optionMenu,
|
|
1150
|
+
}),
|
|
1151
|
+
RegisterItemOption.create({
|
|
1152
|
+
option: option2,
|
|
1153
|
+
amount: 5,
|
|
1154
|
+
optionMenu,
|
|
1155
|
+
}),
|
|
1156
|
+
],
|
|
1157
|
+
groupPrice,
|
|
1158
|
+
organizationId: organization.id,
|
|
1159
|
+
groupId: group.id,
|
|
1160
|
+
memberId: member.id,
|
|
1161
|
+
}),
|
|
1162
|
+
],
|
|
1163
|
+
balanceItems: [
|
|
1164
|
+
],
|
|
1165
|
+
deleteRegistrationIds: [],
|
|
1166
|
+
}),
|
|
1167
|
+
administrationFee: 0,
|
|
1168
|
+
freeContribution: 0,
|
|
1169
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1170
|
+
totalPrice: 50,
|
|
1171
|
+
customer: null,
|
|
1172
|
+
});
|
|
1173
|
+
// #endregion
|
|
1174
|
+
|
|
1175
|
+
// #region act and assert
|
|
1176
|
+
await expect(async () => await post(body, organization, token))
|
|
1177
|
+
.rejects
|
|
1178
|
+
.toThrow(new RegExp('Stock empty'));
|
|
1179
|
+
// #endregion
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
test('Should fail if max option exceeded', async () => {
|
|
1183
|
+
// #region arrange
|
|
1184
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
1185
|
+
|
|
1186
|
+
const option1 = GroupOption.create({
|
|
1187
|
+
name: 'option 1',
|
|
1188
|
+
stock: 4,
|
|
1189
|
+
maximum: 5,
|
|
1190
|
+
allowAmount: true,
|
|
1191
|
+
price: ReduceablePrice.create({
|
|
1192
|
+
price: 5,
|
|
1193
|
+
reducedPrice: 3,
|
|
1194
|
+
}),
|
|
1195
|
+
});
|
|
1196
|
+
|
|
1197
|
+
const option2 = GroupOption.create({
|
|
1198
|
+
name: 'option 2',
|
|
1199
|
+
stock: 5,
|
|
1200
|
+
maximum: 2,
|
|
1201
|
+
allowAmount: true,
|
|
1202
|
+
price: ReduceablePrice.create({
|
|
1203
|
+
price: 3,
|
|
1204
|
+
reducedPrice: 1,
|
|
1205
|
+
}),
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
const optionMenu = GroupOptionMenu.create({
|
|
1209
|
+
name: 'option menu 1',
|
|
1210
|
+
multipleChoice: true,
|
|
1211
|
+
options: [option1, option2],
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
group.settings.optionMenus = [
|
|
1215
|
+
optionMenu,
|
|
1216
|
+
];
|
|
1217
|
+
|
|
1218
|
+
await group.save();
|
|
1219
|
+
|
|
1220
|
+
const body = IDRegisterCheckout.create({
|
|
1221
|
+
cart: IDRegisterCart.create({
|
|
1222
|
+
items: [
|
|
1223
|
+
IDRegisterItem.create({
|
|
1224
|
+
id: uuidv4(),
|
|
1225
|
+
replaceRegistrationIds: [],
|
|
1226
|
+
options: [
|
|
1227
|
+
RegisterItemOption.create({
|
|
1228
|
+
option: option1,
|
|
1229
|
+
amount: 2,
|
|
1230
|
+
optionMenu,
|
|
1231
|
+
}),
|
|
1232
|
+
RegisterItemOption.create({
|
|
1233
|
+
option: option2,
|
|
1234
|
+
amount: 5,
|
|
1235
|
+
optionMenu,
|
|
1236
|
+
}),
|
|
1237
|
+
],
|
|
1238
|
+
groupPrice,
|
|
1239
|
+
organizationId: organization.id,
|
|
1240
|
+
groupId: group.id,
|
|
1241
|
+
memberId: member.id,
|
|
1242
|
+
}),
|
|
1243
|
+
],
|
|
1244
|
+
balanceItems: [
|
|
1245
|
+
],
|
|
1246
|
+
deleteRegistrationIds: [],
|
|
1247
|
+
}),
|
|
1248
|
+
administrationFee: 0,
|
|
1249
|
+
freeContribution: 0,
|
|
1250
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1251
|
+
totalPrice: 50,
|
|
1252
|
+
customer: null,
|
|
1253
|
+
});
|
|
1254
|
+
// #endregion
|
|
1255
|
+
|
|
1256
|
+
// #region act and assert
|
|
1257
|
+
await expect(async () => await post(body, organization, token))
|
|
1258
|
+
.rejects
|
|
1259
|
+
.toThrow(new RegExp('Option maximum exceeded'));
|
|
1260
|
+
// #endregion
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1263
|
+
test('Should not fail if max option not exceeded', async () => {
|
|
1264
|
+
// #region arrange
|
|
1265
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
1266
|
+
|
|
1267
|
+
const option1 = GroupOption.create({
|
|
1268
|
+
name: 'option 1',
|
|
1269
|
+
stock: 4,
|
|
1270
|
+
maximum: 5,
|
|
1271
|
+
allowAmount: true,
|
|
1272
|
+
price: ReduceablePrice.create({
|
|
1273
|
+
price: 5,
|
|
1274
|
+
reducedPrice: 3,
|
|
1275
|
+
}),
|
|
1276
|
+
});
|
|
1277
|
+
|
|
1278
|
+
const option2 = GroupOption.create({
|
|
1279
|
+
name: 'option 2',
|
|
1280
|
+
stock: 5,
|
|
1281
|
+
maximum: 5,
|
|
1282
|
+
allowAmount: true,
|
|
1283
|
+
price: ReduceablePrice.create({
|
|
1284
|
+
price: 3,
|
|
1285
|
+
reducedPrice: 1,
|
|
1286
|
+
}),
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
const optionMenu = GroupOptionMenu.create({
|
|
1290
|
+
name: 'option menu 1',
|
|
1291
|
+
multipleChoice: true,
|
|
1292
|
+
options: [option1, option2],
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1295
|
+
group.settings.optionMenus = [
|
|
1296
|
+
optionMenu,
|
|
1297
|
+
];
|
|
1298
|
+
|
|
1299
|
+
await group.save();
|
|
1300
|
+
|
|
1301
|
+
const body = IDRegisterCheckout.create({
|
|
1302
|
+
cart: IDRegisterCart.create({
|
|
1303
|
+
items: [
|
|
1304
|
+
IDRegisterItem.create({
|
|
1305
|
+
id: uuidv4(),
|
|
1306
|
+
replaceRegistrationIds: [],
|
|
1307
|
+
options: [
|
|
1308
|
+
RegisterItemOption.create({
|
|
1309
|
+
option: option1,
|
|
1310
|
+
amount: 2,
|
|
1311
|
+
optionMenu,
|
|
1312
|
+
}),
|
|
1313
|
+
RegisterItemOption.create({
|
|
1314
|
+
option: option2,
|
|
1315
|
+
amount: 5,
|
|
1316
|
+
optionMenu,
|
|
1317
|
+
}),
|
|
1318
|
+
],
|
|
1319
|
+
groupPrice,
|
|
1320
|
+
organizationId: organization.id,
|
|
1321
|
+
groupId: group.id,
|
|
1322
|
+
memberId: member.id,
|
|
1323
|
+
}),
|
|
1324
|
+
],
|
|
1325
|
+
balanceItems: [
|
|
1326
|
+
],
|
|
1327
|
+
deleteRegistrationIds: [],
|
|
1328
|
+
}),
|
|
1329
|
+
administrationFee: 0,
|
|
1330
|
+
freeContribution: 0,
|
|
1331
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1332
|
+
totalPrice: 50,
|
|
1333
|
+
customer: null,
|
|
1334
|
+
});
|
|
1335
|
+
// #endregion
|
|
1336
|
+
|
|
1337
|
+
// #region act and assert
|
|
1338
|
+
const result = await post(body, organization, token);
|
|
1339
|
+
expect(result).toBeDefined();
|
|
1340
|
+
// #endregion
|
|
1341
|
+
});
|
|
1342
|
+
});
|
|
1343
|
+
|
|
1344
|
+
describe('Register by other organization', () => {
|
|
1345
|
+
test('Should fail if disabled by group', async () => {
|
|
1346
|
+
// #region arrange
|
|
1347
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
1348
|
+
|
|
1349
|
+
const { organization: organization2 } = await initData();
|
|
1350
|
+
|
|
1351
|
+
user.permissions = UserPermissions.create({
|
|
1352
|
+
organizationPermissions: new Map([
|
|
1353
|
+
[organization2.id, Permissions.create({
|
|
1354
|
+
level: PermissionLevel.Full,
|
|
1355
|
+
})],
|
|
1356
|
+
]),
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
await user.save();
|
|
1360
|
+
|
|
1361
|
+
const body = IDRegisterCheckout.create({
|
|
1362
|
+
cart: IDRegisterCart.create({
|
|
1363
|
+
items: [
|
|
1364
|
+
IDRegisterItem.create({
|
|
1365
|
+
id: uuidv4(),
|
|
1366
|
+
replaceRegistrationIds: [],
|
|
1367
|
+
options: [],
|
|
1368
|
+
groupPrice,
|
|
1369
|
+
organizationId: organization.id,
|
|
1370
|
+
groupId: group.id,
|
|
1371
|
+
memberId: member.id,
|
|
1372
|
+
}),
|
|
1373
|
+
],
|
|
1374
|
+
balanceItems: [
|
|
1375
|
+
],
|
|
1376
|
+
deleteRegistrationIds: [],
|
|
1377
|
+
}),
|
|
1378
|
+
administrationFee: 0,
|
|
1379
|
+
freeContribution: 0,
|
|
1380
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1381
|
+
totalPrice: 25,
|
|
1382
|
+
customer: null,
|
|
1383
|
+
asOrganizationId: organization2.id,
|
|
1384
|
+
});
|
|
1385
|
+
// #endregion
|
|
1386
|
+
|
|
1387
|
+
// #region act and assert
|
|
1388
|
+
await expect(async () => await post(body, organization, token))
|
|
1389
|
+
.rejects
|
|
1390
|
+
.toThrow(new RegExp('allowRegistrationsByOrganization disabled'));
|
|
1391
|
+
// #endregion
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
test('Should fail if no customer', async () => {
|
|
1395
|
+
// #region arrange
|
|
1396
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
1397
|
+
group.settings.allowRegistrationsByOrganization = true;
|
|
1398
|
+
await group.save();
|
|
1399
|
+
|
|
1400
|
+
const { organization: organization2 } = await initData();
|
|
1401
|
+
|
|
1402
|
+
user.permissions = UserPermissions.create({
|
|
1403
|
+
organizationPermissions: new Map([
|
|
1404
|
+
[organization2.id, Permissions.create({
|
|
1405
|
+
level: PermissionLevel.Full,
|
|
1406
|
+
})],
|
|
1407
|
+
]),
|
|
1408
|
+
});
|
|
1409
|
+
|
|
1410
|
+
await user.save();
|
|
1411
|
+
|
|
1412
|
+
const body = IDRegisterCheckout.create({
|
|
1413
|
+
cart: IDRegisterCart.create({
|
|
1414
|
+
items: [
|
|
1415
|
+
IDRegisterItem.create({
|
|
1416
|
+
id: uuidv4(),
|
|
1417
|
+
replaceRegistrationIds: [],
|
|
1418
|
+
options: [],
|
|
1419
|
+
groupPrice,
|
|
1420
|
+
organizationId: organization.id,
|
|
1421
|
+
groupId: group.id,
|
|
1422
|
+
memberId: member.id,
|
|
1423
|
+
}),
|
|
1424
|
+
],
|
|
1425
|
+
balanceItems: [
|
|
1426
|
+
],
|
|
1427
|
+
deleteRegistrationIds: [],
|
|
1428
|
+
}),
|
|
1429
|
+
administrationFee: 0,
|
|
1430
|
+
freeContribution: 0,
|
|
1431
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1432
|
+
totalPrice: 25,
|
|
1433
|
+
customer: null,
|
|
1434
|
+
asOrganizationId: organization2.id,
|
|
1435
|
+
});
|
|
1436
|
+
// #endregion
|
|
1437
|
+
|
|
1438
|
+
// #region act and assert
|
|
1439
|
+
await expect(async () => await post(body, organization, token))
|
|
1440
|
+
.rejects
|
|
1441
|
+
.toThrow(new RegExp('customer is required when paying as an organization'));
|
|
1442
|
+
// #endregion
|
|
1443
|
+
});
|
|
1444
|
+
|
|
1445
|
+
test('Should fail if no company on customer', async () => {
|
|
1446
|
+
// #region arrange
|
|
1447
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
1448
|
+
group.settings.allowRegistrationsByOrganization = true;
|
|
1449
|
+
await group.save();
|
|
1450
|
+
|
|
1451
|
+
const { organization: organization2 } = await initData();
|
|
1452
|
+
|
|
1453
|
+
user.permissions = UserPermissions.create({
|
|
1454
|
+
organizationPermissions: new Map([
|
|
1455
|
+
[organization2.id, Permissions.create({
|
|
1456
|
+
level: PermissionLevel.Full,
|
|
1457
|
+
})],
|
|
1458
|
+
]),
|
|
1459
|
+
});
|
|
1460
|
+
|
|
1461
|
+
await user.save();
|
|
1462
|
+
|
|
1463
|
+
const body = IDRegisterCheckout.create({
|
|
1464
|
+
cart: IDRegisterCart.create({
|
|
1465
|
+
items: [
|
|
1466
|
+
IDRegisterItem.create({
|
|
1467
|
+
id: uuidv4(),
|
|
1468
|
+
replaceRegistrationIds: [],
|
|
1469
|
+
options: [],
|
|
1470
|
+
groupPrice,
|
|
1471
|
+
organizationId: organization.id,
|
|
1472
|
+
groupId: group.id,
|
|
1473
|
+
memberId: member.id,
|
|
1474
|
+
}),
|
|
1475
|
+
],
|
|
1476
|
+
balanceItems: [
|
|
1477
|
+
],
|
|
1478
|
+
deleteRegistrationIds: [],
|
|
1479
|
+
}),
|
|
1480
|
+
administrationFee: 0,
|
|
1481
|
+
freeContribution: 0,
|
|
1482
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1483
|
+
totalPrice: 25,
|
|
1484
|
+
customer: PaymentCustomer.create({
|
|
1485
|
+
company: null,
|
|
1486
|
+
}),
|
|
1487
|
+
asOrganizationId: organization2.id,
|
|
1488
|
+
});
|
|
1489
|
+
// #endregion
|
|
1490
|
+
|
|
1491
|
+
// #region act and assert
|
|
1492
|
+
await expect(async () => await post(body, organization, token))
|
|
1493
|
+
.rejects
|
|
1494
|
+
.toThrow(new RegExp('customer.company is required'));
|
|
1495
|
+
// #endregion
|
|
1496
|
+
});
|
|
1497
|
+
|
|
1498
|
+
test('Should fail if company does not exist on organization', async () => {
|
|
1499
|
+
// #region arrange
|
|
1500
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
1501
|
+
group.settings.allowRegistrationsByOrganization = true;
|
|
1502
|
+
await group.save();
|
|
1503
|
+
|
|
1504
|
+
const { organization: organization2 } = await initData();
|
|
1505
|
+
|
|
1506
|
+
user.permissions = UserPermissions.create({
|
|
1507
|
+
organizationPermissions: new Map([
|
|
1508
|
+
[organization2.id, Permissions.create({
|
|
1509
|
+
level: PermissionLevel.Full,
|
|
1510
|
+
})],
|
|
1511
|
+
]),
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1514
|
+
await user.save();
|
|
1515
|
+
|
|
1516
|
+
const body = IDRegisterCheckout.create({
|
|
1517
|
+
cart: IDRegisterCart.create({
|
|
1518
|
+
items: [
|
|
1519
|
+
IDRegisterItem.create({
|
|
1520
|
+
id: uuidv4(),
|
|
1521
|
+
replaceRegistrationIds: [],
|
|
1522
|
+
options: [],
|
|
1523
|
+
groupPrice,
|
|
1524
|
+
organizationId: organization.id,
|
|
1525
|
+
groupId: group.id,
|
|
1526
|
+
memberId: member.id,
|
|
1527
|
+
}),
|
|
1528
|
+
],
|
|
1529
|
+
balanceItems: [
|
|
1530
|
+
],
|
|
1531
|
+
deleteRegistrationIds: [],
|
|
1532
|
+
}),
|
|
1533
|
+
administrationFee: 0,
|
|
1534
|
+
freeContribution: 0,
|
|
1535
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1536
|
+
totalPrice: 25,
|
|
1537
|
+
customer: PaymentCustomer.create({
|
|
1538
|
+
company: Company.create({
|
|
1539
|
+
name: 'test company',
|
|
1540
|
+
}),
|
|
1541
|
+
}),
|
|
1542
|
+
asOrganizationId: organization2.id,
|
|
1543
|
+
});
|
|
1544
|
+
// #endregion
|
|
1545
|
+
|
|
1546
|
+
// #region act and assert
|
|
1547
|
+
await expect(async () => await post(body, organization, token))
|
|
1548
|
+
.rejects
|
|
1549
|
+
.toThrow(new RegExp('Oeps, de facturatiegegevens die je probeerde te selecteren lijken niet meer te bestaan.'));
|
|
1550
|
+
// #endregion
|
|
1551
|
+
});
|
|
1552
|
+
|
|
1553
|
+
test('Should set paying organization id', async () => {
|
|
1554
|
+
// #region arrange
|
|
1555
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
1556
|
+
group.settings.allowRegistrationsByOrganization = true;
|
|
1557
|
+
await group.save();
|
|
1558
|
+
|
|
1559
|
+
const { organization: organization2 } = await initData();
|
|
1560
|
+
const company = Company.create({
|
|
1561
|
+
name: 'test company',
|
|
1562
|
+
});
|
|
1563
|
+
|
|
1564
|
+
organization2.meta.companies.push(company);
|
|
1565
|
+
await organization2.save();
|
|
1566
|
+
|
|
1567
|
+
user.permissions = UserPermissions.create({
|
|
1568
|
+
organizationPermissions: new Map([
|
|
1569
|
+
[organization2.id, Permissions.create({
|
|
1570
|
+
level: PermissionLevel.Full,
|
|
1571
|
+
})],
|
|
1572
|
+
]),
|
|
1573
|
+
});
|
|
1574
|
+
|
|
1575
|
+
await user.save();
|
|
1576
|
+
|
|
1577
|
+
const body = IDRegisterCheckout.create({
|
|
1578
|
+
cart: IDRegisterCart.create({
|
|
1579
|
+
items: [
|
|
1580
|
+
IDRegisterItem.create({
|
|
1581
|
+
id: uuidv4(),
|
|
1582
|
+
replaceRegistrationIds: [],
|
|
1583
|
+
options: [],
|
|
1584
|
+
groupPrice,
|
|
1585
|
+
organizationId: organization.id,
|
|
1586
|
+
groupId: group.id,
|
|
1587
|
+
memberId: member.id,
|
|
1588
|
+
}),
|
|
1589
|
+
],
|
|
1590
|
+
balanceItems: [
|
|
1591
|
+
],
|
|
1592
|
+
deleteRegistrationIds: [],
|
|
1593
|
+
}),
|
|
1594
|
+
administrationFee: 0,
|
|
1595
|
+
freeContribution: 0,
|
|
1596
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1597
|
+
totalPrice: 25,
|
|
1598
|
+
customer: PaymentCustomer.create({
|
|
1599
|
+
company,
|
|
1600
|
+
}),
|
|
1601
|
+
asOrganizationId: organization2.id,
|
|
1602
|
+
});
|
|
1603
|
+
// #endregion
|
|
1604
|
+
|
|
1605
|
+
// #region act and assert
|
|
1606
|
+
const response = await post(body, organization, token);
|
|
1607
|
+
expect(response.body.registrations.length).toBe(1);
|
|
1608
|
+
expect(response.body.registrations[0].payingOrganizationId).toEqual(organization2.id);
|
|
1609
|
+
// #endregion
|
|
1610
|
+
});
|
|
1611
|
+
});
|
|
1612
|
+
|
|
1613
|
+
describe('Replace registrations', () => {
|
|
1614
|
+
test('Should update registered members', async () => {
|
|
1615
|
+
// #region arrange
|
|
1616
|
+
const { organization, group: group1, groupPrice: groupPrice1, token, member } = await initData();
|
|
1617
|
+
|
|
1618
|
+
const registration = await new RegistrationFactory({
|
|
1619
|
+
member,
|
|
1620
|
+
group: group1,
|
|
1621
|
+
groupPrice: groupPrice1,
|
|
1622
|
+
})
|
|
1623
|
+
.create();
|
|
1624
|
+
|
|
1625
|
+
const group = await new GroupFactory({
|
|
1626
|
+
organization,
|
|
1627
|
+
price: 30,
|
|
1628
|
+
stock: 5,
|
|
1629
|
+
}).create();
|
|
1630
|
+
|
|
1631
|
+
const groupPrice = group.settings.prices[0];
|
|
1632
|
+
|
|
1633
|
+
const body = IDRegisterCheckout.create({
|
|
1634
|
+
cart: IDRegisterCart.create({
|
|
1635
|
+
items: [
|
|
1636
|
+
IDRegisterItem.create({
|
|
1637
|
+
id: uuidv4(),
|
|
1638
|
+
replaceRegistrationIds: [registration.id],
|
|
1639
|
+
options: [],
|
|
1640
|
+
groupPrice,
|
|
1641
|
+
organizationId: organization.id,
|
|
1642
|
+
groupId: group.id,
|
|
1643
|
+
memberId: member.id,
|
|
1644
|
+
}),
|
|
1645
|
+
],
|
|
1646
|
+
balanceItems: [],
|
|
1647
|
+
deleteRegistrationIds: [],
|
|
1648
|
+
}),
|
|
1649
|
+
administrationFee: 0,
|
|
1650
|
+
freeContribution: 0,
|
|
1651
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1652
|
+
totalPrice: 5,
|
|
1653
|
+
asOrganizationId: organization.id,
|
|
1654
|
+
customer: null,
|
|
1655
|
+
});
|
|
1656
|
+
// #endregion
|
|
1657
|
+
|
|
1658
|
+
// #region act and assert
|
|
1659
|
+
|
|
1660
|
+
// update occupancy to be sure occupancy is 1
|
|
1661
|
+
await group1.updateOccupancy();
|
|
1662
|
+
expect(group1.settings.registeredMembers).toBe(1);
|
|
1663
|
+
|
|
1664
|
+
// send request and check occupancy
|
|
1665
|
+
const response = await post(body, organization, token);
|
|
1666
|
+
|
|
1667
|
+
expect(response.body).toBeDefined();
|
|
1668
|
+
expect(response.body.registrations.length).toBe(1);
|
|
1669
|
+
|
|
1670
|
+
const updatedGroup = await Group.getByID(group.id);
|
|
1671
|
+
expect(updatedGroup!.settings.registeredMembers).toBe(1);
|
|
1672
|
+
expect(updatedGroup!.settings.reservedMembers).toBe(0);
|
|
1673
|
+
|
|
1674
|
+
const updatedGroup1After = await Group.getByID(group1.id);
|
|
1675
|
+
// occupancy should go from 1 to 0 because the registration should be replaced
|
|
1676
|
+
expect(updatedGroup1After!.settings.registeredMembers).toBe(0);
|
|
1677
|
+
expect(updatedGroup1After!.settings.reservedMembers).toBe(0);
|
|
1678
|
+
// #endregion
|
|
1679
|
+
});
|
|
1680
|
+
|
|
1681
|
+
test('Should set paid as organization on new registration', async () => {
|
|
1682
|
+
// #region arrange
|
|
1683
|
+
const { organization, group: group1, groupPrice: groupPrice1, token, member, user } = await initData();
|
|
1684
|
+
|
|
1685
|
+
group1.settings.allowRegistrationsByOrganization = true;
|
|
1686
|
+
await group1.save();
|
|
1687
|
+
const organization2 = await initOrganization();
|
|
1688
|
+
|
|
1689
|
+
user.permissions = UserPermissions.create({
|
|
1690
|
+
organizationPermissions: new Map([
|
|
1691
|
+
[organization2.id, Permissions.create({
|
|
1692
|
+
level: PermissionLevel.Full,
|
|
1693
|
+
})],
|
|
1694
|
+
[organization.id, Permissions.create({
|
|
1695
|
+
level: PermissionLevel.Full,
|
|
1696
|
+
})],
|
|
1697
|
+
]),
|
|
1698
|
+
});
|
|
1699
|
+
|
|
1700
|
+
await user.save();
|
|
1701
|
+
|
|
1702
|
+
const company = Company.create({
|
|
1703
|
+
name: 'test company',
|
|
1704
|
+
});
|
|
1705
|
+
|
|
1706
|
+
organization2.meta.companies.push(company);
|
|
1707
|
+
await organization2.save();
|
|
1708
|
+
|
|
1709
|
+
organization.meta.companies.push(company);
|
|
1710
|
+
await organization.save();
|
|
1711
|
+
|
|
1712
|
+
const body = IDRegisterCheckout.create({
|
|
1713
|
+
cart: IDRegisterCart.create({
|
|
1714
|
+
items: [
|
|
1715
|
+
IDRegisterItem.create({
|
|
1716
|
+
id: uuidv4(),
|
|
1717
|
+
replaceRegistrationIds: [],
|
|
1718
|
+
options: [],
|
|
1719
|
+
groupPrice: groupPrice1,
|
|
1720
|
+
organizationId: organization.id,
|
|
1721
|
+
groupId: group1.id,
|
|
1722
|
+
memberId: member.id,
|
|
1723
|
+
}),
|
|
1724
|
+
],
|
|
1725
|
+
balanceItems: [],
|
|
1726
|
+
deleteRegistrationIds: [],
|
|
1727
|
+
}),
|
|
1728
|
+
administrationFee: 0,
|
|
1729
|
+
freeContribution: 0,
|
|
1730
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1731
|
+
totalPrice: 25,
|
|
1732
|
+
asOrganizationId: organization2.id,
|
|
1733
|
+
customer: PaymentCustomer.create({
|
|
1734
|
+
company,
|
|
1735
|
+
}),
|
|
1736
|
+
});
|
|
1737
|
+
|
|
1738
|
+
const response1 = await post(body, organization, token);
|
|
1739
|
+
const registration = response1.body.registrations[0];
|
|
1740
|
+
expect(registration).toBeDefined();
|
|
1741
|
+
|
|
1742
|
+
const group = await new GroupFactory({
|
|
1743
|
+
organization,
|
|
1744
|
+
price: 30,
|
|
1745
|
+
stock: 5,
|
|
1746
|
+
}).create();
|
|
1747
|
+
|
|
1748
|
+
const groupPrice = group.settings.prices[0];
|
|
1749
|
+
|
|
1750
|
+
const body2 = IDRegisterCheckout.create({
|
|
1751
|
+
cart: IDRegisterCart.create({
|
|
1752
|
+
items: [
|
|
1753
|
+
IDRegisterItem.create({
|
|
1754
|
+
id: uuidv4(),
|
|
1755
|
+
replaceRegistrationIds: [registration.id],
|
|
1756
|
+
options: [],
|
|
1757
|
+
groupPrice,
|
|
1758
|
+
organizationId: organization.id,
|
|
1759
|
+
groupId: group.id,
|
|
1760
|
+
memberId: member.id,
|
|
1761
|
+
}),
|
|
1762
|
+
],
|
|
1763
|
+
balanceItems: [],
|
|
1764
|
+
deleteRegistrationIds: [],
|
|
1765
|
+
}),
|
|
1766
|
+
administrationFee: 0,
|
|
1767
|
+
freeContribution: 0,
|
|
1768
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1769
|
+
totalPrice: 30,
|
|
1770
|
+
asOrganizationId: organization.id,
|
|
1771
|
+
customer: PaymentCustomer.create({
|
|
1772
|
+
company,
|
|
1773
|
+
}),
|
|
1774
|
+
});
|
|
1775
|
+
// #endregion
|
|
1776
|
+
|
|
1777
|
+
// #region act and assert
|
|
1778
|
+
const response = await post(body2, organization, token);
|
|
1779
|
+
|
|
1780
|
+
expect(response.body).toBeDefined();
|
|
1781
|
+
expect(response.body.registrations.length).toBe(1);
|
|
1782
|
+
|
|
1783
|
+
// the payingOrganizationId should equal the id of the paying organization of the replaced registration
|
|
1784
|
+
expect(response.body.registrations[0].payingOrganizationId).toEqual(organization2.id);
|
|
1785
|
+
// #endregion
|
|
1786
|
+
});
|
|
1787
|
+
|
|
1788
|
+
test('Replace registration by registration of other member should fail', async () => {
|
|
1789
|
+
// #region arrange
|
|
1790
|
+
const { organization, group: group1, groupPrice: groupPrice1, token, member, otherMembers: [member2] } = await initData({ otherMemberAmount: 1 });
|
|
1791
|
+
|
|
1792
|
+
const registration = await new RegistrationFactory({
|
|
1793
|
+
member: member2,
|
|
1794
|
+
group: group1,
|
|
1795
|
+
groupPrice: groupPrice1,
|
|
1796
|
+
})
|
|
1797
|
+
.create();
|
|
1798
|
+
|
|
1799
|
+
const group = await new GroupFactory({
|
|
1800
|
+
organization,
|
|
1801
|
+
price: 30,
|
|
1802
|
+
stock: 5,
|
|
1803
|
+
}).create();
|
|
1804
|
+
|
|
1805
|
+
const groupPrice = group.settings.prices[0];
|
|
1806
|
+
|
|
1807
|
+
const body = IDRegisterCheckout.create({
|
|
1808
|
+
cart: IDRegisterCart.create({
|
|
1809
|
+
items: [
|
|
1810
|
+
IDRegisterItem.create({
|
|
1811
|
+
id: uuidv4(),
|
|
1812
|
+
replaceRegistrationIds: [registration.id],
|
|
1813
|
+
options: [],
|
|
1814
|
+
groupPrice,
|
|
1815
|
+
organizationId: organization.id,
|
|
1816
|
+
groupId: group.id,
|
|
1817
|
+
memberId: member.id,
|
|
1818
|
+
}),
|
|
1819
|
+
],
|
|
1820
|
+
balanceItems: [],
|
|
1821
|
+
deleteRegistrationIds: [],
|
|
1822
|
+
}),
|
|
1823
|
+
administrationFee: 0,
|
|
1824
|
+
freeContribution: 0,
|
|
1825
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1826
|
+
totalPrice: 5,
|
|
1827
|
+
asOrganizationId: organization.id,
|
|
1828
|
+
customer: null,
|
|
1829
|
+
});
|
|
1830
|
+
// #endregion
|
|
1831
|
+
|
|
1832
|
+
// #region act and assert
|
|
1833
|
+
await expect(async () => await post(body, organization, token))
|
|
1834
|
+
.rejects
|
|
1835
|
+
.toThrow(new RegExp('Registration not found'));
|
|
1836
|
+
// #endregion
|
|
1837
|
+
});
|
|
1838
|
+
|
|
1839
|
+
test('Move registration should fail if admin of same organization', async () => {
|
|
1840
|
+
// #region arrange
|
|
1841
|
+
const { organization, group: group1, groupPrice: groupPrice1, token, member } = await initData();
|
|
1842
|
+
|
|
1843
|
+
const registration = await new RegistrationFactory({
|
|
1844
|
+
member,
|
|
1845
|
+
group: group1,
|
|
1846
|
+
groupPrice: groupPrice1,
|
|
1847
|
+
})
|
|
1848
|
+
.create();
|
|
1849
|
+
|
|
1850
|
+
const group = await new GroupFactory({
|
|
1851
|
+
organization,
|
|
1852
|
+
price: 30,
|
|
1853
|
+
stock: 5,
|
|
1854
|
+
}).create();
|
|
114
1855
|
|
|
115
|
-
const
|
|
116
|
-
expect(updatedGroup!.settings.registeredMembers).toBe(1);
|
|
117
|
-
expect(updatedGroup!.settings.reservedMembers).toBe(0);
|
|
118
|
-
});
|
|
1856
|
+
const groupPrice = group.settings.prices[0];
|
|
119
1857
|
|
|
120
|
-
test('Should update reserved members', async () => {
|
|
121
|
-
// #region arrange
|
|
122
1858
|
const body = IDRegisterCheckout.create({
|
|
123
1859
|
cart: IDRegisterCart.create({
|
|
124
1860
|
items: [
|
|
125
1861
|
IDRegisterItem.create({
|
|
126
1862
|
id: uuidv4(),
|
|
127
|
-
replaceRegistrationIds: [],
|
|
1863
|
+
replaceRegistrationIds: [registration.id],
|
|
128
1864
|
options: [],
|
|
129
|
-
groupPrice
|
|
1865
|
+
groupPrice,
|
|
130
1866
|
organizationId: organization.id,
|
|
131
|
-
groupId:
|
|
1867
|
+
groupId: group.id,
|
|
132
1868
|
memberId: member.id,
|
|
133
1869
|
}),
|
|
134
1870
|
],
|
|
@@ -137,41 +1873,26 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
137
1873
|
}),
|
|
138
1874
|
administrationFee: 0,
|
|
139
1875
|
freeContribution: 0,
|
|
140
|
-
paymentMethod: PaymentMethod.
|
|
141
|
-
|
|
142
|
-
cancelUrl: new URL('https://www.example.com'),
|
|
143
|
-
totalPrice: 15,
|
|
1876
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1877
|
+
totalPrice: 5,
|
|
144
1878
|
customer: null,
|
|
145
1879
|
});
|
|
146
|
-
|
|
147
|
-
nock('https://api.ext.payconiq.com')
|
|
148
|
-
.post('/v3/payments')
|
|
149
|
-
.reply(200, {
|
|
150
|
-
paymentId: 'testPaymentId',
|
|
151
|
-
_links: {
|
|
152
|
-
checkout: {
|
|
153
|
-
href: 'https://www.example.com',
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
1880
|
// #endregion
|
|
158
1881
|
|
|
159
|
-
// act
|
|
160
|
-
const response = await post(body);
|
|
1882
|
+
// #region act and assert
|
|
161
1883
|
|
|
162
|
-
//
|
|
163
|
-
expect(
|
|
164
|
-
expect(response.body.registrations.length).toBe(1);
|
|
1884
|
+
// send request and check occupancy
|
|
1885
|
+
await expect(async () => await post(body, organization, token)).rejects.toThrow('Not allowed to move registrations');
|
|
165
1886
|
|
|
166
|
-
|
|
167
|
-
expect(updatedGroup!.settings.registeredMembers).toBe(0);
|
|
168
|
-
expect(updatedGroup!.settings.reservedMembers).toBe(1);
|
|
1887
|
+
// #endregion
|
|
169
1888
|
});
|
|
170
1889
|
});
|
|
171
1890
|
|
|
172
|
-
describe('
|
|
1891
|
+
describe('Delete registrations', () => {
|
|
173
1892
|
test('Should update registered members', async () => {
|
|
174
1893
|
// #region arrange
|
|
1894
|
+
const { member, group: group1, groupPrice: groupPrice1, organization: organization1, token } = await initData();
|
|
1895
|
+
|
|
175
1896
|
const registration = await new RegistrationFactory({
|
|
176
1897
|
member,
|
|
177
1898
|
group: group1,
|
|
@@ -180,7 +1901,7 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
180
1901
|
.create();
|
|
181
1902
|
|
|
182
1903
|
const group = await new GroupFactory({
|
|
183
|
-
organization,
|
|
1904
|
+
organization: organization1,
|
|
184
1905
|
price: 30,
|
|
185
1906
|
stock: 5,
|
|
186
1907
|
}).create();
|
|
@@ -192,22 +1913,22 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
192
1913
|
items: [
|
|
193
1914
|
IDRegisterItem.create({
|
|
194
1915
|
id: uuidv4(),
|
|
195
|
-
replaceRegistrationIds: [
|
|
1916
|
+
replaceRegistrationIds: [],
|
|
196
1917
|
options: [],
|
|
197
1918
|
groupPrice,
|
|
198
|
-
organizationId:
|
|
1919
|
+
organizationId: organization1.id,
|
|
199
1920
|
groupId: group.id,
|
|
200
1921
|
memberId: member.id,
|
|
201
1922
|
}),
|
|
202
1923
|
],
|
|
203
1924
|
balanceItems: [],
|
|
204
|
-
deleteRegistrationIds: [],
|
|
1925
|
+
deleteRegistrationIds: [registration.id],
|
|
205
1926
|
}),
|
|
206
1927
|
administrationFee: 0,
|
|
207
1928
|
freeContribution: 0,
|
|
208
1929
|
paymentMethod: PaymentMethod.PointOfSale,
|
|
209
1930
|
totalPrice: 5,
|
|
210
|
-
asOrganizationId:
|
|
1931
|
+
asOrganizationId: organization1.id,
|
|
211
1932
|
customer: null,
|
|
212
1933
|
});
|
|
213
1934
|
// #endregion
|
|
@@ -219,7 +1940,7 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
219
1940
|
expect(group1.settings.registeredMembers).toBe(1);
|
|
220
1941
|
|
|
221
1942
|
// send request and check occupancy
|
|
222
|
-
const response = await post(body);
|
|
1943
|
+
const response = await post(body, organization1, token);
|
|
223
1944
|
|
|
224
1945
|
expect(response.body).toBeDefined();
|
|
225
1946
|
expect(response.body.registrations.length).toBe(1);
|
|
@@ -229,7 +1950,7 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
229
1950
|
expect(updatedGroup!.settings.reservedMembers).toBe(0);
|
|
230
1951
|
|
|
231
1952
|
const updatedGroup1After = await Group.getByID(group1.id);
|
|
232
|
-
// occupancy should go from 1 to 0 because the registration should be
|
|
1953
|
+
// occupancy should go from 1 to 0 because the registration should be deleted
|
|
233
1954
|
expect(updatedGroup1After!.settings.registeredMembers).toBe(0);
|
|
234
1955
|
expect(updatedGroup1After!.settings.reservedMembers).toBe(0);
|
|
235
1956
|
// #endregion
|
|
@@ -237,6 +1958,8 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
237
1958
|
|
|
238
1959
|
test('Should throw error if with payment', async () => {
|
|
239
1960
|
// #region arrange
|
|
1961
|
+
const { member, group: group1, groupPrice: groupPrice1, organization: organization1, token } = await initData();
|
|
1962
|
+
|
|
240
1963
|
const registration = await new RegistrationFactory({
|
|
241
1964
|
member,
|
|
242
1965
|
group: group1,
|
|
@@ -245,7 +1968,7 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
245
1968
|
.create();
|
|
246
1969
|
|
|
247
1970
|
const group = await new GroupFactory({
|
|
248
|
-
organization,
|
|
1971
|
+
organization: organization1,
|
|
249
1972
|
price: 30,
|
|
250
1973
|
stock: 5,
|
|
251
1974
|
maxMembers: 1,
|
|
@@ -258,16 +1981,16 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
258
1981
|
items: [
|
|
259
1982
|
IDRegisterItem.create({
|
|
260
1983
|
id: uuidv4(),
|
|
261
|
-
replaceRegistrationIds: [
|
|
1984
|
+
replaceRegistrationIds: [],
|
|
262
1985
|
options: [],
|
|
263
1986
|
groupPrice,
|
|
264
|
-
organizationId:
|
|
1987
|
+
organizationId: organization1.id,
|
|
265
1988
|
groupId: group.id,
|
|
266
1989
|
memberId: member.id,
|
|
267
1990
|
}),
|
|
268
1991
|
],
|
|
269
1992
|
balanceItems: [],
|
|
270
|
-
deleteRegistrationIds: [],
|
|
1993
|
+
deleteRegistrationIds: [registration.id],
|
|
271
1994
|
}),
|
|
272
1995
|
administrationFee: 0,
|
|
273
1996
|
freeContribution: 0,
|
|
@@ -285,20 +2008,19 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
285
2008
|
await group1.updateOccupancy();
|
|
286
2009
|
expect(group1.settings.registeredMembers).toBe(1);
|
|
287
2010
|
|
|
288
|
-
await expect(async () => await post(body)).rejects.toThrow('
|
|
2011
|
+
await expect(async () => await post(body, organization1, token)).rejects.toThrow('Permission denied: you are not allowed to delete registrations');
|
|
289
2012
|
// #endregion
|
|
290
2013
|
});
|
|
291
|
-
});
|
|
292
2014
|
|
|
293
|
-
|
|
294
|
-
test('Should update registered members', async () => {
|
|
2015
|
+
test('Should deactivate registration', async () => {
|
|
295
2016
|
// #region arrange
|
|
2017
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
2018
|
+
|
|
296
2019
|
const registration = await new RegistrationFactory({
|
|
297
2020
|
member,
|
|
298
2021
|
group: group1,
|
|
299
2022
|
groupPrice: groupPrice1,
|
|
300
|
-
})
|
|
301
|
-
.create();
|
|
2023
|
+
}).create();
|
|
302
2024
|
|
|
303
2025
|
const group = await new GroupFactory({
|
|
304
2026
|
organization,
|
|
@@ -334,45 +2056,107 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
334
2056
|
// #endregion
|
|
335
2057
|
|
|
336
2058
|
// #region act and assert
|
|
2059
|
+
await post(body, organization, token);
|
|
337
2060
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
expect(
|
|
2061
|
+
const updatedRegistration = await Registration.getByID(registration.id);
|
|
2062
|
+
expect(updatedRegistration).toBeDefined();
|
|
2063
|
+
expect(updatedRegistration!.deactivatedAt).not.toBe(null);
|
|
2064
|
+
// #endregion
|
|
2065
|
+
});
|
|
341
2066
|
|
|
342
|
-
|
|
343
|
-
const
|
|
2067
|
+
test('Should fail if invalid cancelation fee', async () => {
|
|
2068
|
+
for (const cancellationFeePercentage of [10001, -1]) {
|
|
2069
|
+
// #region arrange
|
|
2070
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
344
2071
|
|
|
345
|
-
|
|
346
|
-
|
|
2072
|
+
const body1 = IDRegisterCheckout.create({
|
|
2073
|
+
cart: IDRegisterCart.create({
|
|
2074
|
+
items: [
|
|
2075
|
+
IDRegisterItem.create({
|
|
2076
|
+
id: uuidv4(),
|
|
2077
|
+
replaceRegistrationIds: [],
|
|
2078
|
+
options: [],
|
|
2079
|
+
groupPrice: groupPrice1,
|
|
2080
|
+
organizationId: organization.id,
|
|
2081
|
+
groupId: group1.id,
|
|
2082
|
+
memberId: member.id,
|
|
2083
|
+
}),
|
|
2084
|
+
],
|
|
2085
|
+
balanceItems: [],
|
|
2086
|
+
deleteRegistrationIds: [],
|
|
2087
|
+
}),
|
|
2088
|
+
administrationFee: 0,
|
|
2089
|
+
freeContribution: 0,
|
|
2090
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
2091
|
+
totalPrice: 25,
|
|
2092
|
+
asOrganizationId: organization.id,
|
|
2093
|
+
customer: null,
|
|
2094
|
+
});
|
|
347
2095
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
2096
|
+
const group2 = await new GroupFactory({
|
|
2097
|
+
organization,
|
|
2098
|
+
price: 30,
|
|
2099
|
+
stock: 5,
|
|
2100
|
+
}).create();
|
|
351
2101
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
2102
|
+
const groupPrice2 = group2.settings.prices[0];
|
|
2103
|
+
|
|
2104
|
+
const firstResponse = await post(body1, organization, token);
|
|
2105
|
+
expect(firstResponse).toBeDefined();
|
|
2106
|
+
expect(firstResponse.body.registrations.length).toBe(1);
|
|
2107
|
+
const registration = firstResponse.body.registrations[0];
|
|
2108
|
+
|
|
2109
|
+
const body2 = IDRegisterCheckout.create({
|
|
2110
|
+
cart: IDRegisterCart.create({
|
|
2111
|
+
items: [
|
|
2112
|
+
IDRegisterItem.create({
|
|
2113
|
+
id: uuidv4(),
|
|
2114
|
+
replaceRegistrationIds: [],
|
|
2115
|
+
options: [],
|
|
2116
|
+
groupPrice: groupPrice2,
|
|
2117
|
+
organizationId: organization.id,
|
|
2118
|
+
groupId: group2.id,
|
|
2119
|
+
memberId: member.id,
|
|
2120
|
+
}),
|
|
2121
|
+
],
|
|
2122
|
+
balanceItems: [],
|
|
2123
|
+
deleteRegistrationIds: [registration.id],
|
|
2124
|
+
}),
|
|
2125
|
+
cancellationFeePercentage,
|
|
2126
|
+
administrationFee: 0,
|
|
2127
|
+
freeContribution: 0,
|
|
2128
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
2129
|
+
totalPrice: 30,
|
|
2130
|
+
asOrganizationId: organization.id,
|
|
2131
|
+
customer: null,
|
|
2132
|
+
});
|
|
2133
|
+
// #endregion
|
|
2134
|
+
|
|
2135
|
+
// #region act and assert
|
|
2136
|
+
await expect(async () => await post(body2, organization, token))
|
|
2137
|
+
.rejects
|
|
2138
|
+
.toThrow(new RegExp('Invalid cancellation fee percentage.'));
|
|
356
2139
|
// #endregion
|
|
2140
|
+
}
|
|
357
2141
|
});
|
|
358
2142
|
|
|
359
|
-
test('
|
|
2143
|
+
test('Delete by member should fail if no permission to delete registration', async () => {
|
|
360
2144
|
// #region arrange
|
|
2145
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
2146
|
+
|
|
361
2147
|
const registration = await new RegistrationFactory({
|
|
362
2148
|
member,
|
|
363
2149
|
group: group1,
|
|
364
2150
|
groupPrice: groupPrice1,
|
|
365
|
-
})
|
|
366
|
-
.create();
|
|
2151
|
+
}).create();
|
|
367
2152
|
|
|
368
|
-
const
|
|
2153
|
+
const group2 = await new GroupFactory({
|
|
369
2154
|
organization,
|
|
370
2155
|
price: 30,
|
|
371
2156
|
stock: 5,
|
|
372
|
-
maxMembers: 1,
|
|
373
2157
|
}).create();
|
|
374
2158
|
|
|
375
|
-
const groupPrice =
|
|
2159
|
+
const groupPrice = group2.settings.prices[0];
|
|
376
2160
|
|
|
377
2161
|
const body = IDRegisterCheckout.create({
|
|
378
2162
|
cart: IDRegisterCart.create({
|
|
@@ -383,7 +2167,7 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
383
2167
|
options: [],
|
|
384
2168
|
groupPrice,
|
|
385
2169
|
organizationId: organization.id,
|
|
386
|
-
groupId:
|
|
2170
|
+
groupId: group2.id,
|
|
387
2171
|
memberId: member.id,
|
|
388
2172
|
}),
|
|
389
2173
|
],
|
|
@@ -392,59 +2176,195 @@ describe('Endpoint.RegisterMembers', () => {
|
|
|
392
2176
|
}),
|
|
393
2177
|
administrationFee: 0,
|
|
394
2178
|
freeContribution: 0,
|
|
395
|
-
paymentMethod: PaymentMethod.
|
|
396
|
-
redirectUrl: new URL('https://www.example.com'),
|
|
397
|
-
cancelUrl: new URL('https://www.example.com'),
|
|
2179
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
398
2180
|
totalPrice: 5,
|
|
399
2181
|
customer: null,
|
|
400
2182
|
});
|
|
401
2183
|
// #endregion
|
|
402
2184
|
|
|
403
2185
|
// #region act and assert
|
|
2186
|
+
await expect(async () => await post(body, organization, token))
|
|
2187
|
+
.rejects
|
|
2188
|
+
.toThrow(new RegExp('Permission denied: you are not allowed to delete registrations'));
|
|
2189
|
+
// #endregion
|
|
2190
|
+
});
|
|
404
2191
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
2192
|
+
test('Delete by organization should fail if no permission to delete registration', async () => {
|
|
2193
|
+
// #region arrange
|
|
2194
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData({ permissionLevel: PermissionLevel.Read });
|
|
2195
|
+
|
|
2196
|
+
const registration = await new RegistrationFactory({
|
|
2197
|
+
member,
|
|
2198
|
+
group: group1,
|
|
2199
|
+
groupPrice: groupPrice1,
|
|
2200
|
+
}).create();
|
|
2201
|
+
|
|
2202
|
+
const group2 = await new GroupFactory({
|
|
2203
|
+
organization,
|
|
2204
|
+
price: 30,
|
|
2205
|
+
stock: 5,
|
|
2206
|
+
}).create();
|
|
2207
|
+
|
|
2208
|
+
const groupPrice = group2.settings.prices[0];
|
|
2209
|
+
|
|
2210
|
+
const body = IDRegisterCheckout.create({
|
|
2211
|
+
cart: IDRegisterCart.create({
|
|
2212
|
+
items: [
|
|
2213
|
+
IDRegisterItem.create({
|
|
2214
|
+
id: uuidv4(),
|
|
2215
|
+
replaceRegistrationIds: [],
|
|
2216
|
+
options: [],
|
|
2217
|
+
groupPrice,
|
|
2218
|
+
organizationId: organization.id,
|
|
2219
|
+
groupId: group2.id,
|
|
2220
|
+
memberId: member.id,
|
|
2221
|
+
}),
|
|
2222
|
+
],
|
|
2223
|
+
balanceItems: [],
|
|
2224
|
+
deleteRegistrationIds: [registration.id],
|
|
2225
|
+
}),
|
|
2226
|
+
administrationFee: 0,
|
|
2227
|
+
freeContribution: 0,
|
|
2228
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
2229
|
+
totalPrice: 5,
|
|
2230
|
+
customer: null,
|
|
2231
|
+
asOrganizationId: organization.id,
|
|
2232
|
+
});
|
|
2233
|
+
// #endregion
|
|
408
2234
|
|
|
409
|
-
|
|
2235
|
+
// #region act and assert
|
|
2236
|
+
await expect(async () => await post(body, organization, token)).rejects.toThrow(new RegExp('Je hebt geen toegangsrechten om deze inschrijving te verwijderen'));
|
|
410
2237
|
// #endregion
|
|
411
2238
|
});
|
|
412
|
-
});
|
|
413
2239
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
member,
|
|
418
|
-
group: group1,
|
|
419
|
-
groupPrice: groupPrice1,
|
|
420
|
-
})
|
|
421
|
-
.create();
|
|
2240
|
+
test('Should fail if registration does not exist anymore', async () => {
|
|
2241
|
+
// #region arrange
|
|
2242
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
422
2243
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
2244
|
+
const registration = await new RegistrationFactory({
|
|
2245
|
+
member,
|
|
2246
|
+
group: group1,
|
|
2247
|
+
groupPrice: groupPrice1,
|
|
2248
|
+
}).create();
|
|
2249
|
+
|
|
2250
|
+
const group2 = await new GroupFactory({
|
|
2251
|
+
organization,
|
|
2252
|
+
price: 30,
|
|
2253
|
+
stock: 5,
|
|
2254
|
+
}).create();
|
|
2255
|
+
|
|
2256
|
+
const groupPrice = group2.settings.prices[0];
|
|
2257
|
+
|
|
2258
|
+
const body = IDRegisterCheckout.create({
|
|
2259
|
+
cart: IDRegisterCart.create({
|
|
2260
|
+
items: [
|
|
2261
|
+
IDRegisterItem.create({
|
|
2262
|
+
id: uuidv4(),
|
|
2263
|
+
replaceRegistrationIds: [],
|
|
2264
|
+
options: [],
|
|
2265
|
+
groupPrice,
|
|
2266
|
+
organizationId: organization.id,
|
|
2267
|
+
groupId: group2.id,
|
|
2268
|
+
memberId: member.id,
|
|
2269
|
+
}),
|
|
2270
|
+
],
|
|
2271
|
+
balanceItems: [],
|
|
2272
|
+
deleteRegistrationIds: [registration.id],
|
|
2273
|
+
}),
|
|
2274
|
+
administrationFee: 0,
|
|
2275
|
+
freeContribution: 0,
|
|
2276
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
2277
|
+
totalPrice: 5,
|
|
2278
|
+
customer: null,
|
|
2279
|
+
asOrganizationId: organization.id,
|
|
2280
|
+
});
|
|
2281
|
+
// #endregion
|
|
2282
|
+
|
|
2283
|
+
// #region act and assert
|
|
2284
|
+
await registration.delete();
|
|
2285
|
+
await expect(async () => await post(body, organization, token)).rejects.toThrow(new RegExp('Registration not found'));
|
|
2286
|
+
// #endregion
|
|
446
2287
|
});
|
|
447
2288
|
|
|
448
|
-
|
|
2289
|
+
test('Should fail if already deleted', async () => {
|
|
2290
|
+
// #region arrange
|
|
2291
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
2292
|
+
|
|
2293
|
+
const registration = await new RegistrationFactory({
|
|
2294
|
+
member,
|
|
2295
|
+
group: group1,
|
|
2296
|
+
groupPrice: groupPrice1,
|
|
2297
|
+
}).create();
|
|
2298
|
+
|
|
2299
|
+
const group2 = await new GroupFactory({
|
|
2300
|
+
organization,
|
|
2301
|
+
price: 30,
|
|
2302
|
+
stock: 5,
|
|
2303
|
+
}).create();
|
|
2304
|
+
|
|
2305
|
+
const groupPrice2 = group2.settings.prices[0];
|
|
2306
|
+
|
|
2307
|
+
const group3 = await new GroupFactory({
|
|
2308
|
+
organization,
|
|
2309
|
+
price: 30,
|
|
2310
|
+
stock: 5,
|
|
2311
|
+
}).create();
|
|
2312
|
+
|
|
2313
|
+
const groupPrice3 = group3.settings.prices[0];
|
|
2314
|
+
|
|
2315
|
+
const body1 = IDRegisterCheckout.create({
|
|
2316
|
+
cart: IDRegisterCart.create({
|
|
2317
|
+
items: [
|
|
2318
|
+
IDRegisterItem.create({
|
|
2319
|
+
id: uuidv4(),
|
|
2320
|
+
replaceRegistrationIds: [],
|
|
2321
|
+
options: [],
|
|
2322
|
+
groupPrice: groupPrice2,
|
|
2323
|
+
organizationId: organization.id,
|
|
2324
|
+
groupId: group2.id,
|
|
2325
|
+
memberId: member.id,
|
|
2326
|
+
}),
|
|
2327
|
+
],
|
|
2328
|
+
balanceItems: [],
|
|
2329
|
+
deleteRegistrationIds: [registration.id],
|
|
2330
|
+
}),
|
|
2331
|
+
administrationFee: 0,
|
|
2332
|
+
freeContribution: 0,
|
|
2333
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
2334
|
+
totalPrice: 5,
|
|
2335
|
+
customer: null,
|
|
2336
|
+
asOrganizationId: organization.id,
|
|
2337
|
+
});
|
|
2338
|
+
|
|
2339
|
+
const body2 = IDRegisterCheckout.create({
|
|
2340
|
+
cart: IDRegisterCart.create({
|
|
2341
|
+
items: [
|
|
2342
|
+
IDRegisterItem.create({
|
|
2343
|
+
id: uuidv4(),
|
|
2344
|
+
replaceRegistrationIds: [],
|
|
2345
|
+
options: [],
|
|
2346
|
+
groupPrice: groupPrice3,
|
|
2347
|
+
organizationId: organization.id,
|
|
2348
|
+
groupId: group3.id,
|
|
2349
|
+
memberId: member.id,
|
|
2350
|
+
}),
|
|
2351
|
+
],
|
|
2352
|
+
balanceItems: [],
|
|
2353
|
+
deleteRegistrationIds: [registration.id],
|
|
2354
|
+
}),
|
|
2355
|
+
administrationFee: 0,
|
|
2356
|
+
freeContribution: 0,
|
|
2357
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
2358
|
+
totalPrice: 5,
|
|
2359
|
+
customer: null,
|
|
2360
|
+
asOrganizationId: organization.id,
|
|
2361
|
+
});
|
|
2362
|
+
// #endregion
|
|
2363
|
+
|
|
2364
|
+
// #region act and assert
|
|
2365
|
+
await post(body1, organization, token);
|
|
2366
|
+
await expect(async () => await post(body2, organization, token)).rejects.toThrow(new RegExp('Oeps, één of meerdere inschrijvingen die je probeert te verwijderen was al verwijderd. Herlaad de pagina en probeer opnieuw'));
|
|
2367
|
+
// #endregion
|
|
2368
|
+
});
|
|
449
2369
|
});
|
|
450
2370
|
});
|