@stamhoofd/models 2.11.0 → 2.13.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.
Files changed (37) hide show
  1. package/dist/src/helpers/MemberMerger.d.ts +13 -0
  2. package/dist/src/helpers/MemberMerger.d.ts.map +1 -0
  3. package/dist/src/helpers/MemberMerger.js +328 -0
  4. package/dist/src/helpers/MemberMerger.js.map +1 -0
  5. package/dist/src/helpers/MemberMerger.test.d.ts +2 -0
  6. package/dist/src/helpers/MemberMerger.test.d.ts.map +1 -0
  7. package/dist/src/helpers/MemberMerger.test.js +605 -0
  8. package/dist/src/helpers/MemberMerger.test.js.map +1 -0
  9. package/dist/src/index.d.ts +1 -0
  10. package/dist/src/index.d.ts.map +1 -1
  11. package/dist/src/index.js +1 -0
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/migrations/1723736282-merged-members.sql +19 -0
  14. package/dist/src/models/Member.d.ts.map +1 -1
  15. package/dist/src/models/Member.js +1 -0
  16. package/dist/src/models/Member.js.map +1 -1
  17. package/dist/src/models/MergedMember.d.ts +23 -0
  18. package/dist/src/models/MergedMember.d.ts.map +1 -0
  19. package/dist/src/models/MergedMember.js +121 -0
  20. package/dist/src/models/MergedMember.js.map +1 -0
  21. package/dist/src/models/Organization.d.ts +1 -2
  22. package/dist/src/models/Organization.d.ts.map +1 -1
  23. package/dist/src/models/Organization.js +0 -9
  24. package/dist/src/models/Organization.js.map +1 -1
  25. package/dist/src/models/index.d.ts +1 -0
  26. package/dist/src/models/index.d.ts.map +1 -1
  27. package/dist/src/models/index.js +3 -1
  28. package/dist/src/models/index.js.map +1 -1
  29. package/package.json +2 -2
  30. package/src/helpers/MemberMerger.test.ts +719 -0
  31. package/src/helpers/MemberMerger.ts +497 -0
  32. package/src/index.ts +1 -0
  33. package/src/migrations/1723736282-merged-members.sql +19 -0
  34. package/src/models/Member.ts +2 -1
  35. package/src/models/MergedMember.ts +112 -0
  36. package/src/models/Organization.ts +0 -9
  37. package/src/models/index.ts +1 -0
