@eeacms/volto-cca-policy 1.0.2 → 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 (78) hide show
  1. package/CHANGELOG.md +259 -3
  2. package/jest-addon.config.js +4 -2
  3. package/locales/bg/LC_MESSAGES/volto.po +576 -0
  4. package/locales/cs/LC_MESSAGES/volto.po +576 -0
  5. package/locales/da/LC_MESSAGES/volto.po +576 -0
  6. package/locales/de/LC_MESSAGES/volto.po +576 -0
  7. package/locales/el/LC_MESSAGES/volto.po +576 -0
  8. package/locales/en/LC_MESSAGES/volto.po +576 -0
  9. package/locales/es/LC_MESSAGES/volto.po +576 -0
  10. package/locales/et/LC_MESSAGES/volto.po +576 -0
  11. package/locales/fi/LC_MESSAGES/volto.po +576 -0
  12. package/locales/fr/LC_MESSAGES/volto.po +576 -0
  13. package/locales/ga/LC_MESSAGES/volto.po +576 -0
  14. package/locales/hr/LC_MESSAGES/volto.po +576 -0
  15. package/locales/hu/LC_MESSAGES/volto.po +576 -0
  16. package/locales/is/LC_MESSAGES/volto.po +576 -0
  17. package/locales/it/LC_MESSAGES/volto.po +576 -0
  18. package/locales/lt/LC_MESSAGES/volto.po +576 -0
  19. package/locales/lv/LC_MESSAGES/volto.po +576 -0
  20. package/locales/mt/LC_MESSAGES/volto.po +576 -0
  21. package/locales/nl/LC_MESSAGES/volto.po +576 -0
  22. package/locales/nn/LC_MESSAGES/volto.po +576 -0
  23. package/locales/pl/LC_MESSAGES/volto.po +576 -0
  24. package/locales/pt/LC_MESSAGES/volto.po +576 -0
  25. package/locales/ro/LC_MESSAGES/volto.po +576 -0
  26. package/locales/sk/LC_MESSAGES/volto.po +576 -0
  27. package/locales/sl/LC_MESSAGES/volto.po +576 -0
  28. package/locales/sv/LC_MESSAGES/volto.po +576 -0
  29. package/locales/tr/LC_MESSAGES/volto.po +576 -0
  30. package/locales/volto.pot +577 -1
  31. package/package.json +1 -1
  32. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.jsx +224 -0
  33. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.test.jsx +173 -0
  34. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueContentView.jsx +189 -0
  35. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.jsx +272 -0
  36. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.test.jsx +160 -0
  37. package/src/components/Search/NavigatorCatalogue/utils.js +157 -0
  38. package/src/components/Search/NavigatorCatalogue/utils.test.js +132 -0
  39. package/src/components/Search/NavigatorGuide/NavigatorGuideContentView.jsx +409 -0
  40. package/src/components/Search/NavigatorGuide/NavigatorGuideLayout.jsx +8 -0
  41. package/src/components/index.js +2 -0
  42. package/src/components/theme/CompareTools/CompareToolsPanel.jsx +151 -0
  43. package/src/components/theme/CompareTools/CompareToolsPanel.test.jsx +96 -0
  44. package/src/components/theme/CompareTools/CompareToolsView.jsx +475 -0
  45. package/src/components/theme/CompareTools/CompareToolsView.test.jsx +110 -0
  46. package/src/components/theme/CompareTools/utils.js +111 -0
  47. package/src/components/theme/CompareTools/utils.test.jsx +217 -0
  48. package/src/components/theme/Views/ExtendedToolView.jsx +201 -201
  49. package/src/components/theme/Views/ExtendedToolView.test.jsx +420 -58
  50. package/src/constants.js +0 -48
  51. package/src/customizations/volto/reducers/breadcrumbs/breadcrumbs.js +1 -1
  52. package/src/helpers/Utils.jsx +29 -0
  53. package/src/helpers/index.js +3 -0
  54. package/src/index.js +28 -2
  55. package/src/search/index.js +6 -0
  56. package/src/search/navigator_catalogue/config.js +89 -0
  57. package/src/search/navigator_catalogue/facets.js +86 -0
  58. package/src/search/navigator_catalogue/views.js +28 -0
  59. package/src/search/navigator_guide/config.js +70 -0
  60. package/src/search/navigator_guide/facets.js +31 -0
  61. package/src/search/navigator_guide/guideSteps.js +93 -0
  62. package/src/slate-styles.less +4 -0
  63. package/src/state.js +1 -0
  64. package/theme/elements/button.overrides +0 -11
  65. package/theme/elements/label.overrides +15 -0
  66. package/theme/globals/blocks.less +3 -2
  67. package/theme/globals/navigator.less +1090 -0
  68. package/theme/globals/site.overrides +5 -0
  69. package/theme/tokens/colors.less +2 -0
  70. package/artifacts/BLOCKS.md +0 -167
  71. package/artifacts/link-integrity-workflow/README.md +0 -76
  72. package/artifacts/link-integrity-workflow/index.md +0 -33
  73. package/artifacts/link-integrity-workflow/link-integrity-block-fields-report.md +0 -132
  74. package/artifacts/link-integrity-workflow/link-integrity-blocks-report.md +0 -52
  75. package/artifacts/link-integrity-workflow/understanding-link-integrity.md +0 -143
  76. package/artifacts/link-integrity-workflow/volto-block-link-analysis.md +0 -63
  77. package/artifacts/link-integrity-workflow/volto-block-link-discovery.md +0 -60
  78. package/artifacts/test-fixes/test-fixes-specification.md +0 -267
