Passed
Push — feature/azure-webapp-pipeline-... ( 271549...3c88ad )
by Grant
07:11 queued 10s
created

resources/assets/js/hooks/webResourceHooks/indexCrudReducer.test.ts   A

Complexity

Total Complexity 1
Complexity/F 1

Size

Lines of Code 824
Function Count 1

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 1
eloc 616
c 0
b 0
f 0
dl 0
loc 824
rs 9.984
mnd 0
bc 0
fnc 1
bpm 0
cpm 1
noi 0
1
import indexCrudReducer, {
2
  ActionTypes,
3
  CreateFulfillAction,
4
  CreateRejectAction,
5
  CreateStartAction,
6
  DeleteFulfillAction,
7
  DeleteRejectAction,
8
  DeleteStartAction,
9
  IndexFulfillAction,
10
  IndexRejectAction,
11
  IndexStartAction,
12
  initializeState,
13
  ResourceState,
14
  UpdateFulfillAction,
15
  UpdateRejectAction,
16
  UpdateStartAction,
17
} from "./indexCrudReducer";
18
19
interface TestResource {
20
  id: number;
21
  name: string;
22
}
23
function addKey<T extends { id: number }>(item: T): { item: T; key: string } {
24
  return {
25
    item,
26
    key: String(item.id),
27
  };
28
}
29
30
describe("indexCrudReducer tests", (): void => {
31
  describe("Test INDEX actions", () => {
32
    it("updates indexMeta in response to INDEX START", () => {
33
      const initialState = initializeState([]);
34
      const expectState = {
35
        ...initialState,
36
        indexMeta: {
37
          status: "pending",
38
          pendingCount: 1,
39
          error: undefined,
40
        },
41
      };
42
      const action: IndexStartAction = { type: ActionTypes.IndexStart };
43
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
44
    });
45
    it("increments index pendingCount twice for two INDEX START actions", () => {
46
      const initialState = initializeState([]);
47
      const expectState = {
48
        ...initialState,
49
        indexMeta: {
50
          status: "pending",
51
          pendingCount: 2,
52
          error: undefined,
53
        },
54
      };
55
      const action: IndexStartAction = { type: ActionTypes.IndexStart };
56
      const state1 = indexCrudReducer(initialState, action);
57
      const state2 = indexCrudReducer(state1, action);
58
      expect(state2).toEqual(expectState);
59
    });
60
    it("decrements pending count, updates status, and saves values when INDEX FULFILLED", () => {
61
      const initialState: ResourceState<TestResource> = {
62
        ...initializeState([]),
63
        indexMeta: {
64
          status: "pending",
65
          pendingCount: 1,
66
          error: undefined,
67
        },
68
      };
69
      const action: IndexFulfillAction<TestResource> = {
70
        type: ActionTypes.IndexFulfill,
71
        payload: [
72
          { id: 1, name: "one" },
73
          { id: 2, name: "two" },
74
        ].map(addKey),
75
      };
76
      const expectState = {
77
        ...initialState,
78
        indexMeta: {
79
          status: "fulfilled",
80
          pendingCount: 0,
81
          error: undefined,
82
        },
83
        values: {
84
          1: {
85
            value: { id: 1, name: "one" },
86
            status: "fulfilled",
87
            pendingCount: 0,
88
            error: undefined,
89
          },
90
          2: {
91
            value: { id: 2, name: "two" },
92
            status: "fulfilled",
93
            pendingCount: 0,
94
            error: undefined,
95
          },
96
        },
97
      };
98
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
99
    });
100
    it("INDEX FULFILLED overwrites item values and errors, but not pendingCount (and status if pending), if they already exist", () => {
101
      const initialState: ResourceState<TestResource> = {
102
        ...initializeState([]),
103
        indexMeta: {
104
          status: "pending",
105
          pendingCount: 1,
106
          error: new Error(),
107
        },
108
        values: {
109
          1: {
110
            value: { id: 1, name: "one" },
111
            status: "pending",
112
            pendingCount: 2,
113
            error: undefined,
114
          },
115
          2: {
116
            value: { id: 2, name: "two" },
117
            status: "pending",
118
            pendingCount: 1,
119
            error: new Error("Something went wrong with a pretend request."),
120
          },
121
          3: {
122
            value: { id: 3, name: "three" },
123
            status: "rejected",
124
            pendingCount: 0,
125
            error: new Error("Something went wrong with a pretend request."),
126
          },
127
          4: {
128
            value: { id: 4, name: "four" },
129
            status: "initial",
130
            pendingCount: 0,
131
            error: undefined,
132
          },
133
        },
134
      };
135
      const action: IndexFulfillAction<TestResource> = {
136
        type: ActionTypes.IndexFulfill,
137
        payload: [
138
          { id: 1, name: "new one" },
139
          { id: 2, name: "new two" },
140
          { id: 3, name: "new three" },
141
          { id: 4, name: "new four" },
142
        ].map(addKey),
143
      };
144
      const expectState = {
145
        ...initialState,
146
        indexMeta: {
147
          status: "fulfilled",
148
          pendingCount: 0,
149
          error: undefined,
150
        },
151
        values: {
152
          1: {
153
            ...initialState.values[1],
154
            value: { id: 1, name: "new one" },
155
          },
156
          2: {
157
            ...initialState.values[2],
158
            value: { id: 2, name: "new two" },
159
            error: undefined, // Overwrites error, but not pendingCount and pending status
160
          },
161
          3: {
162
            value: { id: 3, name: "new three" },
163
            status: "fulfilled", // Rejected status replaced with fulfilled
164
            pendingCount: 0,
165
            error: undefined,
166
          },
167
          4: {
168
            value: { id: 4, name: "new four" },
169
            status: "fulfilled", // Initial status replaced with fulfilled
170
            pendingCount: 0,
171
            error: undefined,
172
          },
173
        },
174
      };
175
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
176
    });
177
    it("INDEX FULFILLED deletes values not included in payload", () => {
178
      const initialState: ResourceState<TestResource> = {
179
        ...initializeState(
180
          [
181
            { id: 1, name: "one" },
182
            { id: 2, name: "two" },
183
          ].map(addKey),
184
        ),
185
        indexMeta: {
186
          status: "pending",
187
          pendingCount: 1,
188
          error: undefined,
189
        },
190
      };
191
      const action: IndexFulfillAction<TestResource> = {
192
        type: ActionTypes.IndexFulfill,
193
        payload: [{ id: 2, name: "new two" }].map(addKey),
194
      };
195
      const expectState = {
196
        ...initialState,
197
        indexMeta: {
198
          status: "fulfilled",
199
          pendingCount: 0,
200
          error: undefined,
201
        },
202
        values: {
203
          2: {
204
            ...initialState.values[2],
205
            value: { id: 2, name: "new two" },
206
            status: "fulfilled",
207
          },
208
        },
209
      };
210
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
211
    });
212
    it("INDEX REJECTED decrements pendingCount, sets status to rejected, and doesn't modify values", () => {
213
      const initialState: ResourceState<TestResource> = {
214
        ...initializeState([{ id: 1, name: "one" }].map(addKey)),
215
        indexMeta: {
216
          status: "pending",
217
          pendingCount: 1,
218
          error: undefined,
219
        },
220
      };
221
      const action: IndexRejectAction = {
222
        type: ActionTypes.IndexReject,
223
        payload: new Error("Something went wrong with a fake request"),
224
      };
225
      const expectState = {
226
        ...initialState,
227
        indexMeta: {
228
          status: "rejected",
229
          pendingCount: 0,
230
          error: action.payload,
231
        },
232
        // Values are unchanged
233
      };
234
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
235
    });
236
    it("status remains 'pending' after INDEX FULFILLED and INDEX REJECTED if pendingCount was higher than 1", () => {
237
      const initialState: ResourceState<TestResource> = {
238
        ...initializeState([]),
239
        indexMeta: {
240
          status: "pending",
241
          pendingCount: 2,
242
          error: undefined,
243
        },
244
      };
245
      const fulfilledAction: IndexFulfillAction<TestResource> = {
246
        type: ActionTypes.IndexFulfill,
247
        payload: [],
248
      };
249
      const fulfilledState = {
250
        ...initialState,
251
        indexMeta: {
252
          status: "pending",
253
          pendingCount: 1,
254
          error: undefined,
255
        },
256
      };
257
      expect(indexCrudReducer(initialState, fulfilledAction)).toEqual(
258
        fulfilledState,
259
      );
260
      const rejectedAction: IndexRejectAction = {
261
        type: ActionTypes.IndexReject,
262
        payload: new Error(),
263
      };
264
      const rejectedState = {
265
        ...initialState,
266
        indexMeta: {
267
          status: "pending",
268
          pendingCount: 1,
269
          error: rejectedAction.payload,
270
        },
271
      };
272
      expect(indexCrudReducer(initialState, rejectedAction)).toEqual(
273
        rejectedState,
274
      );
275
    });
276
  });
277
  describe("Test CREATE actions", (): void => {
278
    it("CREATE START updates createMeta", () => {
279
      const initialState: ResourceState<TestResource> = initializeState([]);
280
      const expectState = {
281
        ...initialState,
282
        createMeta: {
283
          status: "pending",
284
          pendingCount: 1,
285
          error: undefined,
286
        },
287
      };
288
      const action: CreateStartAction<TestResource> = {
289
        type: ActionTypes.CreateStart,
290
        meta: { item: { id: 1, name: "one" } },
291
      };
292
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
293
    });
294
    it("two CREATE START actions increment pendingCount twice", () => {
295
      const initialState: ResourceState<TestResource> = initializeState([]);
296
      const expectState = {
297
        ...initialState,
298
        createMeta: {
299
          status: "pending",
300
          pendingCount: 2,
301
          error: undefined,
302
        },
303
      };
304
      const action: CreateStartAction<TestResource> = {
305
        type: ActionTypes.CreateStart,
306
        meta: { item: { id: 1, name: "one" } },
307
      };
308
      const state1 = indexCrudReducer(initialState, action);
309
      const state2 = indexCrudReducer(state1, action);
310
      expect(state2).toEqual(expectState);
311
    });
312
    it("CREATE FULFILLED decrements pending count, updates status, and saves new value", () => {
313
      const initialState: ResourceState<TestResource> = {
314
        ...initializeState([]),
315
        createMeta: {
316
          status: "pending",
317
          pendingCount: 1,
318
          error: undefined,
319
        },
320
      };
321
      const action: CreateFulfillAction<TestResource> = {
322
        type: ActionTypes.CreateFulfill,
323
        payload: addKey({ id: 1, name: "one" }),
324
        meta: { item: { id: 0, name: "one" } },
325
      };
326
      const expectState = {
327
        ...initialState,
328
        createMeta: {
329
          status: "fulfilled",
330
          pendingCount: 0,
331
          error: undefined,
332
        },
333
        values: {
334
          1: {
335
            value: { id: 1, name: "one" },
336
            status: "fulfilled",
337
            pendingCount: 0,
338
            error: undefined,
339
          },
340
        },
341
      };
342
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
343
    });
344
    it("CREATE FULFILLED overwrites an error", () => {
345
      const initialState: ResourceState<TestResource> = {
346
        ...initializeState([]),
347
        createMeta: {
348
          status: "pending",
349
          pendingCount: 1,
350
          error: new Error(),
351
        },
352
      };
353
      const action: CreateFulfillAction<TestResource> = {
354
        type: ActionTypes.CreateFulfill,
355
        payload: addKey({ id: 1, name: "one" }),
356
        meta: { item: { id: 0, name: "one" } },
357
      };
358
      expect(
359
        indexCrudReducer(initialState, action).createMeta.error,
360
      ).toBeUndefined();
361
    });
362
    it("CREATE REJECTED decrements pendingCount, sets status to rejected, and doesn't modify values", () => {
363
      const initialState: ResourceState<TestResource> = {
364
        ...initializeState([{ id: 1, name: "one" }].map(addKey)),
365
        createMeta: {
366
          status: "pending",
367
          pendingCount: 1,
368
          error: undefined,
369
        },
370
      };
371
      const action: CreateRejectAction<TestResource> = {
372
        type: ActionTypes.CreateReject,
373
        payload: new Error("Something went wrong with a fake request"),
374
        meta: { item: { id: 0, name: "two" } },
375
      };
376
      const expectState = {
377
        ...initialState,
378
        createMeta: {
379
          status: "rejected",
380
          pendingCount: 0,
381
          error: action.payload,
382
        },
383
        // Values are unchanged
384
      };
385
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
386
    });
387
    it("status remains 'pending' after CREATE FULFILLED and CREATE REJECTED if pendingCount was higher than 1", () => {
388
      const initialState: ResourceState<TestResource> = {
389
        ...initializeState([]),
390
        createMeta: {
391
          status: "pending",
392
          pendingCount: 2,
393
          error: undefined,
394
        },
395
      };
396
      const fulfilledAction: CreateFulfillAction<TestResource> = {
397
        type: ActionTypes.CreateFulfill,
398
        payload: addKey({ id: 1, name: "one" }),
399
        meta: { item: { id: 0, name: "one" } },
400
      };
401
      const fulfilledState = indexCrudReducer(initialState, fulfilledAction);
402
      expect(fulfilledState.createMeta).toEqual({
403
        status: "pending",
404
        pendingCount: 1,
405
        error: undefined,
406
      });
407
      const rejectedAction: CreateRejectAction<TestResource> = {
408
        type: ActionTypes.CreateReject,
409
        payload: new Error(),
410
        meta: { item: { id: 0, name: "one" } },
411
      };
412
      const rejectedState = indexCrudReducer(initialState, rejectedAction);
413
      expect(rejectedState.createMeta).toEqual({
414
        status: "pending",
415
        pendingCount: 1,
416
        error: rejectedAction.payload,
417
      });
418
    });
419
  });
420
  describe("Test UPDATE actions", (): void => {
421
    it("UPDATE START updates item-specific metadata", () => {
422
      const initialState: ResourceState<TestResource> = initializeState(
423
        [{ id: 1, name: "one" }].map(addKey),
424
      );
425
      const expectState = {
426
        ...initialState,
427
        values: {
428
          1: {
429
            value: initialState.values[1].value,
430
            status: "pending",
431
            pendingCount: 1,
432
            error: undefined,
433
          },
434
        },
435
      };
436
      const action: UpdateStartAction<TestResource> = {
437
        type: ActionTypes.UpdateStart,
438
        meta: addKey({ id: 1, name: "one" }),
439
      };
440
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
441
    });
442
    it("two UPDATE START actions increment pendingCount twice", () => {
443
      const initialState: ResourceState<TestResource> = initializeState(
444
        [{ id: 1, name: "one" }].map(addKey),
445
      );
446
      const expectState = {
447
        ...initialState,
448
        values: {
449
          1: {
450
            value: initialState.values[1].value,
451
            status: "pending",
452
            pendingCount: 2, // pendingCount is 2 this time
453
            error: undefined,
454
          },
455
        },
456
      };
457
      const action: UpdateStartAction<TestResource> = {
458
        type: ActionTypes.UpdateStart,
459
        meta: addKey({ id: 1, name: "one" }),
460
      };
461
      const state1 = indexCrudReducer(initialState, action);
462
      const state2 = indexCrudReducer(state1, action);
463
      expect(state2).toEqual(expectState);
464
    });
465
    it("UPDATE START overwrites an error status", () => {
466
      const initialState: ResourceState<TestResource> = {
467
        ...initializeState([]),
468
        values: {
469
          1: {
470
            value: { id: 1, name: "one" },
471
            status: "rejected",
472
            pendingCount: 0,
473
            error: new Error(),
474
          },
475
        },
476
      };
477
      const expectState = {
478
        ...initialState,
479
        values: {
480
          1: {
481
            value: initialState.values[1].value,
482
            status: "pending",
483
            pendingCount: 1,
484
            error: undefined, // Note the error has been erased after new request starts.
485
          },
486
        },
487
      };
488
      const action: UpdateStartAction<TestResource> = {
489
        type: ActionTypes.UpdateStart,
490
        meta: addKey({ id: 1, name: "one" }),
491
      };
492
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
493
    });
494
    it("UPDATE FULFILLED decrements pending count, updates status, and updates value", () => {
495
      const initialState: ResourceState<TestResource> = {
496
        ...initializeState([]),
497
        values: {
498
          1: {
499
            value: { id: 1, name: "one" },
500
            status: "pending",
501
            pendingCount: 1,
502
            error: undefined,
503
          },
504
        },
505
      };
506
      const action: UpdateFulfillAction<TestResource> = {
507
        type: ActionTypes.UpdateFulfill,
508
        payload: { id: 1, name: "NEW one" },
509
        meta: addKey({ id: 1, name: "NEW one" }),
510
      };
511
      const expectState = {
512
        ...initialState,
513
        values: {
514
          1: {
515
            value: action.payload,
516
            status: "fulfilled",
517
            pendingCount: 0,
518
            error: undefined,
519
          },
520
        },
521
      };
522
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
523
    });
524
    it("UPDATE FULFILLED does not change data for other values", () => {
525
      const initialState = initializeState(
526
        [
527
          { id: 1, name: "one" },
528
          { id: 2, name: "two" },
529
        ].map(addKey),
530
      );
531
      const action: UpdateFulfillAction<TestResource> = {
532
        type: ActionTypes.UpdateFulfill,
533
        payload: { id: 1, name: "NEW one" },
534
        meta: addKey({ id: 1, name: "NEW one" }),
535
      };
536
      const fulfilledState = indexCrudReducer(initialState, action);
537
      expect(fulfilledState.values[2]).toEqual(initialState.values[2]);
538
      expect(fulfilledState.values[1]).not.toEqual(initialState.values[1]);
539
    });
540
    it("UPDATE FULFILLED saves payload, not metadata, as new value in store", () => {
541
      const initialState = initializeState(
542
        [{ id: 1, name: "one" }].map(addKey),
543
      );
544
      const action: UpdateFulfillAction<TestResource> = {
545
        type: ActionTypes.UpdateFulfill,
546
        payload: { id: 1, name: "NEW one" },
547
        meta: addKey({ id: 1, name: "Doesn't matter what metadata value is" }),
548
      };
549
      const fulfilledState = indexCrudReducer(initialState, action);
550
      expect(fulfilledState.values[1].value).toEqual(action.payload);
551
      expect(fulfilledState.values[1].value).not.toEqual(action.meta.item);
552
    });
553
    it("UPDATE FULFILLED overwrites an error", () => {
554
      const initialState: ResourceState<TestResource> = {
555
        ...initializeState([]),
556
        values: {
557
          1: {
558
            value: { id: 1, name: "one" },
559
            status: "pending",
560
            pendingCount: 1,
561
            error: new Error(),
562
          },
563
        },
564
      };
565
      const action: UpdateFulfillAction<TestResource> = {
566
        type: ActionTypes.UpdateFulfill,
567
        payload: { id: 1, name: "NEW one" },
568
        meta: addKey({ id: 1, name: "NEW one" }),
569
      };
570
      const fulfilledState = indexCrudReducer(initialState, action);
571
      expect(fulfilledState.values[1].error).toBeUndefined();
572
    });
573
    it("UPDATE REJECTED decrements pendingCount, sets status to rejected, and doesn't modify last value", () => {
574
      const initialState: ResourceState<TestResource> = {
575
        ...initializeState([]),
576
        values: {
577
          1: {
578
            value: { id: 1, name: "one" },
579
            status: "pending",
580
            pendingCount: 1,
581
            error: undefined,
582
          },
583
        },
584
      };
585
      const action: UpdateRejectAction<TestResource> = {
586
        type: ActionTypes.UpdateReject,
587
        payload: new Error("Something went wrong with a fake request"),
588
        meta: addKey({ id: 1, name: "NEW one" }),
589
      };
590
      const expectState = {
591
        ...initialState,
592
        values: {
593
          1: {
594
            value: initialState.values[1].value,
595
            status: "rejected",
596
            pendingCount: 0,
597
            error: action.payload,
598
          },
599
        },
600
      };
601
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
602
    });
603
    it("status remains 'pending' after UPDATE FULFILLED and UPDATE REJECTED if pendingCount was higher than 1", () => {
604
      const initialState: ResourceState<TestResource> = {
605
        ...initializeState([]),
606
        values: {
607
          1: {
608
            value: { id: 1, name: "one" },
609
            status: "pending",
610
            pendingCount: 2,
611
            error: undefined,
612
          },
613
        },
614
      };
615
      const fulfilledAction: UpdateFulfillAction<TestResource> = {
616
        type: ActionTypes.UpdateFulfill,
617
        payload: { id: 1, name: "NEW one" },
618
        meta: addKey({ id: 1, name: "NEW one" }),
619
      };
620
      const fulfilledState = indexCrudReducer(initialState, fulfilledAction);
621
      expect(fulfilledState.values[1]).toEqual({
622
        value: fulfilledAction.payload,
623
        status: "pending",
624
        pendingCount: 1,
625
        error: undefined,
626
      });
627
      const rejectedAction: UpdateRejectAction<TestResource> = {
628
        type: ActionTypes.UpdateReject,
629
        payload: new Error(),
630
        meta: addKey({ id: 1, name: "one" }),
631
      };
632
      const rejectedState = indexCrudReducer(initialState, rejectedAction);
633
      expect(rejectedState.values[1]).toEqual({
634
        value: initialState.values[1].value,
635
        status: "pending",
636
        pendingCount: 1,
637
        error: rejectedAction.payload,
638
      });
639
    });
640
  });
641
  describe("Test DELETE actions", () => {
642
    it("DELETE START updates item-specific metadata", () => {
643
      const initialState: ResourceState<TestResource> = initializeState(
644
        [{ id: 1, name: "one" }].map(addKey),
645
      );
646
      const expectState = {
647
        ...initialState,
648
        values: {
649
          1: {
650
            value: initialState.values[1].value,
651
            status: "pending",
652
            pendingCount: 1,
653
            error: undefined,
654
          },
655
        },
656
      };
657
      const action: DeleteStartAction = {
658
        type: ActionTypes.DeleteStart,
659
        meta: { key: 1 },
660
      };
661
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
662
    });
663
    it("two DELETE START actions increment pendingCount twice", () => {
664
      const initialState: ResourceState<TestResource> = initializeState(
665
        [{ id: 1, name: "one" }].map(addKey),
666
      );
667
      const expectState = {
668
        ...initialState,
669
        values: {
670
          1: {
671
            value: initialState.values[1].value,
672
            status: "pending",
673
            pendingCount: 2, // pendingCount is 2 this time
674
            error: undefined,
675
          },
676
        },
677
      };
678
      const action: DeleteStartAction = {
679
        type: ActionTypes.DeleteStart,
680
        meta: { key: 1 },
681
      };
682
      const state1 = indexCrudReducer(initialState, action);
683
      const state2 = indexCrudReducer(state1, action);
684
      expect(state2).toEqual(expectState);
685
    });
686
    it("DELETE START overwrites an error status", () => {
687
      const initialState: ResourceState<TestResource> = {
688
        ...initializeState([]),
689
        values: {
690
          1: {
691
            value: { id: 1, name: "one" },
692
            status: "rejected",
693
            pendingCount: 0,
694
            error: new Error(),
695
          },
696
        },
697
      };
698
      const expectState = {
699
        ...initialState,
700
        values: {
701
          1: {
702
            value: initialState.values[1].value,
703
            status: "pending",
704
            pendingCount: 1,
705
            error: undefined, // Note the error has been erased after new request starts.
706
          },
707
        },
708
      };
709
      const action: DeleteStartAction = {
710
        type: ActionTypes.DeleteStart,
711
        meta: { key: 1 },
712
      };
713
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
714
    });
715
    it("DELETE FULFILLED removes value entry entirely", () => {
716
      const initialState: ResourceState<TestResource> = {
717
        ...initializeState([]),
718
        values: {
719
          1: {
720
            value: { id: 1, name: "one" },
721
            status: "pending",
722
            pendingCount: 1,
723
            error: undefined,
724
          },
725
        },
726
      };
727
      const action: DeleteFulfillAction = {
728
        type: ActionTypes.DeleteFulfill,
729
        meta: { key: 1 },
730
      };
731
      const expectState = {
732
        ...initialState,
733
        values: {},
734
      };
735
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
736
    });
737
    it("DELETE FULFILLED doesn't affect other values", () => {
738
      const initialState = initializeState(
739
        [
740
          { id: 1, name: "one" },
741
          { id: 2, name: "two" },
742
        ].map(addKey),
743
      );
744
      const action: DeleteFulfillAction = {
745
        type: ActionTypes.DeleteFulfill,
746
        meta: { key: 1 },
747
      };
748
      const fulfilledState = indexCrudReducer(initialState, action);
749
      expect(fulfilledState.values[2]).toEqual(initialState.values[2]);
750
      expect(fulfilledState.values[1]).toBeUndefined();
751
    });
752
    it("DELETE FULFILLED doesn't change state (or throw error) if value doesn't exist", () => {
753
      const initialState = initializeState(
754
        [{ id: 1, name: "one" }].map(addKey),
755
      );
756
      const action: DeleteFulfillAction = {
757
        type: ActionTypes.DeleteFulfill,
758
        meta: { key: "5" },
759
      };
760
      expect(indexCrudReducer(initialState, action)).toEqual(initialState);
761
    });
762
    it("DELETE REJECTED decrements pendingCount, sets status to rejected, and doesn't modify item value", () => {
763
      const initialState: ResourceState<TestResource> = {
764
        ...initializeState([]),
765
        values: {
766
          1: {
767
            value: { id: 1, name: "one" },
768
            status: "pending",
769
            pendingCount: 1,
770
            error: undefined,
771
          },
772
        },
773
      };
774
      const action: DeleteRejectAction = {
775
        type: ActionTypes.DeleteReject,
776
        payload: new Error("Something went wrong"),
777
        meta: { key: 1 },
778
      };
779
      const expectState = {
780
        ...initialState,
781
        values: {
782
          1: {
783
            value: { id: 1, name: "one" },
784
            status: "rejected",
785
            pendingCount: 0,
786
            error: action.payload,
787
          },
788
        },
789
      };
790
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
791
    });
792
    it("status remains 'pending' after DELETE REJECTED if if pendingCount was higher than 1", () => {
793
      const initialState: ResourceState<TestResource> = {
794
        ...initializeState([]),
795
        values: {
796
          1: {
797
            value: { id: 1, name: "one" },
798
            status: "pending",
799
            pendingCount: 3,
800
            error: undefined,
801
          },
802
        },
803
      };
804
      const action: DeleteRejectAction = {
805
        type: ActionTypes.DeleteReject,
806
        payload: new Error("Something went wrong"),
807
        meta: { key: 1 },
808
      };
809
      const expectState = {
810
        ...initialState,
811
        values: {
812
          1: {
813
            value: { id: 1, name: "one" },
814
            status: "pending",
815
            pendingCount: 2,
816
            error: action.payload,
817
          },
818
        },
819
      };
820
      expect(indexCrudReducer(initialState, action)).toEqual(expectState);
821
    });
822
  });
823
});
824