@@ -0,0 +1,719 @@
1
+ import {
2
+ Address,
3
+ BooleanStatus,
4
+ Country,
5
+ EmergencyContact,
6
+ Gender,
7
+ MemberDetails,
8
+ Parent,
9
+ RecordAnswer,
10
+ RecordSettings,
11
+ ReviewTime,
12
+ ReviewTimes,
13
+ } from "@stamhoofd/structures";
14
+ import { v4 as uuidv4 } from "uuid";
15
+ import { Member } from "../models";
16
+ import { mergeMemberDetails, selectBaseMember } from "./MemberMerger";
17
+
18
+ describe("member merge", () => {
19
+ describe("mergeMemberDetails", () => {
20
+ describe("empty base details", () => {
21
+ //#region arrange
22
+ const m1 = new Member();
23
+ const m2 = new Member();
24
+ const d1Old = MemberDetails.create({
25
+ firstName: " ",
26
+ lastName: "",
27
+ birthDay: undefined,
28
+ memberNumber: undefined,
29
+ uitpasNumber: undefined,
30
+ email: " ",
31
+ phone: undefined,
32
+ gender: Gender.Other,
33
+ requiresFinancialSupport: undefined,
34
+ dataPermissions: undefined,
35
+ address: undefined,
36
+ parents: [],
37
+ emergencyContacts: [],
38
+ reviewTimes: undefined,
39
+ recordAnswers: undefined,
40
+ unverifiedEmails: [],
41
+ unverifiedPhones: [],
42
+ unverifiedAddresses: [],
43
+ notes: undefined,
44
+ });
45
+
46
+ const recordAnswer = RecordAnswer.create({
47
+ settings: RecordSettings.create({
48
+ name: "answer1",
49
+ required: true,
50
+ choices: [],
51
+ }),
52
+ });
53
+
54
+ const d2Old = MemberDetails.create({
55
+ firstName: "John",
56
+ lastName: "Doe",
57
+ birthDay: new Date(1990, 1, 1),
58
+ memberNumber: "123",
59
+ uitpasNumber: "56",
60
+ email: "b7v2X@example.com",
61
+ phone: "04863544",
62
+ gender: Gender.Male,
63
+ requiresFinancialSupport: BooleanStatus.create({ value: true }),
64
+ dataPermissions: BooleanStatus.create({ value: true }),
65
+ address: Address.create({
66
+ city: "Amsterdam",
67
+ street: "Mozartstraat",
68
+ number: "1",
69
+ postalCode: "1011AB",
70
+ country: Country.Netherlands,
71
+ }),
72
+ parents: [Parent.create({ firstName: "John", lastName: "Doe" })],
73
+ emergencyContacts: [
74
+ EmergencyContact.create({
75
+ name: "blabla",
76
+ title: "title",
77
+ phone: "04863544654",
78
+ }),
79
+ ],
80
+ reviewTimes: ReviewTimes.create({
81
+ times: [
82
+ ReviewTime.create({
83
+ name: "parents",
84
+ reviewedAt: new Date(2020, 1, 1),
85
+ }),
86
+ ReviewTime.create({
87
+ name: "details",
88
+ reviewedAt: new Date(2021, 1, 1),
89
+ }),
90
+ ],
91
+ }),
92
+ recordAnswers: new Map([[recordAnswer.id, recordAnswer]]),
93
+ unverifiedEmails: ["email1@test.be", "email2@test.be"],
94
+ unverifiedPhones: ["04863545", "04863546"],
95
+ unverifiedAddresses: [
96
+ Address.create({
97
+ city: "Amsterdam",
98
+ street: "Mozartstraat",
99
+ number: "2",
100
+ postalCode: "1011AB",
101
+ country: Country.Netherlands,
102
+ }),
103
+ ],
104
+ notes: "note1",
105
+ });
106
+
107
+ m1.details = d1Old.clone();
108
+ m2.details = d2Old.clone();
109
+ //#endregion
110
+
111
+ // act
112
+ let d1: MemberDetails;
113
+
114
+ beforeAll(() => {
115
+ mergeMemberDetails(m1, m2);
116
+ d1 = m1.details;
117
+ });
118
+
119
+ // assert
120
+ test("firstName", () => {
121
+ expect(d1.firstName).toBe(d2Old.firstName);
122
+ });
123
+
124
+ test("lastName", () => {
125
+ expect(d1.lastName).toBe(d2Old.lastName);
126
+ });
127
+
128
+ test("memberNumber", () => {
129
+ expect(d1.memberNumber).toBe(d2Old.memberNumber);
130
+ });
131
+
132
+ test("uitpasNumber", () => {
133
+ expect(d1.uitpasNumber).toBe(d2Old.uitpasNumber);
134
+ });
135
+
136
+ test("email", () => {
137
+ expect(d1.email).toBe(d2Old.email);
138
+ expect(d1.unverifiedEmails).not.toContain(d2Old.email);
139
+ });
140
+
141
+ test("phone", () => {
142
+ expect(d1.phone).toBe(d2Old.phone);
143
+ expect(d1.unverifiedPhones).not.toContain(d2Old.phone);
144
+ });
145
+
146
+ test("gender", () => {
147
+ expect(d1.gender).toBe(d2Old.gender);
148
+ });
149
+
150
+ test("birthDay", () => {
151
+ expect(d1.birthDay?.getTime() ?? -1).toBe(
152
+ d2Old.birthDay?.getTime() ?? -1
153
+ );
154
+ });
155
+
156
+ test("requires financial support", () => {
157
+ expect(d1.requiresFinancialSupport?.date.getTime() ?? -1).toBe(
158
+ d2Old.requiresFinancialSupport?.date.getTime() ?? -1
159
+ );
160
+ });
161
+
162
+ test("data permissions", () => {
163
+ expect(d1.dataPermissions?.date.getTime() ?? -1).toBe(
164
+ d2Old.dataPermissions?.date.getTime() ?? -1
165
+ );
166
+ });
167
+
168
+ test("address", () => {
169
+ expect(d1.address?.id).toBe(d2Old.address?.id);
170
+ });
171
+
172
+ test("parents", () => {
173
+ expect(d1.parents.length).toBe(d2Old.parents.length);
174
+ });
175
+
176
+ test("emergency contacts", () => {
177
+ expect(d1.emergencyContacts.length).toBe(
178
+ d2Old.emergencyContacts.length
179
+ );
180
+ });
181
+
182
+ test("review times", () => {
183
+ expect(d1.reviewTimes.times.length).toBe(
184
+ d2Old.reviewTimes.times.length
185
+ );
186
+ });
187
+
188
+ test("answers", () => {
189
+ expect(d1.recordAnswers.size).toBe(d2Old.recordAnswers.size);
190
+ });
191
+
192
+ test("unverifiedEmails", () => {
193
+ expect(d1.unverifiedEmails.length).toBe(d2Old.unverifiedEmails.length);
194
+ });
195
+
196
+ test("unverifiedPhones", () => {
197
+ expect(d1.unverifiedPhones.length).toBe(d2Old.unverifiedPhones.length);
198
+ });
199
+
200
+ test("unverifiedAddresses", () => {
201
+ expect(d1.unverifiedAddresses.length).toBe(
202
+ d2Old.unverifiedAddresses.length
203
+ );
204
+ });
205
+
206
+ test("notes", () => {
207
+ expect(d1.notes).toEqual("note1");
208
+ });
209
+ });
210
+
211
+ describe("empty other details", () => {
212
+ //#region arrange
213
+ const m1 = new Member();
214
+ const m2 = new Member();
215
+
216
+ const recordAnswer = RecordAnswer.create({
217
+ settings: RecordSettings.create({
218
+ name: "answer1",
219
+ required: true,
220
+ choices: [],
221
+ }),
222
+ });
223
+
224
+ const d1Old = MemberDetails.create({
225
+ firstName: "John",
226
+ lastName: "Doe",
227
+ birthDay: new Date(1990, 1, 1),
228
+ memberNumber: "123",
229
+ uitpasNumber: "56",
230
+ email: "b7v2X@example.com",
231
+ phone: "04863544",
232
+ gender: Gender.Male,
233
+ requiresFinancialSupport: BooleanStatus.create({ value: true }),
234
+ dataPermissions: BooleanStatus.create({ value: true }),
235
+ address: Address.create({
236
+ city: "Amsterdam",
237
+ street: "Mozartstraat",
238
+ number: "1",
239
+ postalCode: "1011AB",
240
+ country: Country.Netherlands,
241
+ }),
242
+ parents: [Parent.create({ firstName: "John", lastName: "Doe" })],
243
+ emergencyContacts: [
244
+ EmergencyContact.create({
245
+ name: "blabla",
246
+ title: "title",
247
+ phone: "04863544654",
248
+ }),
249
+ ],
250
+ reviewTimes: ReviewTimes.create({
251
+ times: [
252
+ ReviewTime.create({
253
+ name: "parents",
254
+ reviewedAt: new Date(2020, 1, 1),
255
+ }),
256
+ ReviewTime.create({
257
+ name: "details",
258
+ reviewedAt: new Date(2021, 1, 1),
259
+ }),
260
+ ],
261
+ }),
262
+ recordAnswers: new Map([[recordAnswer.id, recordAnswer]]),
263
+ unverifiedEmails: ["email1@test.be", "email2@test.be"],
264
+ unverifiedPhones: ["04863545", "04863546"],
265
+ unverifiedAddresses: [
266
+ Address.create({
267
+ city: "Amsterdam",
268
+ street: "Mozartstraat",
269
+ number: "2",
270
+ postalCode: "1011AB",
271
+ country: Country.Netherlands,
272
+ }),
273
+ ],
274
+ notes: "note1",
275
+ });
276
+
277
+ const d2Old = MemberDetails.create({
278
+ firstName: " ",
279
+ lastName: "",
280
+ birthDay: undefined,
281
+ memberNumber: undefined,
282
+ uitpasNumber: undefined,
283
+ email: " ",
284
+ phone: undefined,
285
+ gender: Gender.Other,
286
+ requiresFinancialSupport: undefined,
287
+ dataPermissions: undefined,
288
+ address: undefined,
289
+ parents: [],
290
+ emergencyContacts: [],
291
+ reviewTimes: undefined,
292
+ recordAnswers: undefined,
293
+ unverifiedEmails: [],
294
+ unverifiedPhones: [],
295
+ unverifiedAddresses: [],
296
+ notes: undefined,
297
+ });
298
+
299
+ m1.details = d1Old.clone();
300
+ m2.details = d2Old.clone();
301
+ //#endregion
302
+
303
+ // act
304
+ let d1: MemberDetails;
305
+
306
+ beforeAll(() => {
307
+ mergeMemberDetails(m1, m2);
308
+ d1 = m1.details;
309
+ });
310
+
311
+ // assert
312
+ test("firstName", () => {
313
+ expect(d1.firstName).toBe(d1Old.firstName);
314
+ });
315
+
316
+ test("lastName", () => {
317
+ expect(d1.lastName).toBe(d1Old.lastName);
318
+ });
319
+
320
+ test("memberNumber", () => {
321
+ expect(d1.memberNumber).toBe(d1Old.memberNumber);
322
+ });
323
+
324
+ test("uitpasNumber", () => {
325
+ expect(d1.uitpasNumber).toBe(d1Old.uitpasNumber);
326
+ });
327
+
328
+ test("email", () => {
329
+ expect(d1.email).toBe(d1Old.email);
330
+ expect(d1.unverifiedEmails).not.toContain(d2Old.email);
331
+ });
332
+
333
+ test("phone", () => {
334
+ expect(d1.phone).toBe(d1Old.phone);
335
+ expect(d1.unverifiedPhones).not.toContain(d2Old.phone);
336
+ });
337
+
338
+ test("gender", () => {
339
+ expect(d1.gender).toBe(d1Old.gender);
340
+ });
341
+
342
+ test("birthDay", () => {
343
+ expect(d1.birthDay?.getTime() ?? -1).toBe(
344
+ d1Old.birthDay?.getTime() ?? -1
345
+ );
346
+ });
347
+
348
+ test("requires financial support", () => {
349
+ expect(d1.requiresFinancialSupport?.date.getTime() ?? -1).toBe(
350
+ d1Old.requiresFinancialSupport?.date.getTime() ?? -1
351
+ );
352
+ });
353
+
354
+ test("data permissions", () => {
355
+ expect(d1.dataPermissions?.date.getTime() ?? -1).toBe(
356
+ d1Old.dataPermissions?.date.getTime() ?? -1
357
+ );
358
+ });
359
+
360
+ test("address", () => {
361
+ expect(d1.address?.id).toBe(d1Old.address?.id);
362
+ });
363
+
364
+ test("parents", () => {
365
+ expect(d1.parents.length).toBe(d1Old.parents.length);
366
+ });
367
+
368
+ test("emergency contacts", () => {
369
+ expect(d1.emergencyContacts.length).toBe(
370
+ d1Old.emergencyContacts.length
371
+ );
372
+ });
373
+
374
+ test("review times", () => {
375
+ expect(d1.reviewTimes.times.length).toBe(
376
+ d1Old.reviewTimes.times.length
377
+ );
378
+ });
379
+
380
+ test("answers", () => {
381
+ expect(d1.recordAnswers.size).toBe(d1Old.recordAnswers.size);
382
+ });
383
+
384
+ test("unverifiedEmails", () => {
385
+ expect(d1.unverifiedEmails.length).toBe(d1Old.unverifiedEmails.length);
386
+ });
387
+
388
+ test("unverifiedPhones", () => {
389
+ expect(d1.unverifiedPhones.length).toBe(d1Old.unverifiedPhones.length);
390
+ });
391
+
392
+ test("unverifiedAddresses", () => {
393
+ expect(d1.unverifiedAddresses.length).toBe(
394
+ d1Old.unverifiedAddresses.length
395
+ );
396
+ });
397
+
398
+ test("notes", () => {
399
+ expect(d1.notes).toEqual("note1");
400
+ });
401
+ });
402
+
403
+ describe("complete base and other details", () => {
404
+ //#region arrange
405
+ const m1 = new Member();
406
+ const m2 = new Member();
407
+
408
+ const recordAnswer1 = RecordAnswer.create({
409
+ settings: RecordSettings.create({
410
+ name: "answer1",
411
+ required: true,
412
+ choices: [],
413
+ }),
414
+ });
415
+
416
+ const recordAnswer1b = recordAnswer1.clone();
417
+ recordAnswer1b.date = new Date(1990, 1, 1);
418
+
419
+ const recordAnswer2 = RecordAnswer.create({
420
+ settings: RecordSettings.create({
421
+ name: "answer2",
422
+ required: true,
423
+ choices: [],
424
+ }),
425
+ });
426
+
427
+ // will not changed because cloned
428
+ const oldParent1 = Parent.create({
429
+ firstName: "John",
430
+ lastName: "Doe",
431
+ email: "john@test.be",
432
+ phone: "04111111",
433
+ });
434
+
435
+ const parent1Alt = Parent.create({
436
+ firstName: "John",
437
+ lastName: "Doe",
438
+ email: "oldJohn@test.be",
439
+ phone: "0499999",
440
+ address: Address.create({
441
+ street: "john street",
442
+ number: "5",
443
+ city: "Amsterdam",
444
+ postalCode: "1011AB",
445
+ country: Country.Belgium,
446
+ }),
447
+ });
448
+
449
+ const d1Old = MemberDetails.create({
450
+ firstName: "John",
451
+ lastName: "Doe",
452
+ birthDay: new Date(1990, 1, 1),
453
+ memberNumber: "123",
454
+ uitpasNumber: "56",
455
+ email: "b7v2X@example.com",
456
+ phone: "04863544",
457
+ gender: Gender.Male,
458
+ requiresFinancialSupport: BooleanStatus.create({
459
+ value: true,
460
+ date: new Date(2021, 1, 1),
461
+ }),
462
+ dataPermissions: BooleanStatus.create({
463
+ value: true,
464
+ date: new Date(2020, 1, 1),
465
+ }),
466
+ address: Address.create({
467
+ city: "Amsterdam",
468
+ street: "Mozartstraat",
469
+ number: "1",
470
+ postalCode: "1011AB",
471
+ country: Country.Netherlands,
472
+ }),
473
+ parents: [oldParent1],
474
+ emergencyContacts: [
475
+ EmergencyContact.create({
476
+ name: "blabla",
477
+ title: "title",
478
+ phone: "04863544654",
479
+ }),
480
+ EmergencyContact.create({
481
+ name: "blabla2",
482
+ title: "title2",
483
+ phone: "04863544654",
484
+ }),
485
+ ],
486
+ reviewTimes: ReviewTimes.create({
487
+ times: [
488
+ ReviewTime.create({
489
+ name: "parents",
490
+ reviewedAt: new Date(2020, 1, 1),
491
+ }),
492
+ ReviewTime.create({
493
+ name: "details",
494
+ reviewedAt: new Date(2021, 1, 1),
495
+ }),
496
+ ],
497
+ }),
498
+ recordAnswers: new Map([[recordAnswer1.id, recordAnswer1]]),
499
+ unverifiedEmails: ["email1@test.be", "email2@test.be"],
500
+ unverifiedPhones: ["04863545", "04863546"],
501
+ unverifiedAddresses: [
502
+ Address.create({
503
+ city: "Amsterdam",
504
+ street: "Mozartstraat",
505
+ number: "2",
506
+ postalCode: "1011AB",
507
+ country: Country.Netherlands,
508
+ }),
509
+ ],
510
+ notes: "note1",
511
+ });
512
+
513
+ const d2Old = MemberDetails.create({
514
+ firstName: "John",
515
+ lastName: "Doe",
516
+ birthDay: new Date(2000, 1, 1),
517
+ memberNumber: "123456",
518
+ uitpasNumber: "567",
519
+ email: "other@example.com",
520
+ phone: "048635449",
521
+ gender: Gender.Female,
522
+ // earlier date
523
+ requiresFinancialSupport: BooleanStatus.create({
524
+ value: false,
525
+ date: new Date(2020, 1, 1),
526
+ }),
527
+ // older date
528
+ dataPermissions: BooleanStatus.create({
529
+ value: false,
530
+ date: new Date(2021, 1, 1),
531
+ }),
532
+ address: Address.create({
533
+ city: "Amsterdam",
534
+ street: "Mozartstraat",
535
+ number: "5",
536
+ postalCode: "1011AB",
537
+ country: Country.Netherlands,
538
+ }),
539
+ parents: [
540
+ parent1Alt,
541
+ Parent.create({ firstName: "John", lastName: "Other" }),
542
+ ],
543
+ emergencyContacts: [
544
+ EmergencyContact.create({
545
+ name: "other emergency contact",
546
+ title: "title",
547
+ phone: "04863544654",
548
+ }),
549
+ EmergencyContact.create({
550
+ name: "blabla",
551
+ title: "title",
552
+ phone: "04863544654",
553
+ }),
554
+ ],
555
+ reviewTimes: ReviewTimes.create({
556
+ times: [
557
+ ReviewTime.create({
558
+ name: "parents",
559
+ reviewedAt: new Date(2019, 1, 1),
560
+ }),
561
+ ReviewTime.create({
562
+ name: "details",
563
+ reviewedAt: new Date(2023, 1, 1),
564
+ }),
565
+ ],
566
+ }),
567
+ recordAnswers: new Map([
568
+ [recordAnswer2.id, recordAnswer2],
569
+ [recordAnswer1.id, recordAnswer1],
570
+ [recordAnswer1b.id, recordAnswer1b],
571
+ ]),
572
+ unverifiedEmails: ["otherUnverivied@test.be"],
573
+ unverifiedPhones: ["0486354599", "0486354699"],
574
+ unverifiedAddresses: [
575
+ Address.create({
576
+ city: "Amsterdam",
577
+ street: "AndereStraat",
578
+ number: "100",
579
+ postalCode: "1011AB",
580
+ country: Country.Netherlands,
581
+ }),
582
+ ],
583
+ notes: "note2",
584
+ });
585
+
586
+ m1.details = d1Old.clone();
587
+ m2.details = d2Old.clone();
588
+ //#endregion
589
+
590
+ // act
591
+ let d1: MemberDetails;
592
+ let parent1: Parent;
593
+
594
+ beforeAll(() => {
595
+ mergeMemberDetails(m1, m2);
596
+ d1 = m1.details;
597
+ parent1 = d1.parents.find((p) => p.id === oldParent1.id)!;
598
+ });
599
+
600
+ // assert
601
+ test("firstName", () => {
602
+ expect(d1.firstName).toBe(d1Old.firstName);
603
+ });
604
+
605
+ test("lastName", () => {
606
+ expect(d1.lastName).toBe(d1Old.lastName);
607
+ });
608
+
609
+ test("memberNumber", () => {
610
+ expect(d1.memberNumber).toBe(d1Old.memberNumber);
611
+ });
612
+
613
+ test("uitpasNumber", () => {
614
+ expect(d1.uitpasNumber).toBe(d1Old.uitpasNumber);
615
+ });
616
+
617
+ test("email", () => {
618
+ expect(d1.email).toBe(d1Old.email);
619
+ expect(d1.unverifiedEmails).toContain(d2Old.email);
620
+ });
621
+
622
+ test("phone", () => {
623
+ expect(d1.phone).toBe(d1Old.phone);
624
+ expect(d1.unverifiedPhones).toContain(d2Old.phone);
625
+ });
626
+
627
+ test("gender", () => {
628
+ expect(d1.gender).toBe(d1Old.gender);
629
+ });
630
+
631
+ test("birthDay", () => {
632
+ expect(d1.birthDay?.getTime() ?? -1).toBe(
633
+ d1Old.birthDay?.getTime() ?? -1
634
+ );
635
+ });
636
+
637
+ test("requires financial support", () => {
638
+ expect(d1.requiresFinancialSupport?.date.getTime() ?? -1).toBe(
639
+ d1Old.requiresFinancialSupport?.date.getTime() ?? -1
640
+ );
641
+ });
642
+
643
+ test("data permissions", () => {
644
+ expect(d1.dataPermissions?.date.getTime() ?? -1).toBe(
645
+ d2Old.dataPermissions?.date.getTime() ?? -1
646
+ );
647
+ });
648
+
649
+ test("address", () => {
650
+ expect(d1.address?.id).toBe(d1Old.address?.id);
651
+ expect(d1.unverifiedAddresses.map((a) => a.id)).toContain(
652
+ d2Old.address?.id
653
+ );
654
+ });
655
+
656
+ test("parents", () => {
657
+ expect(d1.parents.length).toBe(2);
658
+ expect(parent1.firstName).toBe(parent1Alt.firstName);
659
+ expect(parent1.lastName).toBe(parent1Alt.lastName);
660
+ expect(parent1.email).toBe(oldParent1.email);
661
+ expect(parent1.phone).toBe(oldParent1.phone);
662
+ expect(parent1.address?.id).toBe(parent1Alt.address?.id);
663
+ expect(d1.unverifiedPhones).toContain(parent1Alt.phone);
664
+ expect(parent1.alternativeEmails).toContain(parent1Alt.email);
665
+ });
666
+
667
+ test("emergency contacts", () => {
668
+ expect(d1.emergencyContacts.length).toBe(3);
669
+ });
670
+
671
+ test("review times", () => {
672
+ expect(d1.reviewTimes.times.length).toBe(2);
673
+ });
674
+
675
+ test("answers", () => {
676
+ expect(d1.recordAnswers.size).toBe(3);
677
+ });
678
+
679
+ test("unverifiedEmails", () => {
680
+ expect(d1.unverifiedEmails.length).toBe(4);
681
+ });
682
+
683
+ test("unverifiedPhones", () => {
684
+ expect(d1.unverifiedPhones.length).toBe(6);
685
+ });
686
+
687
+ test("unverifiedAddresses", () => {
688
+ expect(d1.unverifiedAddresses.length).toBe(3);
689
+ });
690
+
691
+ test("notes", () => {
692
+ expect(d1.notes).toEqual("note1\nnote2");
693
+ });
694
+ });
695
+ });
696
+
697
+ test("select base member should return last created member", () => {
698
+ const m1 = new Member();
699
+ m1.createdAt = new Date(2020, 0, 1);
700
+ m1.id = uuidv4();
701
+ const m2 = new Member();
702
+ m2.createdAt = new Date(2021, 0, 1);
703
+ m2.id = uuidv4();
704
+ const m3 = new Member();
705
+ m3.createdAt = new Date(2022, 0, 1);
706
+ m3.id = uuidv4();
707
+
708
+ const members = [m1, m3, m2];
709
+
710
+ const { base, others } = selectBaseMember(members);
711
+
712
+ expect(base.id).toBe(m3.id);
713
+
714
+ expect(others).toHaveLength(2);
715
+ const otherIds = others.map((m) => m.id);
716
+ expect(otherIds).toContain(m1.id);
717
+ expect(otherIds).toContain(m2.id);
718
+ });
719
+ });