@redacto.io/consent-sdk-react 9.2.0 → 9.3.0-beta.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/.turbo/turbo-build.log +25 -26
- package/.turbo/turbo-test.log +203 -0
- package/.turbo/turbo-verify-pack.log +6 -0
- package/CHANGELOG.md +12 -0
- package/dist/privacy-center.js +3242 -2956
- package/dist/privacy-center.mjs +3068 -2774
- package/package.json +3 -3
- package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +6 -3
- package/src/RedactoPrivacyCenter/components/AppShell/AppShell.tsx +36 -5
- package/src/RedactoPrivacyCenter/components/AppShell/TopAppBar.tsx +3 -2
- package/src/RedactoPrivacyCenter/components/Form.tsx +127 -8
- package/src/RedactoPrivacyCenter/components/PrivacyCenterEmptyState.tsx +76 -0
- package/src/RedactoPrivacyCenter/components/ReceiptsList.tsx +3 -41
- package/src/RedactoPrivacyCenter/context/DataAvailabilityContext.tsx +169 -0
- package/src/RedactoPrivacyCenter/locales/as/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/bho/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/bn/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/brx/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/doi/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/en/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/gom/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/gu/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/hi/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/kn/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/ks/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/mai/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/ml/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/mr/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/ne/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/or/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/pa/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/sa/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/sat/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/sd/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/ta/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/te/translation.json +2 -0
- package/src/RedactoPrivacyCenter/locales/ur/translation.json +2 -0
- package/src/RedactoPrivacyCenter/styles/injectStyles.ts +1 -1
- package/tests/DataAvailabilityContext.test.tsx +123 -0
- package/tests/Form.test.tsx +93 -1
package/tests/Form.test.tsx
CHANGED
|
@@ -694,6 +694,13 @@ describe('Form (P2-SDK-3)', () => {
|
|
|
694
694
|
fireEvent.click(submitButton);
|
|
695
695
|
});
|
|
696
696
|
|
|
697
|
+
// ERASURE asks whether to also revoke consent before it submits.
|
|
698
|
+
// Choosing "Yes" (revokeConsentYes) sets revoke_consent_on_fulfilment=true.
|
|
699
|
+
const revokeYesButton = await screen.findByRole('button', { name: 'Yes' });
|
|
700
|
+
await act(async () => {
|
|
701
|
+
fireEvent.click(revokeYesButton);
|
|
702
|
+
});
|
|
703
|
+
|
|
697
704
|
await waitFor(() => {
|
|
698
705
|
expect(createCaseRequest).toHaveBeenCalledTimes(1);
|
|
699
706
|
});
|
|
@@ -703,7 +710,7 @@ describe('Form (P2-SDK-3)', () => {
|
|
|
703
710
|
expect('data_principal_uuid' in payload).toBe(false);
|
|
704
711
|
expect(payload.uuid).toBe('form-session-uuid');
|
|
705
712
|
expect(payload.request_type).toBe('erasure');
|
|
706
|
-
//
|
|
713
|
+
// The user chose "Yes" in the consent-revoke modal, so the backend's
|
|
707
714
|
// auto-revoke task fires when the case is fulfilled (DPDPA Sec 12:
|
|
708
715
|
// erasing data implies revoking the consent that authorized
|
|
709
716
|
// processing it).
|
|
@@ -714,6 +721,86 @@ describe('Form (P2-SDK-3)', () => {
|
|
|
714
721
|
});
|
|
715
722
|
});
|
|
716
723
|
|
|
724
|
+
it('opens the consent-revoke modal on erasure and sends revoke_consent_on_fulfilment=false when the user declines', async () => {
|
|
725
|
+
setupSession();
|
|
726
|
+
const directGroup = makeGroup({
|
|
727
|
+
product_uuid: 'prod-direct',
|
|
728
|
+
product_name: 'Acme Loyalty',
|
|
729
|
+
purposes: [basePurpose('purp-direct', 'Marketing')],
|
|
730
|
+
});
|
|
731
|
+
const nominatedGroup = makeGroup({
|
|
732
|
+
product_uuid: 'prod-nominated',
|
|
733
|
+
product_name: 'Partner Bank',
|
|
734
|
+
nominator: {
|
|
735
|
+
uuid: 'nominator-uuid',
|
|
736
|
+
org_user_id: 'org-user-1',
|
|
737
|
+
name: 'Alice',
|
|
738
|
+
email: 'alice@example.com',
|
|
739
|
+
},
|
|
740
|
+
purposes: [basePurpose('purp-nominated', 'Analytics')],
|
|
741
|
+
});
|
|
742
|
+
getFormData.mockResolvedValue(
|
|
743
|
+
makeFormData({
|
|
744
|
+
direct_groups: [directGroup],
|
|
745
|
+
nominated_groups: [nominatedGroup],
|
|
746
|
+
}),
|
|
747
|
+
);
|
|
748
|
+
createCaseRequest.mockResolvedValueOnce({
|
|
749
|
+
case_id: 'CASE-2',
|
|
750
|
+
uuid: 'uuid-2',
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
render(<Form onCreateRequest={vi.fn()} />);
|
|
754
|
+
await waitFor(() => expect(getFormData).toHaveBeenCalled());
|
|
755
|
+
|
|
756
|
+
pickRequestType(RequestTypeEnum.ERASURE);
|
|
757
|
+
|
|
758
|
+
await waitFor(() =>
|
|
759
|
+
expect(screen.getByText('Acme Loyalty')).toBeInTheDocument(),
|
|
760
|
+
);
|
|
761
|
+
clickProductChip('prod-direct');
|
|
762
|
+
|
|
763
|
+
await waitFor(() => {
|
|
764
|
+
expect(
|
|
765
|
+
screen.getByTestId('per-product-purposes-prod-direct'),
|
|
766
|
+
).toBeInTheDocument();
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
const marketingCheckbox = screen
|
|
770
|
+
.getByText('Marketing')
|
|
771
|
+
.closest('label')
|
|
772
|
+
?.querySelector('input[type="checkbox"]') as HTMLInputElement | null;
|
|
773
|
+
expect(marketingCheckbox).toBeTruthy();
|
|
774
|
+
fireEvent.click(marketingCheckbox!);
|
|
775
|
+
|
|
776
|
+
const confirmCheckbox = (
|
|
777
|
+
screen.getAllByRole('checkbox') as HTMLInputElement[]
|
|
778
|
+
).find((c) => c.closest('label')?.textContent?.includes('I confirm'));
|
|
779
|
+
expect(confirmCheckbox).toBeTruthy();
|
|
780
|
+
fireEvent.click(confirmCheckbox!);
|
|
781
|
+
|
|
782
|
+
await act(async () => {
|
|
783
|
+
fireEvent.click(screen.getByRole('button', { name: /^submit$/i }));
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
// The consent-revoke modal must appear, and no request fires until the
|
|
787
|
+
// user makes a choice. ('Revoke consent?' === revokeConsentModalTitle stub.)
|
|
788
|
+
expect(await screen.findByText('Revoke consent?')).toBeInTheDocument();
|
|
789
|
+
expect(createCaseRequest).not.toHaveBeenCalled();
|
|
790
|
+
|
|
791
|
+
// Declining ('No' === revokeConsentNo) submits with the flag explicitly false.
|
|
792
|
+
await act(async () => {
|
|
793
|
+
fireEvent.click(screen.getByRole('button', { name: 'No' }));
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
await waitFor(() => {
|
|
797
|
+
expect(createCaseRequest).toHaveBeenCalledTimes(1);
|
|
798
|
+
});
|
|
799
|
+
const payload = createCaseRequest.mock.calls[0][2];
|
|
800
|
+
expect(payload.request_type).toBe('erasure');
|
|
801
|
+
expect(payload.revoke_consent_on_fulfilment).toBe(false);
|
|
802
|
+
});
|
|
803
|
+
|
|
717
804
|
it('switches the inline purpose panel when another product chip is selected', async () => {
|
|
718
805
|
setupSession();
|
|
719
806
|
const creditCard = makeGroup({
|
|
@@ -1052,6 +1139,11 @@ describe('Form (P2-SDK-3)', () => {
|
|
|
1052
1139
|
fireEvent.click(screen.getByRole('button', { name: /^submit$/i }));
|
|
1053
1140
|
});
|
|
1054
1141
|
|
|
1142
|
+
// ERASURE routes through the consent-revoke modal before submitting.
|
|
1143
|
+
await act(async () => {
|
|
1144
|
+
fireEvent.click(await screen.findByRole('button', { name: 'Yes' }));
|
|
1145
|
+
});
|
|
1146
|
+
|
|
1055
1147
|
await waitFor(() => {
|
|
1056
1148
|
expect(createCaseRequest).toHaveBeenCalledTimes(1);
|
|
1057
1149
|
});
|