@tantainnovative/ndpr-toolkit 1.0.3 → 1.0.4

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 (156) hide show
  1. package/next-env.d.ts +5 -0
  2. package/package.json +1 -1
  3. package/.claude/settings.local.json +0 -20
  4. package/.eslintrc.json +0 -10
  5. package/.github/workflows/ci.yml +0 -36
  6. package/.github/workflows/nextjs.yml +0 -104
  7. package/.husky/commit-msg +0 -4
  8. package/.husky/pre-commit +0 -4
  9. package/.lintstagedrc.js +0 -4
  10. package/.nvmrc +0 -1
  11. package/.versionrc +0 -17
  12. package/CLAUDE.md +0 -90
  13. package/commitlint.config.js +0 -36
  14. package/eslint.config.mjs +0 -16
  15. package/jest.config.js +0 -31
  16. package/jest.setup.js +0 -15
  17. package/next.config.js +0 -15
  18. package/next.config.ts +0 -62
  19. package/packages/ndpr-toolkit/README.md +0 -467
  20. package/packages/ndpr-toolkit/jest.config.js +0 -23
  21. package/packages/ndpr-toolkit/package-lock.json +0 -8197
  22. package/packages/ndpr-toolkit/package.json +0 -71
  23. package/packages/ndpr-toolkit/rollup.config.js +0 -34
  24. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +0 -119
  25. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +0 -122
  26. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +0 -270
  27. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +0 -199
  28. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +0 -224
  29. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +0 -104
  30. package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +0 -161
  31. package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +0 -330
  32. package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +0 -149
  33. package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +0 -88
  34. package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +0 -160
  35. package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +0 -110
  36. package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +0 -97
  37. package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +0 -701
  38. package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +0 -631
  39. package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +0 -569
  40. package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +0 -496
  41. package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +0 -270
  42. package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +0 -217
  43. package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +0 -206
  44. package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +0 -342
  45. package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +0 -373
  46. package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +0 -174
  47. package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +0 -717
  48. package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +0 -476
  49. package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +0 -620
  50. package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +0 -541
  51. package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +0 -454
  52. package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +0 -333
  53. package/packages/ndpr-toolkit/src/hooks/useBreach.ts +0 -409
  54. package/packages/ndpr-toolkit/src/hooks/useConsent.ts +0 -263
  55. package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +0 -457
  56. package/packages/ndpr-toolkit/src/hooks/useDSR.ts +0 -236
  57. package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +0 -428
  58. package/packages/ndpr-toolkit/src/index.ts +0 -44
  59. package/packages/ndpr-toolkit/src/setupTests.ts +0 -5
  60. package/packages/ndpr-toolkit/src/types/breach.ts +0 -283
  61. package/packages/ndpr-toolkit/src/types/consent.ts +0 -111
  62. package/packages/ndpr-toolkit/src/types/dpia.ts +0 -236
  63. package/packages/ndpr-toolkit/src/types/dsr.ts +0 -192
  64. package/packages/ndpr-toolkit/src/types/index.ts +0 -42
  65. package/packages/ndpr-toolkit/src/types/privacy.ts +0 -246
  66. package/packages/ndpr-toolkit/src/utils/breach.ts +0 -122
  67. package/packages/ndpr-toolkit/src/utils/consent.ts +0 -51
  68. package/packages/ndpr-toolkit/src/utils/dpia.ts +0 -104
  69. package/packages/ndpr-toolkit/src/utils/dsr.ts +0 -77
  70. package/packages/ndpr-toolkit/src/utils/privacy.ts +0 -100
  71. package/packages/ndpr-toolkit/tsconfig.json +0 -23
  72. package/postcss.config.mjs +0 -5
  73. package/src/__tests__/example.test.ts +0 -13
  74. package/src/__tests__/requestService.test.ts +0 -57
  75. package/src/app/accessibility.css +0 -70
  76. package/src/app/docs/components/DocLayout.tsx +0 -267
  77. package/src/app/docs/components/breach-notification/page.tsx +0 -797
  78. package/src/app/docs/components/consent-management/page.tsx +0 -576
  79. package/src/app/docs/components/data-subject-rights/page.tsx +0 -511
  80. package/src/app/docs/components/dpia-questionnaire/layout.tsx +0 -15
  81. package/src/app/docs/components/dpia-questionnaire/metadata.ts +0 -31
  82. package/src/app/docs/components/dpia-questionnaire/page.tsx +0 -666
  83. package/src/app/docs/components/hooks/page.tsx +0 -305
  84. package/src/app/docs/components/page.tsx +0 -84
  85. package/src/app/docs/components/privacy-policy-generator/page.tsx +0 -634
  86. package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +0 -123
  87. package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +0 -328
  88. package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +0 -28
  89. package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +0 -91
  90. package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +0 -118
  91. package/src/app/docs/guides/breach-notification-process/page.tsx +0 -39
  92. package/src/app/docs/guides/conducting-dpia/page.tsx +0 -593
  93. package/src/app/docs/guides/data-subject-requests/page.tsx +0 -666
  94. package/src/app/docs/guides/managing-consent/page.tsx +0 -738
  95. package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +0 -296
  96. package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +0 -145
  97. package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +0 -33
  98. package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +0 -99
  99. package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +0 -159
  100. package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +0 -38
  101. package/src/app/docs/guides/page.tsx +0 -67
  102. package/src/app/docs/layout.tsx +0 -15
  103. package/src/app/docs/metadata.ts +0 -31
  104. package/src/app/docs/page.tsx +0 -572
  105. package/src/app/favicon.ico +0 -0
  106. package/src/app/globals.css +0 -123
  107. package/src/app/layout.tsx +0 -37
  108. package/src/app/ndpr-demos/breach/page.tsx +0 -354
  109. package/src/app/ndpr-demos/consent/page.tsx +0 -366
  110. package/src/app/ndpr-demos/dpia/page.tsx +0 -495
  111. package/src/app/ndpr-demos/dsr/page.tsx +0 -280
  112. package/src/app/ndpr-demos/page.tsx +0 -73
  113. package/src/app/ndpr-demos/policy/page.tsx +0 -771
  114. package/src/app/page.tsx +0 -452
  115. package/src/components/ErrorBoundary.tsx +0 -90
  116. package/src/components/breach-notification/BreachNotificationForm.tsx +0 -479
  117. package/src/components/consent/ConsentBanner.tsx +0 -159
  118. package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +0 -419
  119. package/src/components/docs/DocLayout.tsx +0 -289
  120. package/src/components/docs/index.ts +0 -2
  121. package/src/components/dpia/DPIAQuestionnaire.tsx +0 -483
  122. package/src/components/privacy-policy/PolicyGenerator.tsx +0 -1062
  123. package/src/components/privacy-policy/data.ts +0 -98
  124. package/src/components/privacy-policy/shared/CheckboxField.tsx +0 -38
  125. package/src/components/privacy-policy/shared/CheckboxGroup.tsx +0 -85
  126. package/src/components/privacy-policy/shared/FormField.tsx +0 -79
  127. package/src/components/privacy-policy/shared/StepIndicator.tsx +0 -86
  128. package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +0 -335
  129. package/src/components/privacy-policy/steps/DataCollectionStep.tsx +0 -231
  130. package/src/components/privacy-policy/steps/DataSharingStep.tsx +0 -418
  131. package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +0 -202
  132. package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +0 -172
  133. package/src/components/ui/Badge.tsx +0 -46
  134. package/src/components/ui/Button.tsx +0 -59
  135. package/src/components/ui/Card.tsx +0 -92
  136. package/src/components/ui/Checkbox.tsx +0 -57
  137. package/src/components/ui/FormField.tsx +0 -50
  138. package/src/components/ui/Input.tsx +0 -38
  139. package/src/components/ui/Loading.tsx +0 -201
  140. package/src/components/ui/Select.tsx +0 -42
  141. package/src/components/ui/TextArea.tsx +0 -38
  142. package/src/components/ui/label.tsx +0 -24
  143. package/src/components/ui/switch.tsx +0 -31
  144. package/src/components/ui/tabs.tsx +0 -66
  145. package/src/hooks/useConsent.ts +0 -64
  146. package/src/hooks/useLoadingState.ts +0 -85
  147. package/src/lib/consentService.ts +0 -137
  148. package/src/lib/dpiaQuestions.ts +0 -148
  149. package/src/lib/requestService.ts +0 -75
  150. package/src/lib/sanitize.ts +0 -108
  151. package/src/lib/storage.ts +0 -222
  152. package/src/lib/utils.ts +0 -6
  153. package/src/types/html-to-docx.d.ts +0 -30
  154. package/src/types/index.ts +0 -72
  155. package/tailwind.config.ts +0 -65
  156. package/tsconfig.json +0 -41
