@eeacms/volto-cca-policy 1.0.17 → 1.0.19
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/CHANGELOG.md +24 -0
- package/package.json +1 -1
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.jsx +4 -3
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.test.jsx +63 -0
- package/src/components/Search/NavigatorCatalogue/utils.js +0 -12
- package/src/components/Search/NavigatorCatalogue/utils.test.js +0 -4
- package/src/components/Search/NavigatorGuide/NavigatorGuideContentView.jsx +5 -6
- package/src/components/Search/NavigatorGuide/NavigatorGuideContentView.test.jsx +94 -0
- package/src/components/theme/CompareTools/CompareToolsPanel.jsx +2 -3
- package/src/components/theme/CompareTools/CompareToolsPanel.test.jsx +54 -0
- package/src/components/theme/CompareTools/CompareToolsView.jsx +152 -87
- package/src/components/theme/CompareTools/CompareToolsView.test.jsx +117 -10
- package/src/components/theme/CompareTools/utils.js +33 -1
- package/src/components/theme/CompareTools/utils.test.jsx +128 -17
- package/src/components/theme/ToolThumbnail/ToolThumbnail.jsx +40 -0
- package/src/components/theme/ToolThumbnail/ToolThumbnail.test.jsx +29 -0
- package/src/components/theme/ToolThumbnail/utils.js +49 -0
- package/src/components/theme/ToolThumbnail/utils.test.js +124 -0
- package/src/components/theme/Views/ExtendedToolView.jsx +2 -0
- package/src/components/theme/Views/ExtendedToolView.test.jsx +67 -0
- package/src/components/theme/Views/RelatedTools.jsx +2 -6
- package/theme/globals/navigator.less +51 -7
- package/theme/globals/views.less +14 -18
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [1.0.19](https://github.com/eea/volto-cca-policy/compare/1.0.18...1.0.19) - 10 September 2026
|
|
8
|
+
|
|
9
|
+
#### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
- feat: enhance comparison table with new output type and adaptation support cycle step features [kreafox - [`40e56ad`](https://github.com/eea/volto-cca-policy/commit/40e56adb144e283ce18bf36e87db5c36f286ab9c)]
|
|
12
|
+
- feat: enhance CompareToolsView with new comparison options and styling [kreafox - [`a912b50`](https://github.com/eea/volto-cca-policy/commit/a912b5006af55aefbd024b494cd9c810bfb22684)]
|
|
13
|
+
|
|
14
|
+
#### :nail_care: Enhancements
|
|
15
|
+
|
|
16
|
+
- change: comparison table export by removing unused fields and improve export functionality [kreafox - [`f9ee0f7`](https://github.com/eea/volto-cca-policy/commit/f9ee0f74d02153b9a233ef13264c026503534038)]
|
|
17
|
+
- change: update comparison options handling and enhance tests for adaptation support cycle steps [kreafox - [`fc2736b`](https://github.com/eea/volto-cca-policy/commit/fc2736b293e938b3e13367d96d3c8158c5435f49)]
|
|
18
|
+
|
|
19
|
+
#### :hammer_and_wrench: Others
|
|
20
|
+
|
|
21
|
+
- test: improve test readability and structure in Compare Tools utilities [kreafox - [`b6fc550`](https://github.com/eea/volto-cca-policy/commit/b6fc550db8f3ddbadf093c56596968caf94900ad)]
|
|
22
|
+
### [1.0.18](https://github.com/eea/volto-cca-policy/compare/1.0.17...1.0.18) - 10 September 2026
|
|
23
|
+
|
|
24
|
+
#### :rocket: New Features
|
|
25
|
+
|
|
26
|
+
- feat: implement ToolThumbnail component and integrate it across various views [kreafox - [`edd3087`](https://github.com/eea/volto-cca-policy/commit/edd3087830076efa968ef42d1ec99efa42010cd5)]
|
|
27
|
+
|
|
28
|
+
#### :hammer_and_wrench: Others
|
|
29
|
+
|
|
30
|
+
- test: update image display style assertions in tests for NavigatorCatalogueCardItem and ToolThumbnail components [kreafox - [`24e1437`](https://github.com/eea/volto-cca-policy/commit/24e14375674dca5e73d8919eb4578d1c184db21a)]
|
|
7
31
|
### [1.0.17](https://github.com/eea/volto-cca-policy/compare/1.0.16...1.0.17) - 8 September 2026
|
|
8
32
|
|
|
9
33
|
#### :rocket: New Features
|
package/package.json
CHANGED
|
@@ -3,6 +3,8 @@ import { Checkbox, Icon, Popup } from 'semantic-ui-react';
|
|
|
3
3
|
import { defineMessages, useIntl } from 'react-intl';
|
|
4
4
|
import ExternalLink from '@eeacms/search/components/Result/ExternalLink';
|
|
5
5
|
import ResultContext from '@eeacms/search/components/Result/ResultContext';
|
|
6
|
+
import ToolThumbnail from '../../theme/ToolThumbnail/ToolThumbnail';
|
|
7
|
+
import { getToolThumbnailUrl } from '../../theme/ToolThumbnail/utils';
|
|
6
8
|
import {
|
|
7
9
|
getCompareToolTitle,
|
|
8
10
|
getCompareToolUid,
|
|
@@ -136,6 +138,7 @@ const NavigatorCatalogueCardItem = (props) => {
|
|
|
136
138
|
uid: getCompareToolUid(result),
|
|
137
139
|
title: getCompareToolTitle(result),
|
|
138
140
|
href: result.href,
|
|
141
|
+
image: getToolThumbnailUrl(result),
|
|
139
142
|
};
|
|
140
143
|
const { isSelected, isLimitReached, setSelected } =
|
|
141
144
|
useCompareTools(compareTool);
|
|
@@ -146,9 +149,7 @@ const NavigatorCatalogueCardItem = (props) => {
|
|
|
146
149
|
|
|
147
150
|
return (
|
|
148
151
|
<div className={`navigator-catalogue-item${isSelected ? ' selected' : ''}`}>
|
|
149
|
-
<
|
|
150
|
-
<Icon className="ri-file-line" />
|
|
151
|
-
</div>
|
|
152
|
+
<ToolThumbnail result={result} size="large" />
|
|
152
153
|
|
|
153
154
|
<div className="catalogue-item-main">
|
|
154
155
|
<div className="catalogue-item-top">
|
|
@@ -76,6 +76,7 @@ describe('NavigatorCatalogueCardItem', () => {
|
|
|
76
76
|
cca_uid: { raw: 'tool-uid' },
|
|
77
77
|
title: 'Climate planning tool',
|
|
78
78
|
href: 'https://example.com/tool',
|
|
79
|
+
image: '/uploaded-tool-thumb.jpg',
|
|
79
80
|
publication_date: { raw: '2026-07-24' },
|
|
80
81
|
cca_adaptation_sectors: {
|
|
81
82
|
raw: ['Agriculture', 'Water', 'Health', 'Energy'],
|
|
@@ -138,6 +139,7 @@ describe('NavigatorCatalogueCardItem', () => {
|
|
|
138
139
|
uid: 'tool-uid',
|
|
139
140
|
title: 'Climate planning tool',
|
|
140
141
|
href: 'https://example.com/tool',
|
|
142
|
+
image: '/uploaded-tool-thumb.jpg',
|
|
141
143
|
});
|
|
142
144
|
});
|
|
143
145
|
|
|
@@ -170,4 +172,65 @@ describe('NavigatorCatalogueCardItem', () => {
|
|
|
170
172
|
expect(screen.getByText('Water')).toBeInTheDocument();
|
|
171
173
|
expect(screen.queryByText('License:')).not.toBeInTheDocument();
|
|
172
174
|
});
|
|
175
|
+
|
|
176
|
+
describe('thumbnail rendering and fallback', () => {
|
|
177
|
+
it('renders thumbnail image and smoothly transitions from placeholder on load', () => {
|
|
178
|
+
const { container } = renderCard({
|
|
179
|
+
title: 'Tool with image',
|
|
180
|
+
href: '/tools/my-tool',
|
|
181
|
+
image: { scales: { thumb: { download: '/uploaded-thumb.jpg' } } },
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const img = container.querySelector('.navigator-tool-icon img');
|
|
185
|
+
expect(img).toBeInTheDocument();
|
|
186
|
+
expect(img).toHaveAttribute('src', '/uploaded-thumb.jpg');
|
|
187
|
+
expect(img.parentElement).toHaveClass('navigator-tool-icon', 'large');
|
|
188
|
+
expect(img).toHaveStyle({ display: 'none' });
|
|
189
|
+
expect(
|
|
190
|
+
container.querySelector('.navigator-tool-icon .ri-file-line'),
|
|
191
|
+
).toBeInTheDocument();
|
|
192
|
+
|
|
193
|
+
// Fire load event on image
|
|
194
|
+
fireEvent.load(img);
|
|
195
|
+
|
|
196
|
+
expect(img.style.display).toBe('');
|
|
197
|
+
expect(
|
|
198
|
+
container.querySelector('.navigator-tool-icon .ri-file-line'),
|
|
199
|
+
).not.toBeInTheDocument();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('falls back to placeholder icon when image fails to load', () => {
|
|
203
|
+
const { container } = renderCard({
|
|
204
|
+
title: 'Tool with broken image',
|
|
205
|
+
href: '/tools/broken-tool',
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const img = container.querySelector('.navigator-tool-icon img');
|
|
209
|
+
expect(img).toBeInTheDocument();
|
|
210
|
+
|
|
211
|
+
// Fire error event on image (e.g. 404 from backend)
|
|
212
|
+
fireEvent.error(img);
|
|
213
|
+
|
|
214
|
+
expect(
|
|
215
|
+
container.querySelector('.navigator-tool-icon img'),
|
|
216
|
+
).not.toBeInTheDocument();
|
|
217
|
+
expect(
|
|
218
|
+
container.querySelector('.navigator-tool-icon .ri-file-line'),
|
|
219
|
+
).toBeInTheDocument();
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('renders placeholder icon directly when item has no image or href', () => {
|
|
223
|
+
const { container } = renderCard({
|
|
224
|
+
title: 'Tool without image',
|
|
225
|
+
image: null,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
expect(
|
|
229
|
+
container.querySelector('.navigator-tool-icon img'),
|
|
230
|
+
).not.toBeInTheDocument();
|
|
231
|
+
expect(
|
|
232
|
+
container.querySelector('.navigator-tool-icon .ri-file-line'),
|
|
233
|
+
).toBeInTheDocument();
|
|
234
|
+
});
|
|
235
|
+
});
|
|
173
236
|
});
|
|
@@ -124,12 +124,6 @@ export const exportComparisonTable = (tools, getToolField) => {
|
|
|
124
124
|
formatFunctionalityScore(getToolField(tool, 'functionality')),
|
|
125
125
|
),
|
|
126
126
|
],
|
|
127
|
-
[
|
|
128
|
-
'Spatial scale',
|
|
129
|
-
...tools.map((tool) =>
|
|
130
|
-
arrayFieldToString(getToolField(tool, 'cca_geographical_scale')),
|
|
131
|
-
),
|
|
132
|
-
],
|
|
133
127
|
[
|
|
134
128
|
'Output type',
|
|
135
129
|
...tools.map((tool) =>
|
|
@@ -144,12 +138,6 @@ export const exportComparisonTable = (tools, getToolField) => {
|
|
|
144
138
|
),
|
|
145
139
|
),
|
|
146
140
|
],
|
|
147
|
-
[
|
|
148
|
-
'Sector',
|
|
149
|
-
...tools.map((tool) =>
|
|
150
|
-
arrayFieldToString(getToolField(tool, 'cca_adaptation_sectors')),
|
|
151
|
-
),
|
|
152
|
-
],
|
|
153
141
|
];
|
|
154
142
|
|
|
155
143
|
downloadCsv('navigator-catalogue-comparison.csv', rows);
|
|
@@ -104,10 +104,8 @@ describe('Navigator Catalogue utilities', () => {
|
|
|
104
104
|
values: {
|
|
105
105
|
accessibility_and_usability: 'High',
|
|
106
106
|
functionality: 5,
|
|
107
|
-
cca_geographical_scale: ['Local'],
|
|
108
107
|
cca_type_of_outputs: ['Maps'],
|
|
109
108
|
cca_adaptation_support_cycle_step: ['Step 1'],
|
|
110
|
-
cca_adaptation_sectors: ['Water'],
|
|
111
109
|
},
|
|
112
110
|
},
|
|
113
111
|
];
|
|
@@ -118,9 +116,7 @@ describe('Navigator Catalogue utilities', () => {
|
|
|
118
116
|
expect(csv).toContain('"Criteria","Tool A"');
|
|
119
117
|
expect(csv).toContain('"Usability","High"');
|
|
120
118
|
expect(csv).toContain('"Functionality","5/6"');
|
|
121
|
-
expect(csv).toContain('"Spatial scale","Local"');
|
|
122
119
|
expect(csv).toContain('"Output type","Maps"');
|
|
123
120
|
expect(csv).toContain('"Adaptation support cycle step","Step 1"');
|
|
124
|
-
expect(csv).toContain('"Sector","Water"');
|
|
125
121
|
});
|
|
126
122
|
});
|
|
@@ -6,6 +6,7 @@ import { defineMessages, useIntl } from 'react-intl';
|
|
|
6
6
|
import { Button, Checkbox, Icon, Loader, Message } from 'semantic-ui-react';
|
|
7
7
|
import URLManager from '@elastic/search-ui/lib/cjs/URLManager';
|
|
8
8
|
import { useSearchContext } from '@eeacms/search/lib/hocs';
|
|
9
|
+
import ToolThumbnail from '../../theme/ToolThumbnail/ToolThumbnail';
|
|
9
10
|
import guideSteps from '../../../search/navigator_guide/guideSteps';
|
|
10
11
|
import { navigatorGuideStepAtom } from '../../../state';
|
|
11
12
|
import { mergeGuideOptions } from './utils';
|
|
@@ -350,12 +351,10 @@ const NavigatorGuideContentView = ({ appConfig }) => {
|
|
|
350
351
|
className="navigator-guide-preview-result"
|
|
351
352
|
key={result._original?._id || result.href}
|
|
352
353
|
>
|
|
353
|
-
<
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
<Icon className="ri-stack-line" />
|
|
358
|
-
</div>
|
|
354
|
+
<ToolThumbnail
|
|
355
|
+
result={result}
|
|
356
|
+
fallbackIcon="ri-stack-line"
|
|
357
|
+
/>
|
|
359
358
|
<div className="navigator-guide-preview-result-content">
|
|
360
359
|
<small
|
|
361
360
|
className="navigator-tool-provider"
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import { fireEvent, render } from '@testing-library/react';
|
|
4
|
+
import { IntlProvider } from 'react-intl';
|
|
5
|
+
import { useAtom } from 'jotai';
|
|
6
|
+
import { useSelector } from 'react-redux';
|
|
7
|
+
import { useHistory } from 'react-router-dom';
|
|
8
|
+
import { useSearchContext } from '@eeacms/search/lib/hocs';
|
|
9
|
+
import NavigatorGuideContentView from './NavigatorGuideContentView';
|
|
10
|
+
import useGuideFacetOptions from './useGuideFacetOptions';
|
|
11
|
+
|
|
12
|
+
jest.mock('jotai', () => ({
|
|
13
|
+
...jest.requireActual('jotai'),
|
|
14
|
+
useAtom: jest.fn(),
|
|
15
|
+
}));
|
|
16
|
+
jest.mock('react-redux', () => ({ useSelector: jest.fn() }));
|
|
17
|
+
jest.mock('react-router-dom', () => ({ useHistory: jest.fn() }));
|
|
18
|
+
jest.mock('@eeacms/search/lib/hocs', () => ({ useSearchContext: jest.fn() }));
|
|
19
|
+
jest.mock('./useGuideFacetOptions', () => ({
|
|
20
|
+
__esModule: true,
|
|
21
|
+
default: jest.fn(),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
const renderGuide = (result) => {
|
|
25
|
+
useSearchContext.mockReturnValue({
|
|
26
|
+
filters: [{ field: 'cca_adaptation_sectors.keyword', values: ['Water'] }],
|
|
27
|
+
facets: {},
|
|
28
|
+
results: [result],
|
|
29
|
+
totalResults: 1,
|
|
30
|
+
isLoading: false,
|
|
31
|
+
});
|
|
32
|
+
return render(
|
|
33
|
+
<IntlProvider locale="en">
|
|
34
|
+
<NavigatorGuideContentView appConfig={{ previewResultsLimit: 3 }} />
|
|
35
|
+
</IntlProvider>,
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
describe('NavigatorGuideContentView thumbnails', () => {
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
jest.clearAllMocks();
|
|
42
|
+
useAtom.mockReturnValue([0, jest.fn()]);
|
|
43
|
+
useSelector.mockReturnValue('en');
|
|
44
|
+
useHistory.mockReturnValue({ push: jest.fn() });
|
|
45
|
+
useGuideFacetOptions.mockReturnValue({});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('shows the uploaded result image after loading, with a stack icon while loading', () => {
|
|
49
|
+
const { container } = renderGuide({
|
|
50
|
+
title: 'Guide tool',
|
|
51
|
+
href: '/tools/guide-tool',
|
|
52
|
+
image: { scales: { thumb: { download: '/uploaded-guide-thumb.jpg' } } },
|
|
53
|
+
});
|
|
54
|
+
const thumbnail = container.querySelector('.navigator-tool-icon');
|
|
55
|
+
const img = thumbnail.querySelector('img');
|
|
56
|
+
|
|
57
|
+
expect(thumbnail).toHaveClass('medium');
|
|
58
|
+
expect(thumbnail).toHaveAttribute('aria-hidden', 'true');
|
|
59
|
+
expect(img).toHaveAttribute('src', '/uploaded-guide-thumb.jpg');
|
|
60
|
+
expect(img).toHaveStyle({ display: 'none' });
|
|
61
|
+
expect(thumbnail.querySelector('.ri-stack-line')).toBeInTheDocument();
|
|
62
|
+
|
|
63
|
+
fireEvent.load(img);
|
|
64
|
+
|
|
65
|
+
expect(img).not.toHaveStyle({ display: 'none' });
|
|
66
|
+
expect(thumbnail.querySelector('.ri-stack-line')).not.toBeInTheDocument();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('falls back to the stack icon when the image fails', () => {
|
|
70
|
+
const { container } = renderGuide({
|
|
71
|
+
title: 'Guide tool',
|
|
72
|
+
href: '/tools/guide-tool',
|
|
73
|
+
image: '/broken.jpg',
|
|
74
|
+
});
|
|
75
|
+
const thumbnail = container.querySelector('.navigator-tool-icon');
|
|
76
|
+
|
|
77
|
+
fireEvent.error(thumbnail.querySelector('img'));
|
|
78
|
+
|
|
79
|
+
expect(thumbnail.querySelector('img')).not.toBeInTheDocument();
|
|
80
|
+
expect(thumbnail.querySelector('.ri-stack-line')).toBeInTheDocument();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it.each([null, false])('shows the stack icon for image: %s', (image) => {
|
|
84
|
+
const { container } = renderGuide({
|
|
85
|
+
title: 'Guide tool',
|
|
86
|
+
href: '/tools/guide-tool',
|
|
87
|
+
image,
|
|
88
|
+
});
|
|
89
|
+
const thumbnail = container.querySelector('.navigator-tool-icon');
|
|
90
|
+
|
|
91
|
+
expect(thumbnail.querySelector('img')).not.toBeInTheDocument();
|
|
92
|
+
expect(thumbnail.querySelector('.ri-stack-line')).toBeInTheDocument();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -4,6 +4,7 @@ import { useSelector } from 'react-redux';
|
|
|
4
4
|
import { useHistory } from 'react-router-dom';
|
|
5
5
|
import { Icon, Button } from 'semantic-ui-react';
|
|
6
6
|
import { defineMessages, useIntl } from 'react-intl';
|
|
7
|
+
import ToolThumbnail from '../ToolThumbnail/ToolThumbnail';
|
|
7
8
|
import {
|
|
8
9
|
MAX_COMPARE_TOOLS,
|
|
9
10
|
compareToolsAtom,
|
|
@@ -89,9 +90,7 @@ export const CompareToolsPanel = () => {
|
|
|
89
90
|
<div className="compare-panel-tools">
|
|
90
91
|
{effectiveSelectedTools.map((tool) => (
|
|
91
92
|
<div key={tool.uid} className="compare-panel-tool">
|
|
92
|
-
<
|
|
93
|
-
<Icon className="ri-file-line" />
|
|
94
|
-
</span>
|
|
93
|
+
<ToolThumbnail result={tool} size="small" />
|
|
95
94
|
<span className="compare-panel-tool-title">{tool.title}</span>
|
|
96
95
|
<Button
|
|
97
96
|
className="compare-panel-tool-clear"
|
|
@@ -101,4 +101,58 @@ describe('CompareToolsPanel', () => {
|
|
|
101
101
|
fireEvent.click(screen.getByText('Clear all'));
|
|
102
102
|
expect(screen.queryByText('Compare tools')).not.toBeInTheDocument();
|
|
103
103
|
});
|
|
104
|
+
|
|
105
|
+
it('shows the selected tool thumbnail after loading and preserves empty slot icons', () => {
|
|
106
|
+
const { container } = renderPanel([
|
|
107
|
+
{
|
|
108
|
+
uid: 'one',
|
|
109
|
+
title: 'Tool one',
|
|
110
|
+
href: '/tools/one',
|
|
111
|
+
image: '/uploaded-tool-thumb.jpg',
|
|
112
|
+
},
|
|
113
|
+
]);
|
|
114
|
+
const thumbnail = container.querySelector(
|
|
115
|
+
'.compare-panel-tool:not(.placeholder) .navigator-tool-icon',
|
|
116
|
+
);
|
|
117
|
+
const img = thumbnail.querySelector('img');
|
|
118
|
+
|
|
119
|
+
expect(thumbnail).toHaveClass('small');
|
|
120
|
+
expect(img).toHaveAttribute('src', '/uploaded-tool-thumb.jpg');
|
|
121
|
+
expect(img).toHaveStyle({ display: 'none' });
|
|
122
|
+
expect(thumbnail.querySelector('.ri-file-line')).toBeInTheDocument();
|
|
123
|
+
expect(
|
|
124
|
+
container.querySelectorAll('.placeholder .ri-add-line'),
|
|
125
|
+
).toHaveLength(3);
|
|
126
|
+
expect(container.querySelector('.placeholder img')).not.toBeInTheDocument();
|
|
127
|
+
|
|
128
|
+
fireEvent.load(img);
|
|
129
|
+
|
|
130
|
+
expect(img).not.toHaveStyle({ display: 'none' });
|
|
131
|
+
expect(thumbnail.querySelector('.ri-file-line')).not.toBeInTheDocument();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('uses the URL of an older saved selection and falls back on image error', () => {
|
|
135
|
+
const { container } = renderPanel([
|
|
136
|
+
{ uid: 'one', title: 'Tool one', href: '/tools/one' },
|
|
137
|
+
]);
|
|
138
|
+
const thumbnail = container.querySelector('.navigator-tool-icon');
|
|
139
|
+
const img = thumbnail.querySelector('img');
|
|
140
|
+
|
|
141
|
+
expect(img).toHaveAttribute('src', '/tools/one/@@images/image/thumb');
|
|
142
|
+
|
|
143
|
+
fireEvent.error(img);
|
|
144
|
+
|
|
145
|
+
expect(thumbnail.querySelector('img')).not.toBeInTheDocument();
|
|
146
|
+
expect(thumbnail.querySelector('.ri-file-line')).toBeInTheDocument();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it.each([null, false])('shows the file icon for image: %s', (image) => {
|
|
150
|
+
const { container } = renderPanel([
|
|
151
|
+
{ uid: 'one', title: 'Tool one', href: '/tools/one', image },
|
|
152
|
+
]);
|
|
153
|
+
const thumbnail = container.querySelector('.navigator-tool-icon');
|
|
154
|
+
|
|
155
|
+
expect(thumbnail.querySelector('img')).not.toBeInTheDocument();
|
|
156
|
+
expect(thumbnail.querySelector('.ri-file-line')).toBeInTheDocument();
|
|
157
|
+
});
|
|
104
158
|
});
|