@@ -0,0 +1,217 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import { Provider as JotaiProvider } from 'jotai';
5
+ import { applyConfigurationSchema, rebind } from '@eeacms/search';
6
+ import runRequest from '@eeacms/search/lib/runRequest';
7
+ import {
8
+ MAX_COMPARE_TOOLS,
9
+ fetchResultsByUid,
10
+ getCompareLocation,
11
+ getCompareToolTitle,
12
+ getCompareToolUid,
13
+ getPathname,
14
+ useCompareTools,
15
+ } from './utils';
16
+
17
+ jest.mock('@eeacms/search', () => ({
18
+ applyConfigurationSchema: jest.fn((config) => config),
19
+ rebind: jest.fn((config) => config),
20
+ }));
21
+
22
+ jest.mock('@eeacms/search/lib/runRequest', () => jest.fn());
23
+
24
+ jest.mock('@plone/volto/helpers/Url/Url', () => ({
25
+ flattenToAppURL: (url) => url.replace('https://example.com', ''),
26
+ }));
27
+
28
+ const CompareHarness = ({ tool }) => {
29
+ const { isLimitReached, isSelected, setSelected, toggle } =
30
+ useCompareTools(tool);
31
+
32
+ return (
33
+ <>
34
+ <span data-testid="selected">{String(isSelected)}</span>
35
+ <span data-testid="limit">{String(isLimitReached)}</span>
36
+ <button type="button" onClick={toggle}>
37
+ Toggle
38
+ </button>
39
+ <button type="button" onClick={() => setSelected(true)}>
40
+ Select
41
+ </button>
42
+ <button type="button" onClick={() => setSelected(false)}>
43
+ Remove
44
+ </button>
45
+ </>
46
+ );
47
+ };
48
+
49
+ const renderCompareHarness = (tool, initialTools = []) => {
50
+ window.localStorage.setItem(
51
+ 'cca-compare-tools',
52
+ JSON.stringify(initialTools),
53
+ );
54
+
55
+ return render(
56
+ <JotaiProvider>
57
+ <CompareHarness tool={tool} />
58
+ </JotaiProvider>,
59
+ );
60
+ };
61
+
62
+ describe('Compare Tools utilities', () => {
63
+ beforeEach(() => {
64
+ jest.clearAllMocks();
65
+ window.localStorage.clear();
66
+ });
67
+
68
+ it('resolves comparison identifiers and titles from supported shapes', () => {
69
+ expect(getCompareToolUid({ cca_uid: { raw: 'cca-id' } })).toBe('cca-id');
70
+ expect(getCompareToolUid({ UID: 'plone-id' })).toBe('plone-id');
71
+ expect(getCompareToolUid({ _result: { cca_uid: { raw: 'raw-id' } } })).toBe(
72
+ 'raw-id',
73
+ );
74
+ expect(getCompareToolUid({})).toBe('');
75
+ expect(getCompareToolTitle({ title: 'Tool title' })).toBe('Tool title');
76
+ expect(getCompareToolTitle({})).toBe('');
77
+ });
78
+
79
+ it('normalizes paths and removes query strings and hashes', () => {
80
+ expect(getPathname()).toBe('');
81
+ expect(getPathname('https://example.com/en/tools/?a=1#result')).toBe(
82
+ '/en/tools',
83
+ );
84
+ expect(getPathname('/en/tools')).toBe('/en/tools');
85
+ });
86
+
87
+ it('builds a localized comparison location with at most four tools', () => {
88
+ const tools = [
89
+ { uid: 'one' },
90
+ { uid: '' },
91
+ { uid: 'two' },
92
+ { uid: 'three' },
93
+ { uid: 'four' },
94
+ { uid: 'five' },
95
+ ];
96
+
97
+ expect(
98
+ getCompareLocation(
99
+ tools,
100
+ { landingPageURL: '/en/navigator/tool-catalogue' },
101
+ '/en/navigator/tool-catalogue?q=test',
102
+ 'ro',
103
+ ),
104
+ ).toEqual({
105
+ pathname: '/ro/navigator/compare',
106
+ search: '?uid=one&uid=two&uid=three',
107
+ state: { returnURL: '/en/navigator/tool-catalogue?q=test' },
108
+ });
109
+ expect(MAX_COMPARE_TOOLS).toBe(4);
110
+ expect(getCompareLocation([], {}, undefined)).toEqual({
111
+ pathname: '/en/navigator/compare',
112
+ search: '',
113
+ state: { returnURL: undefined },
114
+ });
115
+ });
116
+
117
+ it('fetches and converts matching search results', async () => {
118
+ class ResultModel {
119
+ constructor(hit, config) {
120
+ this.hit = hit;
121
+ this.config = config;
122
+ }
123
+ }
124
+ const appConfig = {
125
+ index_name: 'data_searchui',
126
+ resultItemModel: { factory: 'resultModel' },
127
+ };
128
+ const registry = {
129
+ searchui: { navigatorCatalogueSearch: appConfig },
130
+ resolve: { resultModel: ResultModel },
131
+ };
132
+ runRequest.mockResolvedValue({
133
+ body: { hits: { hits: [{ _id: 'one' }, { _id: 'two' }] } },
134
+ });
135
+
136
+ const results = await fetchResultsByUid(['one', 'two'], registry);
137
+
138
+ expect(rebind).toHaveBeenCalledWith(appConfig);
139
+ expect(applyConfigurationSchema).toHaveBeenCalledWith(appConfig);
140
+ expect(runRequest).toHaveBeenCalledWith(
141
+ {
142
+ index: 'data_searchui',
143
+ size: 2,
144
+ query: {
145
+ bool: {
146
+ minimum_should_match: 1,
147
+ should: [
148
+ { terms: { 'cca_uid.keyword': ['one', 'two'] } },
149
+ { terms: { cca_uid: ['one', 'two'] } },
150
+ ],
151
+ },
152
+ },
153
+ },
154
+ appConfig,
155
+ );
156
+ expect(results).toHaveLength(2);
157
+ expect(results[0]).toBeInstanceOf(ResultModel);
158
+ });
159
+
160
+ it('handles missing hits and configurations without an index', async () => {
161
+ const registry = {
162
+ searchui: {
163
+ navigatorCatalogueSearch: {
164
+ resultItemModel: { factory: 'resultModel' },
165
+ },
166
+ },
167
+ resolve: { resultModel: class ResultModel {} },
168
+ };
169
+ runRequest.mockResolvedValue({});
170
+
171
+ await expect(fetchResultsByUid(['one'], registry)).resolves.toEqual([]);
172
+ expect(runRequest.mock.calls[0][0]).not.toHaveProperty('index');
173
+ });
174
+
175
+ it('adds, toggles, and removes a comparison tool', () => {
176
+ renderCompareHarness({ uid: 'one', title: 'Tool one' });
177
+
178
+ expect(screen.getByTestId('selected')).toHaveTextContent('false');
179
+ expect(screen.getByTestId('limit')).toHaveTextContent('false');
180
+
181
+ fireEvent.click(screen.getByText('Toggle'));
182
+ expect(screen.getByTestId('selected')).toHaveTextContent('true');
183
+ expect(
184
+ JSON.parse(window.localStorage.getItem('cca-compare-tools')),
185
+ ).toEqual([{ uid: 'one', title: 'Tool one' }]);
186
+
187
+ fireEvent.click(screen.getByText('Select'));
188
+ expect(screen.getByTestId('selected')).toHaveTextContent('true');
189
+
190
+ fireEvent.click(screen.getByText('Remove'));
191
+ expect(screen.getByTestId('selected')).toHaveTextContent('false');
192
+ expect(
193
+ JSON.parse(window.localStorage.getItem('cca-compare-tools')),
194
+ ).toEqual([]);
195
+ });
196
+
197
+ it('does not add tools without an identifier', () => {
198
+ renderCompareHarness({ title: 'Missing UID' });
199
+
200
+ fireEvent.click(screen.getByText('Select'));
201
+ expect(screen.getByTestId('selected')).toHaveTextContent('false');
202
+ });
203
+
204
+ it('enforces the comparison limit', () => {
205
+ const initialTools = Array.from(
206
+ { length: MAX_COMPARE_TOOLS },
207
+ (_, index) => ({
208
+ uid: `tool-${index}`,
209
+ }),
210
+ );
211
+ renderCompareHarness({ uid: 'extra' }, initialTools);
212
+
213
+ expect(screen.getByTestId('limit')).toHaveTextContent('true');
214
+ fireEvent.click(screen.getByText('Select'));
215
+ expect(screen.getByTestId('selected')).toHaveTextContent('false');
216
+ });
217
+ });