@@ -1,199 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, fireEvent } from '@testing-library/react';
3
- import { DSRDashboard } from '../../../components/dsr/DSRDashboard';
4
- import { DSRRequest } from '../../../types/dsr';
5
-
6
- describe('DSRDashboard', () => {
7
- const mockRequests: DSRRequest[] = [
8
- {
9
- id: '1',
10
- type: 'access',
11
- status: 'pending',
12
- createdAt: 1620000000000,
13
- updatedAt: 1620000000000,
14
- subject: {
15
- name: 'John Doe',
16
- email: 'john@example.com',
17
- phone: '1234567890'
18
- },
19
- description: 'I want to access my data'
20
- },
21
- {
22
- id: '2',
23
- type: 'erasure',
24
- status: 'inProgress',
25
- createdAt: 1620100000000,
26
- updatedAt: 1620100000000,
27
- subject: {
28
- name: 'Jane Smith',
29
- email: 'jane@example.com'
30
- }
31
- },
32
- {
33
- id: '3',
34
- type: 'rectification',
35
- status: 'completed',
36
- createdAt: 1620200000000,
37
- updatedAt: 1620300000000,
38
- completedAt: 1620300000000,
39
- subject: {
40
- name: 'Bob Johnson',
41
- email: 'bob@example.com'
42
- },
43
- description: 'Please correct my address'
44
- }
45
- ];
46
-
47
- const mockUpdateRequest = jest.fn();
48
- const mockDeleteRequest = jest.fn();
49
-
50
- beforeEach(() => {
51
- mockUpdateRequest.mockClear();
52
- mockDeleteRequest.mockClear();
53
- });
54
-
55
- it('renders the dashboard with requests', () => {
56
- render(
57
- <DSRDashboard
58
- requests={mockRequests}
59
- onUpdateStatus={mockUpdateRequest}
60
- onSelectRequest={mockDeleteRequest}
61
- />
62
- );
63
-
64
- // Check that the dashboard title is rendered
65
- expect(screen.getByText(/Data Subject Request Dashboard/i)).toBeInTheDocument();
66
-
67
- // Check that the dashboard has the correct structure
68
- const dashboard = document.querySelector('.grid');
69
- expect(dashboard).not.toBeNull();
70
-
71
- // Check that DSR Requests section is rendered
72
- expect(screen.getByText(/DSR Requests/i)).toBeInTheDocument();
73
-
74
- // Check that there are request elements in the dashboard
75
- const requestElements = document.querySelectorAll('.rounded-md.cursor-pointer');
76
- expect(requestElements.length).toBeGreaterThan(0);
77
- });
78
-
79
- it('renders the dashboard with filter controls', () => {
80
- render(
81
- <DSRDashboard
82
- requests={mockRequests}
83
- onUpdateStatus={mockUpdateRequest}
84
- onSelectRequest={mockDeleteRequest}
85
- />
86
- );
87
-
88
- // Check that the dashboard title is rendered
89
- expect(screen.getByText(/Data Subject Request Dashboard/i)).toBeInTheDocument();
90
-
91
- // Check that filter controls are rendered by looking for select elements
92
- const selectElements = screen.getAllByRole('combobox');
93
- expect(selectElements.length).toBeGreaterThan(0);
94
-
95
- // Check that tHere&apos;s a search input
96
- const searchInput = screen.getByPlaceholderText(/Search requests/i);
97
- expect(searchInput).toBeInTheDocument();
98
- });
99
-
100
- it('renders with sort controls', () => {
101
- render(
102
- <DSRDashboard
103
- requests={mockRequests}
104
- onUpdateStatus={mockUpdateRequest}
105
- onSelectRequest={mockDeleteRequest}
106
- />
107
- );
108
-
109
- // Check that sort options are rendered
110
- const sortBySelect = screen.getByLabelText(/Sort By/i);
111
- expect(sortBySelect).toBeInTheDocument();
112
-
113
- // Check that the sort dropdown exists
114
- expect(sortBySelect.tagName.toLowerCase()).toBe('select');
115
-
116
- // Check that at least one option exists
117
- const options = screen.getAllByRole('option');
118
- expect(options.length).toBeGreaterThan(0);
119
- });
120
-
121
- it('renders with search functionality', () => {
122
- render(
123
- <DSRDashboard
124
- requests={mockRequests}
125
- onUpdateStatus={mockUpdateRequest}
126
- onSelectRequest={mockDeleteRequest}
127
- />
128
- );
129
-
130
- // Check that search input is rendered
131
- const searchInput = screen.getByPlaceholderText(/Search requests/i);
132
- expect(searchInput).toBeInTheDocument();
133
- });
134
-
135
- it('renders with request list section', () => {
136
- render(
137
- <DSRDashboard
138
- requests={mockRequests}
139
- onUpdateStatus={mockUpdateRequest}
140
- onSelectRequest={mockDeleteRequest}
141
- />
142
- );
143
-
144
- // Check that the DSR Requests section is rendered
145
- expect(screen.getByText(/DSR Requests/i)).toBeInTheDocument();
146
-
147
- // Check that the dashboard has the correct structure
148
- const dashboard = document.querySelector('.grid');
149
- expect(dashboard).not.toBeNull();
150
- });
151
-
152
- it('renders with the correct title and description', () => {
153
- const customTitle = 'Custom DSR Dashboard Title';
154
- const customDescription = 'Custom description for testing';
155
-
156
- render(
157
- <DSRDashboard
158
- requests={mockRequests}
159
- onUpdateStatus={mockUpdateRequest}
160
- onSelectRequest={mockDeleteRequest}
161
- title={customTitle}
162
- description={customDescription}
163
- />
164
- );
165
-
166
- // Check that custom title and description are rendered
167
- expect(screen.getByText(customTitle)).toBeInTheDocument();
168
- expect(screen.getByText(customDescription)).toBeInTheDocument();
169
- });
170
-
171
- it('handles empty requests array', () => {
172
- render(
173
- <DSRDashboard
174
- requests={[]}
175
- onUpdateStatus={mockUpdateRequest}
176
- onSelectRequest={mockDeleteRequest}
177
- />
178
- );
179
-
180
- expect(screen.getByText(/No data subject requests found/i)).toBeInTheDocument();
181
- });
182
-
183
- it('renders with custom className', () => {
184
- const customClassName = 'custom-dashboard-class';
185
-
186
- render(
187
- <DSRDashboard
188
- requests={mockRequests}
189
- onUpdateStatus={mockUpdateRequest}
190
- onSelectRequest={mockDeleteRequest}
191
- className={customClassName}
192
- />
193
- );
194
-
195
- // Check that the custom class is applied to the component
196
- const dashboardElement = document.querySelector(`.${customClassName}`);
197
- expect(dashboardElement).toBeInTheDocument();
198
- });
199
- });
@@ -1,224 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, fireEvent } from '@testing-library/react';
3
- import { DSRRequestForm } from '../../../components/dsr/DSRRequestForm';
4
- // Note: We'll mock the DSR context instead of importing it directly
5
-
6
- describe('DSRRequestForm', () => {
7
- const mockOnSubmit = jest.fn();
8
-
9
- const renderComponent = (props = {}) => {
10
- return render(
11
- <DSRRequestForm
12
- onSubmit={mockOnSubmit}
13
- requestTypes={[
14
- { id: 'access', name: 'Access my data', description: 'Request a copy of your data', estimatedCompletionTime: 30, requiresAdditionalInfo: false },
15
- { id: 'rectification', name: 'Correct my data', description: 'Request corrections to your data', estimatedCompletionTime: 15, requiresAdditionalInfo: true },
16
- { id: 'erasure', name: 'Delete my data', description: 'Request deletion of your data', estimatedCompletionTime: 30, requiresAdditionalInfo: false }
17
- ]}
18
- {...props}
19
- />
20
- );
21
- };
22
-
23
- beforeEach(() => {
24
- mockOnSubmit.mockClear();
25
- });
26
-
27
- it('renders the form correctly', () => {
28
- renderComponent();
29
-
30
- expect(screen.getByText(/submit a data subject request/i)).toBeInTheDocument();
31
- expect(screen.getByLabelText(/full name/i)).toBeInTheDocument();
32
- expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
33
- expect(screen.getByLabelText(/request type/i)).toBeInTheDocument();
34
- expect(screen.getByRole('button', { name: /submit/i })).toBeInTheDocument();
35
- });
36
-
37
- it('displays all request types in the dropdown', () => {
38
- renderComponent();
39
-
40
- const selectElement = screen.getByLabelText(/request type/i);
41
- fireEvent.click(selectElement);
42
-
43
- expect(screen.getByText('Access my data')).toBeInTheDocument();
44
- expect(screen.getByText('Correct my data')).toBeInTheDocument();
45
- expect(screen.getByText('Delete my data')).toBeInTheDocument();
46
- });
47
-
48
- it('validates required fields', async () => {
49
- // Mock console.error to prevent React warnings from cluttering test output
50
- const originalConsoleError = console.error;
51
- console.error = jest.fn();
52
-
53
- const { container } = renderComponent();
54
-
55
- // Submit without filling required fields
56
- fireEvent.click(screen.getByRole('button', { name: /submit/i }));
57
-
58
- // Wait for validation to happen
59
- await new Promise(resolve => setTimeout(resolve, 100));
60
-
61
- // Directly check that the form validation prevented submission
62
- expect(mockOnSubmit).not.toHaveBeenCalled();
63
-
64
- // Restore console.error
65
- console.error = originalConsoleError;
66
- });
67
-
68
- it('validates email format', async () => {
69
- // Use a custom render to access component state
70
- const { container } = renderComponent();
71
-
72
- // Fill in name and request type
73
- fireEvent.change(screen.getByLabelText(/full name/i), {
74
- target: { value: 'John Doe' }
75
- });
76
-
77
- // Select a request type
78
- const selectElement = screen.getByLabelText(/request type/i);
79
- fireEvent.change(selectElement, { target: { value: 'access' } });
80
-
81
- // Enter invalid email
82
- const emailInput = screen.getByLabelText(/email/i);
83
- fireEvent.change(emailInput, {
84
- target: { value: 'invalid-email' }
85
- });
86
-
87
- // Submit the form
88
- fireEvent.click(screen.getByRole('button', { name: /submit/i }));
89
-
90
- // Wait a bit for the validation to happen
91
- await new Promise(resolve => setTimeout(resolve, 0));
92
-
93
- // Check that the form has an error message somewhere
94
- const errorElements = container.querySelectorAll('.text-red-500');
95
- expect(errorElements.length).toBeGreaterThan(0);
96
-
97
- // Should not call onSubmit when validation fails
98
- expect(mockOnSubmit).not.toHaveBeenCalled();
99
-
100
- // Now try with a valid email
101
- fireEvent.change(emailInput, {
102
- target: { value: 'valid@example.com' }
103
- });
104
-
105
- // Also fill in any other required fields
106
- // Fill in identifier value if required
107
- const identifierValueInput = screen.getByLabelText(/identifier value/i);
108
- fireEvent.change(identifierValueInput, {
109
- target: { value: 'valid-id-123' }
110
- });
111
-
112
- // Submit the form again
113
- fireEvent.click(screen.getByRole('button', { name: /submit/i }));
114
-
115
- // Now onSubmit should be called
116
- expect(mockOnSubmit).toHaveBeenCalled();
117
- });
118
-
119
- it('submits the form with valid data', async () => {
120
- // Mock the onSubmit function
121
- const mockSubmit = jest.fn();
122
-
123
- render(
124
- <DSRRequestForm
125
- requestTypes={[
126
- { id: 'access', name: 'Access my data', description: 'Request a copy of your data', estimatedCompletionTime: 30, requiresAdditionalInfo: false },
127
- { id: 'rectification', name: 'Correct my data', description: 'Request corrections to your data', estimatedCompletionTime: 15, requiresAdditionalInfo: true },
128
- { id: 'erasure', name: 'Delete my data', description: 'Request deletion of your data', estimatedCompletionTime: 30, requiresAdditionalInfo: false }
129
- ]}
130
- onSubmit={mockSubmit}
131
- />
132
- );
133
-
134
- // Fill in all required fields
135
- fireEvent.change(screen.getByLabelText(/full name/i), {
136
- target: { value: 'John Doe' }
137
- });
138
-
139
- fireEvent.change(screen.getByLabelText(/email/i), {
140
- target: { value: 'john@example.com' }
141
- });
142
-
143
- // Select a request type
144
- const selectElement = screen.getByLabelText(/request type/i);
145
- fireEvent.change(selectElement, { target: { value: 'access' } });
146
-
147
- // Fill in identifier value
148
- fireEvent.change(screen.getByLabelText(/identifier value/i), {
149
- target: { value: 'john@example.com' }
150
- });
151
-
152
- // Submit the form
153
- fireEvent.click(screen.getByRole('button', { name: /submit request/i }));
154
-
155
- // Should call onSubmit with form data
156
- expect(mockSubmit).toHaveBeenCalled();
157
- });
158
-
159
- it('shows success message after submission', async () => {
160
- // Mock the onSubmit function to trigger the success message
161
- const mockSubmit = jest.fn().mockImplementation(() => {
162
- // This will be called when the form is submitted
163
- });
164
-
165
- render(
166
- <DSRRequestForm
167
- requestTypes={[
168
- { id: 'access', name: 'Access my data', description: 'Request a copy of your data', estimatedCompletionTime: 30, requiresAdditionalInfo: false },
169
- { id: 'rectification', name: 'Correct my data', description: 'Request corrections to your data', estimatedCompletionTime: 15, requiresAdditionalInfo: true },
170
- { id: 'erasure', name: 'Delete my data', description: 'Request deletion of your data', estimatedCompletionTime: 30, requiresAdditionalInfo: false }
171
- ]}
172
- onSubmit={mockSubmit}
173
- showConfirmation={true}
174
- confirmationMessage="Your request has been submitted successfully. You will receive a confirmation email shortly."
175
- />
176
- );
177
-
178
- // Fill in all required fields
179
- fireEvent.change(screen.getByLabelText(/full name/i), {
180
- target: { value: 'John Doe' }
181
- });
182
-
183
- fireEvent.change(screen.getByLabelText(/email/i), {
184
- target: { value: 'john@example.com' }
185
- });
186
-
187
- // Select a request type
188
- const selectElement = screen.getByLabelText(/request type/i);
189
- fireEvent.change(selectElement, { target: { value: 'access' } });
190
-
191
- // Fill in identifier value
192
- fireEvent.change(screen.getByLabelText(/identifier value/i), {
193
- target: { value: 'john@example.com' }
194
- });
195
-
196
- // Submit the form
197
- fireEvent.click(screen.getByRole('button', { name: /submit request/i }));
198
-
199
- // Should show success message
200
- expect(await screen.findByText(/request submitted/i)).toBeInTheDocument();
201
- expect(await screen.findByText(/you will receive a confirmation email shortly/i)).toBeInTheDocument();
202
-
203
- // Verify that onSubmit was called
204
- expect(mockSubmit).toHaveBeenCalled();
205
- });
206
-
207
- it('handles custom field labels', () => {
208
- renderComponent({
209
- labels: {
210
- name: 'Your Full Name',
211
- email: 'Your Email Address',
212
- requestType: 'Type of Request',
213
- description: 'Additional Information',
214
- submit: 'Send Request'
215
- }
216
- });
217
-
218
- expect(screen.getByLabelText(/Your Full Name/i)).toBeInTheDocument();
219
- expect(screen.getByLabelText(/Your Email Address/i)).toBeInTheDocument();
220
- expect(screen.getByLabelText(/Type of Request/i)).toBeInTheDocument();
221
- expect(screen.getByLabelText(/Additional Information/i)).toBeInTheDocument();
222
- expect(screen.getByRole('button', { name: /Send Request/i })).toBeInTheDocument();
223
- });
224
- });
@@ -1,104 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, fireEvent } from '@testing-library/react';
3
- import { DSRTracker } from '../../../components/dsr/DSRTracker';
4
- import { DSRRequest } from '../../../types/dsr';
5
-
6
- describe('DSRTracker', () => {
7
- const mockRequest: DSRRequest = {
8
- id: 'dsr-123',
9
- type: 'access',
10
- status: 'inProgress',
11
- createdAt: 1620000000000,
12
- updatedAt: 1620100000000,
13
- subject: {
14
- name: 'John Doe',
15
- email: 'john@example.com'
16
- },
17
- description: 'I want to access my personal data'
18
- };
19
-
20
- const mockTrackHandler = jest.fn();
21
-
22
- beforeEach(() => {
23
- mockTrackHandler.mockClear();
24
- });
25
-
26
- it('renders the tracking form correctly', () => {
27
- render(
28
- <DSRTracker
29
- requests={[]}
30
- onSelectRequest={mockTrackHandler}
31
- />
32
- );
33
-
34
- expect(screen.getByText(/DSR Request Tracker/i)).toBeInTheDocument();
35
- expect(screen.getByText(/track the status and progress/i)).toBeInTheDocument();
36
- expect(screen.getByText(/total requests/i)).toBeInTheDocument();
37
- expect(screen.getByLabelText(/timeframe/i)).toBeInTheDocument();
38
- });
39
-
40
- // Note: The DSRTracker component doesn&apos;t have a form for tracking requests directly visible on initial render
41
- // These tests are removed as they don&apos;t match the actual component implementation
42
-
43
- it('displays request count when provided', () => {
44
- // Render the component with a request
45
- const { container } = render(
46
- <DSRTracker
47
- requests={[mockRequest]}
48
- onSelectRequest={mockTrackHandler}
49
- />
50
- );
51
-
52
- // Check that the component renders without crashing
53
- expect(container).toBeInTheDocument();
54
-
55
- // Should show summary stats with the request count heading
56
- expect(screen.getByText(/total requests/i)).toBeInTheDocument();
57
-
58
- // Check that the component has rendered some content
59
- const statsContainer = screen.getByText(/total requests/i).closest('div');
60
- expect(statsContainer).toBeInTheDocument();
61
- });
62
-
63
- // Note: The DSRTracker component doesn&apos;t display a "Request not found" message directly on initial render
64
- // This test is removed as it doesn&apos;t match the actual component implementation
65
-
66
- it('handles custom title', () => {
67
- const customTitle = 'Custom DSR Tracker Title';
68
-
69
- render(
70
- <DSRTracker
71
- requests={[]}
72
- onSelectRequest={mockTrackHandler}
73
- title={customTitle}
74
- />
75
- );
76
-
77
- expect(screen.getByText(customTitle)).toBeInTheDocument();
78
- });
79
-
80
- it('shows request timeline chart when requests are provided', () => {
81
- const requestWithDates: DSRRequest = {
82
- ...mockRequest,
83
- verifiedAt: 1620050000000,
84
- completedAt: 1620200000000
85
- };
86
-
87
- // Render the component with the request
88
- const { container } = render(
89
- <DSRTracker
90
- requests={[requestWithDates]}
91
- onSelectRequest={mockTrackHandler}
92
- />
93
- );
94
-
95
- // Check that the component renders without crashing
96
- expect(container).toBeInTheDocument();
97
-
98
- // Check for the title which should always be present
99
- expect(screen.getByText(/DSR Request Tracker/i)).toBeInTheDocument();
100
-
101
- // Check that the description is present
102
- expect(screen.getByText(/Track the status and progress/i)).toBeInTheDocument();
103
- });
104
- });
@@ -1,161 +0,0 @@
1
- import React from 'react';
2
- import { renderHook, act } from '@testing-library/react';
3
- import { useConsent } from '../../hooks/useConsent';
4
- import { ConsentOption, ConsentSettings } from '../../types/consent';
5
-
6
- // Mock localStorage
7
- const mockLocalStorage = (() => {
8
- let store: Record<string, string> = {};
9
- return {
10
- getItem: jest.fn((key: string) => store[key] || null),
11
- setItem: jest.fn((key: string, value: string) => {
12
- store[key] = value.toString();
13
- }),
14
- removeItem: jest.fn((key: string) => {
15
- delete store[key];
16
- }),
17
- clear: jest.fn(() => {
18
- store = {};
19
- }),
20
- };
21
- })();
22
-
23
- Object.defineProperty(window, 'localStorage', {
24
- value: mockLocalStorage,
25
- });
26
-
27
- describe('useConsent', () => {
28
- beforeEach(() => {
29
- mockLocalStorage.clear();
30
- jest.clearAllMocks();
31
- });
32
-
33
- const consentOptions: ConsentOption[] = [
34
- {
35
- id: 'necessary',
36
- label: 'Necessary',
37
- description: 'Essential cookies',
38
- required: true,
39
- },
40
- {
41
- id: 'analytics',
42
- label: 'Analytics',
43
- description: 'Analytics cookies',
44
- required: false,
45
- },
46
- {
47
- id: 'marketing',
48
- label: 'Marketing',
49
- description: 'Marketing cookies',
50
- required: false,
51
- },
52
- ];
53
-
54
- it('should initialize with default consent settings', () => {
55
- const { result } = renderHook(() => useConsent({
56
- options: consentOptions,
57
- storageOptions: { storageKey: 'test-consent' }
58
- }));
59
-
60
- expect(result.current.settings).toBe(null);
61
- expect(result.current.shouldShowBanner).toBe(true);
62
- expect(result.current.hasConsent('necessary')).toBe(false);
63
- expect(result.current.hasConsent('analytics')).toBe(false);
64
- });
65
-
66
- it('should update consent settings', () => {
67
- const { result } = renderHook(() => useConsent({
68
- options: consentOptions,
69
- storageOptions: { storageKey: 'test-consent' }
70
- }));
71
-
72
- act(() => {
73
- result.current.updateConsent({
74
- necessary: true,
75
- analytics: true,
76
- marketing: false
77
- });
78
- });
79
-
80
- expect(result.current.settings?.consents.necessary).toBe(true);
81
- expect(result.current.settings?.consents.analytics).toBe(true);
82
- expect(result.current.settings?.consents.marketing).toBe(false);
83
- expect(result.current.hasConsent('analytics')).toBe(true);
84
- });
85
-
86
- it('should accept all consent options', () => {
87
- const { result } = renderHook(() => useConsent({
88
- options: consentOptions,
89
- storageOptions: { storageKey: 'test-consent' }
90
- }));
91
-
92
- act(() => {
93
- result.current.acceptAll();
94
- });
95
-
96
- expect(result.current.settings?.consents.necessary).toBe(true);
97
- expect(result.current.settings?.consents.analytics).toBe(true);
98
- expect(result.current.settings?.consents.marketing).toBe(true);
99
- });
100
-
101
- it('should save and reset consent settings', () => {
102
- const { result } = renderHook(() => useConsent({
103
- options: consentOptions,
104
- storageOptions: { storageKey: 'test-consent' }
105
- }));
106
-
107
- act(() => {
108
- result.current.updateConsent({
109
- necessary: true,
110
- analytics: true,
111
- marketing: false
112
- });
113
- });
114
-
115
- expect(mockLocalStorage.setItem).toHaveBeenCalled();
116
- expect(result.current.shouldShowBanner).toBe(false);
117
-
118
- // Reset the consent settings
119
- act(() => {
120
- result.current.resetConsent();
121
- });
122
-
123
- expect(mockLocalStorage.removeItem).toHaveBeenCalledWith('test-consent');
124
- expect(result.current.settings).toBe(null);
125
- expect(result.current.shouldShowBanner).toBe(true);
126
- });
127
-
128
- it('should reject all non-required consent options', () => {
129
- const { result } = renderHook(() => useConsent({
130
- options: consentOptions,
131
- storageOptions: { storageKey: 'test-consent' }
132
- }));
133
-
134
- act(() => {
135
- result.current.rejectAll();
136
- });
137
-
138
- // Necessary is required, so it should be true
139
- expect(result.current.settings?.consents.necessary).toBe(true);
140
- // Non-required options should be false
141
- expect(result.current.settings?.consents.analytics).toBe(false);
142
- expect(result.current.settings?.consents.marketing).toBe(false);
143
- });
144
-
145
- it('should handle validation', () => {
146
- const { result } = renderHook(() => useConsent({
147
- options: consentOptions,
148
- storageOptions: { storageKey: 'test-consent' }
149
- }));
150
-
151
- expect(result.current.isValid).toBe(false);
152
-
153
- act(() => {
154
- result.current.acceptAll();
155
- });
156
-
157
- // After accepting all, settings should be valid
158
- expect(result.current.isValid).toBe(true);
159
- expect(result.current.validationErrors).toEqual([]);
160
- });
161
- });