@unite-us/app-create-referral 0.15.176 → 0.15.177
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/dist/api/ApiHooks.js +25 -1
- package/dist/api/ApiHooks.js.map +1 -1
- package/dist/hooks/__tests__/useCreateReferrals.test.js +664 -8
- package/dist/hooks/__tests__/useCreateReferrals.test.js.map +1 -1
- package/dist/hooks/useCreateReferrals.js +284 -72
- package/dist/hooks/useCreateReferrals.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { renderHook, act } from '@testing-library/react-hooks';
|
|
2
2
|
import useCreateReferrals from '../useCreateReferrals';
|
|
3
3
|
import { useAppCreateReferralContext } from '../../context/AppCreateReferralProvider';
|
|
4
|
-
import { useCreateRecord, useUpdateRecord } from '../../api/ApiHooks';
|
|
5
|
-
import { coreApi } from '../../api/config';
|
|
4
|
+
import { useAtomicOperations, useCreateRecord, useUpdateRecord } from '../../api/ApiHooks';
|
|
5
|
+
import { coreApi, FEATURE_FLAGS } from '../../api/config';
|
|
6
6
|
jest.mock('../../context/AppCreateReferralProvider', () => ({
|
|
7
7
|
useAppCreateReferralContext: jest.fn(),
|
|
8
8
|
setData: data => ({
|
|
@@ -11,6 +11,7 @@ jest.mock('../../context/AppCreateReferralProvider', () => ({
|
|
|
11
11
|
})
|
|
12
12
|
}));
|
|
13
13
|
jest.mock('../../api/ApiHooks', () => ({
|
|
14
|
+
useAtomicOperations: jest.fn(),
|
|
14
15
|
useCreateRecord: jest.fn(),
|
|
15
16
|
useUpdateRecord: jest.fn()
|
|
16
17
|
}));
|
|
@@ -24,6 +25,7 @@ jest.mock('../../api/config', () => ({
|
|
|
24
25
|
query: jest.fn(),
|
|
25
26
|
uploadFile: jest.fn()
|
|
26
27
|
},
|
|
28
|
+
FEATURE_FLAGS: {},
|
|
27
29
|
CALLBACKS: {
|
|
28
30
|
notify: {
|
|
29
31
|
error: jest.fn()
|
|
@@ -87,6 +89,7 @@ describe('useCreateReferrals', () => {
|
|
|
87
89
|
service_start: null,
|
|
88
90
|
service_end: null
|
|
89
91
|
},
|
|
92
|
+
description: 'Test Referral',
|
|
90
93
|
programs: [{
|
|
91
94
|
id: 'program1',
|
|
92
95
|
provider: {
|
|
@@ -364,6 +367,14 @@ describe('useCreateReferrals', () => {
|
|
|
364
367
|
};
|
|
365
368
|
beforeEach(() => {
|
|
366
369
|
jest.clearAllMocks();
|
|
370
|
+
Object.keys(FEATURE_FLAGS).forEach(key => delete FEATURE_FLAGS[key]);
|
|
371
|
+
useAtomicOperations.mockReturnValue({
|
|
372
|
+
atomicOperations: jest.fn().mockResolvedValue({
|
|
373
|
+
data: {
|
|
374
|
+
'atomic:results': []
|
|
375
|
+
}
|
|
376
|
+
})
|
|
377
|
+
});
|
|
367
378
|
coreApi.deleteFile.mockResolvedValue({});
|
|
368
379
|
coreApi.deleteRecord.mockResolvedValue({});
|
|
369
380
|
coreApi.findRecord.mockResolvedValue({
|
|
@@ -381,6 +392,645 @@ describe('useCreateReferrals', () => {
|
|
|
381
392
|
}
|
|
382
393
|
});
|
|
383
394
|
});
|
|
395
|
+
it('creates a new referral group in one atomic operation when enabled', async () => {
|
|
396
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
397
|
+
const atomicOperations = jest.fn().mockResolvedValue({
|
|
398
|
+
data: {
|
|
399
|
+
'atomic:results': [{
|
|
400
|
+
data: {
|
|
401
|
+
id: 'case1',
|
|
402
|
+
description: 'Test Case'
|
|
403
|
+
}
|
|
404
|
+
}, {
|
|
405
|
+
data: {
|
|
406
|
+
id: 'referral1',
|
|
407
|
+
state: 'sent'
|
|
408
|
+
}
|
|
409
|
+
}]
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
useAtomicOperations.mockReturnValue({
|
|
413
|
+
atomicOperations
|
|
414
|
+
});
|
|
415
|
+
setupMocks(referrals);
|
|
416
|
+
const {
|
|
417
|
+
result
|
|
418
|
+
} = renderHook(() => useCreateReferrals());
|
|
419
|
+
await act(async () => {
|
|
420
|
+
const response = await result.current({
|
|
421
|
+
draft: false
|
|
422
|
+
});
|
|
423
|
+
expect(response).toEqual({
|
|
424
|
+
cases: [{
|
|
425
|
+
id: 'case1',
|
|
426
|
+
description: 'Test Case'
|
|
427
|
+
}],
|
|
428
|
+
referrals: [{
|
|
429
|
+
id: 'referral1',
|
|
430
|
+
state: 'sent',
|
|
431
|
+
referralIndex: 0
|
|
432
|
+
}],
|
|
433
|
+
shippingDetail: [{
|
|
434
|
+
id: 'referral-result-0',
|
|
435
|
+
index: 0,
|
|
436
|
+
sent: true,
|
|
437
|
+
error: null,
|
|
438
|
+
caseId: 'case1',
|
|
439
|
+
attachmentStatus: 'not_requested',
|
|
440
|
+
attachmentErrors: [],
|
|
441
|
+
rawAtomicErrors: null
|
|
442
|
+
}],
|
|
443
|
+
referralsToConsent: [{
|
|
444
|
+
programNames: ['Unknown Program'],
|
|
445
|
+
referrals: ['referral1'],
|
|
446
|
+
serviceName: 'Unknown Service'
|
|
447
|
+
}]
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
expect(atomicOperations).toHaveBeenCalledTimes(1);
|
|
451
|
+
const submittedOperations = atomicOperations.mock.calls[0][0];
|
|
452
|
+
expect(submittedOperations).toHaveLength(2);
|
|
453
|
+
const [caseOp, referralOp] = submittedOperations;
|
|
454
|
+
expect(caseOp).toMatchObject({
|
|
455
|
+
op: 'add',
|
|
456
|
+
model: 'case',
|
|
457
|
+
lid: 'case-0'
|
|
458
|
+
});
|
|
459
|
+
expect(referralOp).toMatchObject({
|
|
460
|
+
op: 'add',
|
|
461
|
+
model: 'referral',
|
|
462
|
+
data: expect.objectContaining({
|
|
463
|
+
case: {
|
|
464
|
+
lid: 'case-0'
|
|
465
|
+
},
|
|
466
|
+
receiving_program: 'program1'
|
|
467
|
+
})
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
it('includes existing documents in the atomic request without calling setRelationship', async () => {
|
|
471
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
472
|
+
const referralWithExistingDocument = [createBaseReferral({
|
|
473
|
+
attachableDocuments: [{
|
|
474
|
+
attached: true,
|
|
475
|
+
document: {
|
|
476
|
+
id: 'existing-doc-1',
|
|
477
|
+
title: 'Existing Document'
|
|
478
|
+
}
|
|
479
|
+
}]
|
|
480
|
+
})];
|
|
481
|
+
const atomicOperations = jest.fn().mockResolvedValue({
|
|
482
|
+
data: {
|
|
483
|
+
'atomic:results': [{
|
|
484
|
+
data: {
|
|
485
|
+
id: 'case1',
|
|
486
|
+
description: 'Test Case'
|
|
487
|
+
}
|
|
488
|
+
}, {
|
|
489
|
+
data: {
|
|
490
|
+
id: 'referral1',
|
|
491
|
+
state: 'sent'
|
|
492
|
+
}
|
|
493
|
+
}, {}]
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
useAtomicOperations.mockReturnValue({
|
|
497
|
+
atomicOperations
|
|
498
|
+
});
|
|
499
|
+
setupMocks(referralWithExistingDocument);
|
|
500
|
+
const {
|
|
501
|
+
result
|
|
502
|
+
} = renderHook(() => useCreateReferrals());
|
|
503
|
+
await act(async () => {
|
|
504
|
+
await result.current({
|
|
505
|
+
draft: false
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
const submittedOperations = atomicOperations.mock.calls[0][0];
|
|
509
|
+
expect(submittedOperations).toHaveLength(3);
|
|
510
|
+
expect(coreApi.setRelationship).not.toHaveBeenCalled();
|
|
511
|
+
const [caseOp, referralOp, relationshipOp] = submittedOperations;
|
|
512
|
+
expect(caseOp).toMatchObject({
|
|
513
|
+
op: 'add',
|
|
514
|
+
model: 'case',
|
|
515
|
+
lid: 'case-0'
|
|
516
|
+
});
|
|
517
|
+
expect(referralOp).toMatchObject({
|
|
518
|
+
op: 'add',
|
|
519
|
+
model: 'referral',
|
|
520
|
+
data: expect.objectContaining({
|
|
521
|
+
case: {
|
|
522
|
+
lid: 'case-0'
|
|
523
|
+
}
|
|
524
|
+
})
|
|
525
|
+
});
|
|
526
|
+
expect(relationshipOp).toMatchObject({
|
|
527
|
+
op: 'add',
|
|
528
|
+
model: 'case',
|
|
529
|
+
lid: 'case-0',
|
|
530
|
+
relationship: 'file_uploads',
|
|
531
|
+
relationshipModel: 'file_upload',
|
|
532
|
+
value: ['existing-doc-1']
|
|
533
|
+
});
|
|
534
|
+
});
|
|
535
|
+
it('does not upload attachments when the atomic referral group fails', async () => {
|
|
536
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
537
|
+
const pendingFile = {
|
|
538
|
+
name: 'pending.pdf',
|
|
539
|
+
type: 'application/pdf'
|
|
540
|
+
};
|
|
541
|
+
const referralWithAttachment = [createBaseReferral({
|
|
542
|
+
pendingAttachments: [{
|
|
543
|
+
tempId: 'file-1',
|
|
544
|
+
file: pendingFile
|
|
545
|
+
}]
|
|
546
|
+
})];
|
|
547
|
+
const atomicOperations = jest.fn().mockRejectedValue({
|
|
548
|
+
response: {
|
|
549
|
+
data: {
|
|
550
|
+
errors: [{
|
|
551
|
+
title: 'Referral operation failed'
|
|
552
|
+
}]
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
useAtomicOperations.mockReturnValue({
|
|
557
|
+
atomicOperations
|
|
558
|
+
});
|
|
559
|
+
setupMocks(referralWithAttachment);
|
|
560
|
+
const {
|
|
561
|
+
result
|
|
562
|
+
} = renderHook(() => useCreateReferrals());
|
|
563
|
+
let response;
|
|
564
|
+
await act(async () => {
|
|
565
|
+
response = await result.current({
|
|
566
|
+
draft: false
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
expect(response).toMatchObject({
|
|
570
|
+
cases: [],
|
|
571
|
+
referrals: [],
|
|
572
|
+
shippingDetail: [{
|
|
573
|
+
sent: false,
|
|
574
|
+
error: 'Error creating the Referral: Referral operation failed',
|
|
575
|
+
caseId: null,
|
|
576
|
+
attachmentStatus: 'not_requested'
|
|
577
|
+
}]
|
|
578
|
+
});
|
|
579
|
+
expect(coreApi.uploadFile).not.toHaveBeenCalled();
|
|
580
|
+
const submittedOperations = atomicOperations.mock.calls[0][0];
|
|
581
|
+
expect(submittedOperations).toHaveLength(2);
|
|
582
|
+
const [caseOp, referralOp] = submittedOperations;
|
|
583
|
+
expect(caseOp).toMatchObject({
|
|
584
|
+
op: 'add',
|
|
585
|
+
model: 'case',
|
|
586
|
+
lid: 'case-0'
|
|
587
|
+
});
|
|
588
|
+
expect(referralOp).toMatchObject({
|
|
589
|
+
op: 'add',
|
|
590
|
+
model: 'referral',
|
|
591
|
+
data: expect.objectContaining({
|
|
592
|
+
case: {
|
|
593
|
+
lid: 'case-0'
|
|
594
|
+
}
|
|
595
|
+
})
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
it('includes service_authorization in atomic operations when authorization is required', async () => {
|
|
599
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
600
|
+
const referralWithAuth = [createBaseReferral({
|
|
601
|
+
paymentAuthForm: {
|
|
602
|
+
amount_requested: 500,
|
|
603
|
+
service_start: 1724500000,
|
|
604
|
+
service_end: 1727100000
|
|
605
|
+
},
|
|
606
|
+
programs: [{
|
|
607
|
+
id: 'program1',
|
|
608
|
+
provider: {
|
|
609
|
+
id: 'provider1',
|
|
610
|
+
licensed: true
|
|
611
|
+
},
|
|
612
|
+
fee_schedule_program: {
|
|
613
|
+
id: 'fsp-1',
|
|
614
|
+
authorization_required: true,
|
|
615
|
+
payment_type: 'fee_for_service',
|
|
616
|
+
fee_schedule: {
|
|
617
|
+
id: 'fee-schedule-1'
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}]
|
|
621
|
+
})];
|
|
622
|
+
const atomicOperations = jest.fn().mockResolvedValue({
|
|
623
|
+
data: {
|
|
624
|
+
'atomic:results': [{
|
|
625
|
+
data: {
|
|
626
|
+
id: 'case1',
|
|
627
|
+
description: 'Test Case'
|
|
628
|
+
}
|
|
629
|
+
}, {
|
|
630
|
+
data: {
|
|
631
|
+
id: 'auth1',
|
|
632
|
+
state: 'requested'
|
|
633
|
+
}
|
|
634
|
+
}, {
|
|
635
|
+
data: {
|
|
636
|
+
id: 'referral1',
|
|
637
|
+
state: 'pending_authorization'
|
|
638
|
+
}
|
|
639
|
+
}]
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
useAtomicOperations.mockReturnValue({
|
|
643
|
+
atomicOperations
|
|
644
|
+
});
|
|
645
|
+
setupMocks(referralWithAuth);
|
|
646
|
+
coreApi.query.mockResolvedValue({
|
|
647
|
+
data: {
|
|
648
|
+
data: [{
|
|
649
|
+
id: 'insurance-1'
|
|
650
|
+
}]
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
const {
|
|
654
|
+
result
|
|
655
|
+
} = renderHook(() => useCreateReferrals());
|
|
656
|
+
let response;
|
|
657
|
+
await act(async () => {
|
|
658
|
+
response = await result.current({
|
|
659
|
+
draft: false
|
|
660
|
+
});
|
|
661
|
+
});
|
|
662
|
+
expect(response.referrals[0]).toMatchObject({
|
|
663
|
+
id: 'referral1',
|
|
664
|
+
state: 'pending_authorization'
|
|
665
|
+
});
|
|
666
|
+
expect(atomicOperations).toHaveBeenCalledTimes(1);
|
|
667
|
+
const submittedOperations = atomicOperations.mock.calls[0][0];
|
|
668
|
+
expect(submittedOperations).toHaveLength(3);
|
|
669
|
+
const [caseOp, authOp, referralOp] = submittedOperations;
|
|
670
|
+
expect(caseOp).toMatchObject({
|
|
671
|
+
op: 'add',
|
|
672
|
+
model: 'case'
|
|
673
|
+
});
|
|
674
|
+
expect(authOp).toMatchObject({
|
|
675
|
+
op: 'add',
|
|
676
|
+
model: 'service_authorization',
|
|
677
|
+
data: expect.objectContaining({
|
|
678
|
+
case: {
|
|
679
|
+
lid: 'case-0'
|
|
680
|
+
},
|
|
681
|
+
fee_schedule_program: 'fsp-1',
|
|
682
|
+
insurance: 'insurance-1',
|
|
683
|
+
state: 'requested'
|
|
684
|
+
})
|
|
685
|
+
});
|
|
686
|
+
expect(referralOp).toMatchObject({
|
|
687
|
+
op: 'add',
|
|
688
|
+
model: 'referral',
|
|
689
|
+
data: expect.objectContaining({
|
|
690
|
+
case: {
|
|
691
|
+
lid: 'case-0'
|
|
692
|
+
},
|
|
693
|
+
state: 'pending_authorization'
|
|
694
|
+
})
|
|
695
|
+
});
|
|
696
|
+
});
|
|
697
|
+
it('does not submit atomic operations when referral values are missing', async () => {
|
|
698
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
699
|
+
const atomicOperations = jest.fn();
|
|
700
|
+
const referralWithoutProgramId = [createBaseReferral({
|
|
701
|
+
programs: [{
|
|
702
|
+
provider: {
|
|
703
|
+
id: 'provider1',
|
|
704
|
+
licensed: true
|
|
705
|
+
}
|
|
706
|
+
}]
|
|
707
|
+
})];
|
|
708
|
+
useAtomicOperations.mockReturnValue({
|
|
709
|
+
atomicOperations
|
|
710
|
+
});
|
|
711
|
+
setupMocks(referralWithoutProgramId);
|
|
712
|
+
const {
|
|
713
|
+
result
|
|
714
|
+
} = renderHook(() => useCreateReferrals());
|
|
715
|
+
let response;
|
|
716
|
+
await act(async () => {
|
|
717
|
+
response = await result.current({
|
|
718
|
+
draft: false
|
|
719
|
+
});
|
|
720
|
+
});
|
|
721
|
+
expect(atomicOperations).not.toHaveBeenCalled();
|
|
722
|
+
expect(response.shippingDetail[0]).toMatchObject({
|
|
723
|
+
sent: false,
|
|
724
|
+
error: 'The following fields for the referral are required: receiving_program',
|
|
725
|
+
caseId: null
|
|
726
|
+
});
|
|
727
|
+
});
|
|
728
|
+
it('creates multiple referrals in one atomic operation for grouped referrals', async () => {
|
|
729
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
730
|
+
const groupedReferral = [createBaseReferral({
|
|
731
|
+
programs: [{
|
|
732
|
+
id: 'program1',
|
|
733
|
+
provider: {
|
|
734
|
+
id: 'provider1',
|
|
735
|
+
licensed: true
|
|
736
|
+
}
|
|
737
|
+
}, {
|
|
738
|
+
id: 'program2',
|
|
739
|
+
provider: {
|
|
740
|
+
id: 'provider2',
|
|
741
|
+
licensed: true
|
|
742
|
+
}
|
|
743
|
+
}, {
|
|
744
|
+
id: 'program3',
|
|
745
|
+
provider: {
|
|
746
|
+
id: 'provider3',
|
|
747
|
+
licensed: true
|
|
748
|
+
}
|
|
749
|
+
}]
|
|
750
|
+
})];
|
|
751
|
+
const atomicOperations = jest.fn().mockResolvedValue({
|
|
752
|
+
data: {
|
|
753
|
+
'atomic:results': [{
|
|
754
|
+
data: {
|
|
755
|
+
id: 'case1',
|
|
756
|
+
description: 'Test Case'
|
|
757
|
+
}
|
|
758
|
+
}, {
|
|
759
|
+
data: {
|
|
760
|
+
id: 'referral1',
|
|
761
|
+
state: 'sent'
|
|
762
|
+
}
|
|
763
|
+
}, {
|
|
764
|
+
data: {
|
|
765
|
+
id: 'referral2',
|
|
766
|
+
state: 'sent'
|
|
767
|
+
}
|
|
768
|
+
}, {
|
|
769
|
+
data: {
|
|
770
|
+
id: 'referral3',
|
|
771
|
+
state: 'sent'
|
|
772
|
+
}
|
|
773
|
+
}]
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
useAtomicOperations.mockReturnValue({
|
|
777
|
+
atomicOperations
|
|
778
|
+
});
|
|
779
|
+
setupMocks(groupedReferral);
|
|
780
|
+
const {
|
|
781
|
+
result
|
|
782
|
+
} = renderHook(() => useCreateReferrals());
|
|
783
|
+
let response;
|
|
784
|
+
await act(async () => {
|
|
785
|
+
response = await result.current({
|
|
786
|
+
draft: false
|
|
787
|
+
});
|
|
788
|
+
});
|
|
789
|
+
expect(atomicOperations).toHaveBeenCalledTimes(1);
|
|
790
|
+
const submittedOperations = atomicOperations.mock.calls[0][0];
|
|
791
|
+
expect(submittedOperations).toHaveLength(4);
|
|
792
|
+
const [caseOp, ...referralOps] = submittedOperations;
|
|
793
|
+
expect(caseOp).toMatchObject({
|
|
794
|
+
op: 'add',
|
|
795
|
+
model: 'case'
|
|
796
|
+
});
|
|
797
|
+
referralOps.forEach((op, idx) => {
|
|
798
|
+
expect(op).toMatchObject({
|
|
799
|
+
op: 'add',
|
|
800
|
+
model: 'referral',
|
|
801
|
+
data: expect.objectContaining({
|
|
802
|
+
case: {
|
|
803
|
+
lid: 'case-0'
|
|
804
|
+
},
|
|
805
|
+
is_grouped: true,
|
|
806
|
+
receiving_program: `program${idx + 1}`
|
|
807
|
+
})
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
expect(response.referrals).toHaveLength(3);
|
|
811
|
+
expect(response.referrals.map(r => r.id)).toEqual(['referral1', 'referral2', 'referral3']);
|
|
812
|
+
expect(response.cases).toHaveLength(1);
|
|
813
|
+
});
|
|
814
|
+
it('stashes the raw atomic errors on the shipping detail without changing the user-facing message', async () => {
|
|
815
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
816
|
+
const rawErrors = [{
|
|
817
|
+
title: 'Referral operation failed',
|
|
818
|
+
source: {
|
|
819
|
+
pointer: '/atomic:operations/1'
|
|
820
|
+
}
|
|
821
|
+
}];
|
|
822
|
+
const atomicOperations = jest.fn().mockRejectedValue({
|
|
823
|
+
response: {
|
|
824
|
+
data: {
|
|
825
|
+
errors: rawErrors
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
useAtomicOperations.mockReturnValue({
|
|
830
|
+
atomicOperations
|
|
831
|
+
});
|
|
832
|
+
setupMocks(referrals);
|
|
833
|
+
const {
|
|
834
|
+
result
|
|
835
|
+
} = renderHook(() => useCreateReferrals());
|
|
836
|
+
let response;
|
|
837
|
+
await act(async () => {
|
|
838
|
+
response = await result.current({
|
|
839
|
+
draft: false
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
expect(response.shippingDetail[0]).toMatchObject({
|
|
843
|
+
error: 'Error creating the Referral: Referral operation failed',
|
|
844
|
+
rawAtomicErrors: rawErrors
|
|
845
|
+
});
|
|
846
|
+
});
|
|
847
|
+
it('does not corrupt later groups when an earlier atomic group fails mid-batch', async () => {
|
|
848
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
849
|
+
const twoReferrals = [createBaseReferral({
|
|
850
|
+
description: 'Failing referral'
|
|
851
|
+
}), createBaseReferral({
|
|
852
|
+
description: 'Succeeding referral'
|
|
853
|
+
})];
|
|
854
|
+
const atomicOperations = jest.fn().mockRejectedValueOnce({
|
|
855
|
+
response: {
|
|
856
|
+
data: {
|
|
857
|
+
errors: [{
|
|
858
|
+
title: 'Referral operation failed'
|
|
859
|
+
}]
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}).mockResolvedValueOnce({
|
|
863
|
+
data: {
|
|
864
|
+
'atomic:results': [{
|
|
865
|
+
data: {
|
|
866
|
+
id: 'case2',
|
|
867
|
+
description: 'Test Case'
|
|
868
|
+
}
|
|
869
|
+
}, {
|
|
870
|
+
data: {
|
|
871
|
+
id: 'referral2',
|
|
872
|
+
state: 'sent'
|
|
873
|
+
}
|
|
874
|
+
}]
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
useAtomicOperations.mockReturnValue({
|
|
878
|
+
atomicOperations
|
|
879
|
+
});
|
|
880
|
+
setupMocks(twoReferrals);
|
|
881
|
+
const {
|
|
882
|
+
result
|
|
883
|
+
} = renderHook(() => useCreateReferrals());
|
|
884
|
+
let response;
|
|
885
|
+
await act(async () => {
|
|
886
|
+
response = await result.current({
|
|
887
|
+
draft: false
|
|
888
|
+
});
|
|
889
|
+
});
|
|
890
|
+
expect(atomicOperations).toHaveBeenCalledTimes(2);
|
|
891
|
+
expect(response.shippingDetail[0]).toMatchObject({
|
|
892
|
+
sent: false,
|
|
893
|
+
error: 'Error creating the Referral: Referral operation failed',
|
|
894
|
+
caseId: null
|
|
895
|
+
});
|
|
896
|
+
expect(response.shippingDetail[1]).toMatchObject({
|
|
897
|
+
sent: true,
|
|
898
|
+
caseId: 'case2',
|
|
899
|
+
error: null
|
|
900
|
+
});
|
|
901
|
+
expect(response.cases).toEqual([{
|
|
902
|
+
id: 'case2',
|
|
903
|
+
description: 'Test Case'
|
|
904
|
+
}]);
|
|
905
|
+
expect(response.referrals).toEqual([{
|
|
906
|
+
id: 'referral2',
|
|
907
|
+
state: 'sent',
|
|
908
|
+
referralIndex: 1
|
|
909
|
+
}]);
|
|
910
|
+
});
|
|
911
|
+
it('uploads only the pending attachments on the atomic path', async () => {
|
|
912
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
913
|
+
const pendingFile = {
|
|
914
|
+
name: 'pending.pdf',
|
|
915
|
+
type: 'application/pdf'
|
|
916
|
+
};
|
|
917
|
+
const referralWithAttachment = [createBaseReferral({
|
|
918
|
+
pendingAttachments: [{
|
|
919
|
+
tempId: 'file-1',
|
|
920
|
+
file: pendingFile
|
|
921
|
+
}]
|
|
922
|
+
})];
|
|
923
|
+
const atomicOperations = jest.fn().mockResolvedValue({
|
|
924
|
+
data: {
|
|
925
|
+
'atomic:results': [{
|
|
926
|
+
data: {
|
|
927
|
+
id: 'case1',
|
|
928
|
+
description: 'Test Case'
|
|
929
|
+
}
|
|
930
|
+
}, {
|
|
931
|
+
data: {
|
|
932
|
+
id: 'referral1',
|
|
933
|
+
state: 'sent'
|
|
934
|
+
}
|
|
935
|
+
}]
|
|
936
|
+
}
|
|
937
|
+
});
|
|
938
|
+
useAtomicOperations.mockReturnValue({
|
|
939
|
+
atomicOperations
|
|
940
|
+
});
|
|
941
|
+
setupMocks(referralWithAttachment);
|
|
942
|
+
const {
|
|
943
|
+
result
|
|
944
|
+
} = renderHook(() => useCreateReferrals());
|
|
945
|
+
await act(async () => {
|
|
946
|
+
await result.current({
|
|
947
|
+
draft: false
|
|
948
|
+
});
|
|
949
|
+
});
|
|
950
|
+
expect(coreApi.uploadFile).toHaveBeenCalledTimes(1);
|
|
951
|
+
expect(coreApi.uploadFile).toHaveBeenCalledWith('case', 'case1', pendingFile);
|
|
952
|
+
});
|
|
953
|
+
it('reports the upload failure separately while the referral stays successful', async () => {
|
|
954
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
955
|
+
const pendingFile = {
|
|
956
|
+
name: 'pending.pdf',
|
|
957
|
+
type: 'application/pdf'
|
|
958
|
+
};
|
|
959
|
+
const referralWithAttachment = [createBaseReferral({
|
|
960
|
+
pendingAttachments: [{
|
|
961
|
+
tempId: 'file-1',
|
|
962
|
+
file: pendingFile
|
|
963
|
+
}]
|
|
964
|
+
})];
|
|
965
|
+
const atomicOperations = jest.fn().mockResolvedValue({
|
|
966
|
+
data: {
|
|
967
|
+
'atomic:results': [{
|
|
968
|
+
data: {
|
|
969
|
+
id: 'case1',
|
|
970
|
+
description: 'Test Case'
|
|
971
|
+
}
|
|
972
|
+
}, {
|
|
973
|
+
data: {
|
|
974
|
+
id: 'referral1',
|
|
975
|
+
state: 'sent'
|
|
976
|
+
}
|
|
977
|
+
}]
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
useAtomicOperations.mockReturnValue({
|
|
981
|
+
atomicOperations
|
|
982
|
+
});
|
|
983
|
+
setupMocks(referralWithAttachment);
|
|
984
|
+
coreApi.uploadFile.mockRejectedValue(new Error('Upload failed'));
|
|
985
|
+
const {
|
|
986
|
+
result
|
|
987
|
+
} = renderHook(() => useCreateReferrals());
|
|
988
|
+
let response;
|
|
989
|
+
await act(async () => {
|
|
990
|
+
response = await result.current({
|
|
991
|
+
draft: false
|
|
992
|
+
});
|
|
993
|
+
});
|
|
994
|
+
expect(response.shippingDetail[0]).toMatchObject({
|
|
995
|
+
sent: true,
|
|
996
|
+
caseId: 'case1',
|
|
997
|
+
attachmentStatus: 'failed'
|
|
998
|
+
});
|
|
999
|
+
expect(response.referrals).toEqual([{
|
|
1000
|
+
id: 'referral1',
|
|
1001
|
+
state: 'sent',
|
|
1002
|
+
referralIndex: 0
|
|
1003
|
+
}]);
|
|
1004
|
+
});
|
|
1005
|
+
it('does not fall back to legacy create/update calls when an atomic group fails', async () => {
|
|
1006
|
+
FEATURE_FLAGS.pays11587AtomicReferralCreation = true;
|
|
1007
|
+
const atomicOperations = jest.fn().mockRejectedValue({
|
|
1008
|
+
response: {
|
|
1009
|
+
data: {
|
|
1010
|
+
errors: [{
|
|
1011
|
+
title: 'Referral operation failed'
|
|
1012
|
+
}]
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
useAtomicOperations.mockReturnValue({
|
|
1017
|
+
atomicOperations
|
|
1018
|
+
});
|
|
1019
|
+
setupMocks(referrals);
|
|
1020
|
+
const createRecord = jest.fn();
|
|
1021
|
+
useCreateRecord.mockReturnValue({
|
|
1022
|
+
createRecord
|
|
1023
|
+
});
|
|
1024
|
+
const {
|
|
1025
|
+
result
|
|
1026
|
+
} = renderHook(() => useCreateReferrals());
|
|
1027
|
+
await act(async () => {
|
|
1028
|
+
await result.current({
|
|
1029
|
+
draft: false
|
|
1030
|
+
});
|
|
1031
|
+
});
|
|
1032
|
+
expect(createRecord).not.toHaveBeenCalled();
|
|
1033
|
+
});
|
|
384
1034
|
it('should validate response structure no matters the result', async () => {
|
|
385
1035
|
useAppCreateReferralContext.mockReturnValue({
|
|
386
1036
|
dispatch: mockDispatch,
|
|
@@ -519,7 +1169,8 @@ describe('useCreateReferrals', () => {
|
|
|
519
1169
|
error: null,
|
|
520
1170
|
caseId: 'case1',
|
|
521
1171
|
attachmentStatus: 'not_requested',
|
|
522
|
-
attachmentErrors: []
|
|
1172
|
+
attachmentErrors: [],
|
|
1173
|
+
rawAtomicErrors: null
|
|
523
1174
|
}],
|
|
524
1175
|
referralsToConsent: [{
|
|
525
1176
|
programNames: ['Unknown Program'],
|
|
@@ -608,7 +1259,8 @@ describe('useCreateReferrals', () => {
|
|
|
608
1259
|
error: null,
|
|
609
1260
|
caseId: 'case1',
|
|
610
1261
|
attachmentStatus: 'not_requested',
|
|
611
|
-
attachmentErrors: []
|
|
1262
|
+
attachmentErrors: [],
|
|
1263
|
+
rawAtomicErrors: null
|
|
612
1264
|
}, {
|
|
613
1265
|
id: 'referral-result-1',
|
|
614
1266
|
index: 1,
|
|
@@ -616,7 +1268,8 @@ describe('useCreateReferrals', () => {
|
|
|
616
1268
|
error: 'Unexpected error: The following fields for the case are required: description',
|
|
617
1269
|
caseId: null,
|
|
618
1270
|
attachmentStatus: 'not_requested',
|
|
619
|
-
attachmentErrors: []
|
|
1271
|
+
attachmentErrors: [],
|
|
1272
|
+
rawAtomicErrors: null
|
|
620
1273
|
}],
|
|
621
1274
|
referralsToConsent: [{
|
|
622
1275
|
programNames: ['Unknown Program'],
|
|
@@ -666,7 +1319,8 @@ describe('useCreateReferrals', () => {
|
|
|
666
1319
|
error: 'Unexpected error: The following fields for the case are required: description',
|
|
667
1320
|
caseId: null,
|
|
668
1321
|
attachmentStatus: 'not_requested',
|
|
669
|
-
attachmentErrors: []
|
|
1322
|
+
attachmentErrors: [],
|
|
1323
|
+
rawAtomicErrors: null
|
|
670
1324
|
}, {
|
|
671
1325
|
id: 'referral-result-1',
|
|
672
1326
|
index: 1,
|
|
@@ -674,7 +1328,8 @@ describe('useCreateReferrals', () => {
|
|
|
674
1328
|
error: 'Unexpected error: The following fields for the case are required: description',
|
|
675
1329
|
caseId: null,
|
|
676
1330
|
attachmentStatus: 'not_requested',
|
|
677
|
-
attachmentErrors: []
|
|
1331
|
+
attachmentErrors: [],
|
|
1332
|
+
rawAtomicErrors: null
|
|
678
1333
|
}],
|
|
679
1334
|
referralsToConsent: []
|
|
680
1335
|
});
|
|
@@ -721,7 +1376,8 @@ describe('useCreateReferrals', () => {
|
|
|
721
1376
|
error: null,
|
|
722
1377
|
caseId: 'case1',
|
|
723
1378
|
attachmentStatus: 'not_requested',
|
|
724
|
-
attachmentErrors: []
|
|
1379
|
+
attachmentErrors: [],
|
|
1380
|
+
rawAtomicErrors: null
|
|
725
1381
|
}],
|
|
726
1382
|
referralsToConsent: []
|
|
727
1383
|
});
|