@eeacms/volto-bise-policy 1.2.32 → 1.2.34
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 +34 -0
- package/package.json +3 -1
- package/src/components/Widgets/GeolocationWidget.jsx +143 -0
- package/src/components/Widgets/GeolocationWidgetMapContainer.jsx +131 -0
- package/src/components/Widgets/NRRWidgets.jsx +95 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyExplorerEdit.jsx +5 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyExplorerView.jsx +107 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyExplorerView.test.jsx +89 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyFilters.jsx +339 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyFilters.test.jsx +111 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyListing.jsx +330 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyListing.test.jsx +166 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.jsx +237 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.test.jsx +176 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureDisplay.jsx +41 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureDisplay.test.jsx +32 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureInteraction.jsx +98 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureInteraction.test.jsx +160 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/InfoOverlay.jsx +82 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/InfoOverlay.test.jsx +153 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/hooks.js +20 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/images/icon-depth.png +0 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/images/icon-light.png +0 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/images/search.svg +3 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/index.js +16 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/mockJsdom.js +8 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/styles.less +359 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/styles.less_old +201 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/utils.js +144 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/utils.test.js +88 -0
- package/src/components/manage/Blocks/index.js +2 -0
- package/src/express-middleware.js +37 -0
- package/src/index.js +29 -0
- package/theme/globals/site.overrides +12 -4
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
centerAndResetMapZoom,
|
|
6
|
+
scrollToElement,
|
|
7
|
+
zoomMapToFeatures,
|
|
8
|
+
} from './utils';
|
|
9
|
+
|
|
10
|
+
const showPageNr = (pageNr, currentPage, numberOfPages) => {
|
|
11
|
+
// show first 5 pages
|
|
12
|
+
if (currentPage < 4 && pageNr <= 5) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// show last 5 pages
|
|
17
|
+
if (numberOfPages - currentPage < 4 && numberOfPages - pageNr < 5) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (
|
|
22
|
+
currentPage >= 4 &&
|
|
23
|
+
numberOfPages - currentPage >= 4 &&
|
|
24
|
+
pageNr >= currentPage - 2 &&
|
|
25
|
+
pageNr <= currentPage + 2
|
|
26
|
+
) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function CaseStudyList(props) {
|
|
34
|
+
const { selectedCase, onSelectedCase, pointsSource, map, searchInput, ol } =
|
|
35
|
+
props;
|
|
36
|
+
const reSearch = new RegExp(`\\b(${searchInput})\\b`, 'gi');
|
|
37
|
+
const [currentPage, setCurrentPage] = React.useState(1);
|
|
38
|
+
|
|
39
|
+
const features = pointsSource
|
|
40
|
+
.getFeatures(selectedCase)
|
|
41
|
+
.sort((item1, item2) =>
|
|
42
|
+
item1.values_.title.localeCompare(item2.values_.title),
|
|
43
|
+
);
|
|
44
|
+
const numberOfPages = Math.ceil(features.length / 10);
|
|
45
|
+
|
|
46
|
+
const displayFatures = features.slice(
|
|
47
|
+
10 * (currentPage - 1),
|
|
48
|
+
10 * currentPage,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return displayFatures.length === 0 ? (
|
|
52
|
+
<>
|
|
53
|
+
<h3 style={{ margin: 'calc(2rem - 0.1em) 0 1rem' }}>
|
|
54
|
+
We could not find any results for your search criteria
|
|
55
|
+
</h3>
|
|
56
|
+
<ul>
|
|
57
|
+
<li>check the selected filters</li>
|
|
58
|
+
</ul>
|
|
59
|
+
</>
|
|
60
|
+
) : (
|
|
61
|
+
<>
|
|
62
|
+
<div className="listing">
|
|
63
|
+
{selectedCase ? (
|
|
64
|
+
<div
|
|
65
|
+
className="content-box u-item listing-item result-item"
|
|
66
|
+
style={{
|
|
67
|
+
marginTop: '2em',
|
|
68
|
+
padding: 'em',
|
|
69
|
+
// border: '3px solid #f2f2f2',
|
|
70
|
+
// borderTop: '1em solid #f2f2f2',
|
|
71
|
+
paddingTop: 0,
|
|
72
|
+
backgroundColor: '#f2f2f2',
|
|
73
|
+
border: 'none',
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
76
|
+
<div className="slot-top">
|
|
77
|
+
<div className="listing-body">
|
|
78
|
+
<h3 className="listing-header">
|
|
79
|
+
<a
|
|
80
|
+
target="_blank"
|
|
81
|
+
rel="noopener noreferrer"
|
|
82
|
+
href={selectedCase.path}
|
|
83
|
+
title={selectedCase.title}
|
|
84
|
+
datatest-id="selected-case"
|
|
85
|
+
>
|
|
86
|
+
{selectedCase.title}
|
|
87
|
+
</a>
|
|
88
|
+
</h3>
|
|
89
|
+
<p className="listing-description">
|
|
90
|
+
{selectedCase.description}
|
|
91
|
+
</p>
|
|
92
|
+
<div className="slot-bottom">
|
|
93
|
+
<div className="result-bottom">
|
|
94
|
+
{/* <div className="result-info">
|
|
95
|
+
<span className="result-info-title">Typology of measures:</span>
|
|
96
|
+
<span>
|
|
97
|
+
{selectedCase.typology_of_measures
|
|
98
|
+
? selectedCase.typology_of_measures.join(', ')
|
|
99
|
+
: ''}
|
|
100
|
+
</span>
|
|
101
|
+
</div> */}
|
|
102
|
+
{/* <div className="result-info">
|
|
103
|
+
<span className="result-info-title">
|
|
104
|
+
Measures implemented:
|
|
105
|
+
</span>
|
|
106
|
+
{selectedCase.measures_implemented.map((measure, index) => {
|
|
107
|
+
return (
|
|
108
|
+
<span>
|
|
109
|
+
<a
|
|
110
|
+
target="_blank"
|
|
111
|
+
rel="noopener noreferrer"
|
|
112
|
+
href={measure.path}
|
|
113
|
+
>
|
|
114
|
+
{measure.title}
|
|
115
|
+
{index !==
|
|
116
|
+
selectedCase.measures_implemented.length - 1
|
|
117
|
+
? ', '
|
|
118
|
+
: ''}
|
|
119
|
+
</a>
|
|
120
|
+
</span>
|
|
121
|
+
);
|
|
122
|
+
})}
|
|
123
|
+
</div> */}
|
|
124
|
+
<div
|
|
125
|
+
className="result-info show-on-map"
|
|
126
|
+
tabIndex="0"
|
|
127
|
+
role="button"
|
|
128
|
+
onKeyDown={() => {}}
|
|
129
|
+
onClick={() => {
|
|
130
|
+
// scroll to the map
|
|
131
|
+
scrollToElement('search-input');
|
|
132
|
+
// reset map zoom
|
|
133
|
+
onSelectedCase(null);
|
|
134
|
+
centerAndResetMapZoom({ map, ol });
|
|
135
|
+
map.getInteractions().array_[9].getFeatures().clear();
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
<span
|
|
139
|
+
className="result-info-title"
|
|
140
|
+
data-testid="reset-map"
|
|
141
|
+
>
|
|
142
|
+
Reset map
|
|
143
|
+
</span>
|
|
144
|
+
<i className="icon ri-map-2-line"></i>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
) : (
|
|
152
|
+
displayFatures.map((item, index) => {
|
|
153
|
+
return (
|
|
154
|
+
<div className="u-item listing-item result-item" key={index}>
|
|
155
|
+
<div className="slot-top">
|
|
156
|
+
<div className="listing-body">
|
|
157
|
+
<h3 className="listing-header">
|
|
158
|
+
<a
|
|
159
|
+
target="_blank"
|
|
160
|
+
rel="noopener noreferrer"
|
|
161
|
+
href={item.values_.path}
|
|
162
|
+
title={item.values_.title}
|
|
163
|
+
>
|
|
164
|
+
{item.values_.title}
|
|
165
|
+
</a>
|
|
166
|
+
</h3>
|
|
167
|
+
<p
|
|
168
|
+
className="listing-description"
|
|
169
|
+
dangerouslySetInnerHTML={{
|
|
170
|
+
__html: searchInput
|
|
171
|
+
? item.values_.description.replaceAll(
|
|
172
|
+
reSearch,
|
|
173
|
+
'<b>$1</b>',
|
|
174
|
+
)
|
|
175
|
+
: item.values_.description,
|
|
176
|
+
}}
|
|
177
|
+
></p>
|
|
178
|
+
<div className="slot-bottom">
|
|
179
|
+
<div className="result-bottom">
|
|
180
|
+
{/* <div className="result-info">
|
|
181
|
+
<span className="result-info-title">Typology of measures:</span>
|
|
182
|
+
<span>{item.values_.typology_of_measures.join(', ')}</span>
|
|
183
|
+
</div> */}
|
|
184
|
+
{/* <div className="result-info">
|
|
185
|
+
<span className="result-info-title">
|
|
186
|
+
Measures implemented:
|
|
187
|
+
</span>
|
|
188
|
+
|
|
189
|
+
{item.values_.measures_implemented.map(
|
|
190
|
+
(measure, index) => {
|
|
191
|
+
return (
|
|
192
|
+
<span key={index}>
|
|
193
|
+
<a
|
|
194
|
+
target="_blank"
|
|
195
|
+
rel="noopener noreferrer"
|
|
196
|
+
href={measure.path}
|
|
197
|
+
>
|
|
198
|
+
{measure.title}
|
|
199
|
+
{index !==
|
|
200
|
+
item.values_.measures_implemented.length - 1
|
|
201
|
+
? ', '
|
|
202
|
+
: ''}
|
|
203
|
+
</a>
|
|
204
|
+
</span>
|
|
205
|
+
);
|
|
206
|
+
},
|
|
207
|
+
)}
|
|
208
|
+
</div> */}
|
|
209
|
+
<div
|
|
210
|
+
className="result-info show-on-map"
|
|
211
|
+
tabIndex="0"
|
|
212
|
+
role="button"
|
|
213
|
+
onKeyDown={() => {}}
|
|
214
|
+
onClick={() => {
|
|
215
|
+
map
|
|
216
|
+
.getInteractions()
|
|
217
|
+
.array_[9].getFeatures()
|
|
218
|
+
.clear();
|
|
219
|
+
// scroll to the map
|
|
220
|
+
scrollToElement('ol-map-container');
|
|
221
|
+
|
|
222
|
+
zoomMapToFeatures({
|
|
223
|
+
map,
|
|
224
|
+
features: [item],
|
|
225
|
+
threshold: 5000,
|
|
226
|
+
ol,
|
|
227
|
+
});
|
|
228
|
+
onSelectedCase(item.values_);
|
|
229
|
+
|
|
230
|
+
setTimeout(() => {
|
|
231
|
+
const coords =
|
|
232
|
+
item.values_.geometry.flatCoordinates;
|
|
233
|
+
const pixel = map.getPixelFromCoordinate(coords);
|
|
234
|
+
map
|
|
235
|
+
.getInteractions()
|
|
236
|
+
.array_[9].getFeatures()
|
|
237
|
+
.push(map.getFeaturesAtPixel(pixel)[0]);
|
|
238
|
+
}, 1100);
|
|
239
|
+
}}
|
|
240
|
+
>
|
|
241
|
+
<span className="result-info-title">Show on map</span>
|
|
242
|
+
<i className="icon ri-road-map-line"></i>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
);
|
|
250
|
+
})
|
|
251
|
+
)}
|
|
252
|
+
</div>
|
|
253
|
+
{!selectedCase ? (
|
|
254
|
+
<div className="search-body-footer">
|
|
255
|
+
<div className="ui centered grid">
|
|
256
|
+
<div className="center aligned column">
|
|
257
|
+
<div className="prev-next-paging">
|
|
258
|
+
<div className="paging-wrapper">
|
|
259
|
+
{currentPage !== 1 ? (
|
|
260
|
+
<button
|
|
261
|
+
className="ui button prev double-angle"
|
|
262
|
+
onClick={() => {
|
|
263
|
+
setCurrentPage(1);
|
|
264
|
+
}}
|
|
265
|
+
></button>
|
|
266
|
+
) : (
|
|
267
|
+
''
|
|
268
|
+
)}
|
|
269
|
+
{currentPage !== 1 ? (
|
|
270
|
+
<button
|
|
271
|
+
className="ui button prev single-angle"
|
|
272
|
+
onClick={() => {
|
|
273
|
+
setCurrentPage(currentPage - 1);
|
|
274
|
+
}}
|
|
275
|
+
></button>
|
|
276
|
+
) : (
|
|
277
|
+
''
|
|
278
|
+
)}
|
|
279
|
+
{Array.from(Array(numberOfPages).keys()).map((index) => {
|
|
280
|
+
const pageNr = index + 1;
|
|
281
|
+
return showPageNr(pageNr, currentPage, numberOfPages) ? (
|
|
282
|
+
<button
|
|
283
|
+
className={
|
|
284
|
+
'ui button pagination-item' +
|
|
285
|
+
(currentPage === pageNr ? ' active' : '')
|
|
286
|
+
}
|
|
287
|
+
onClick={() => {
|
|
288
|
+
setCurrentPage(pageNr);
|
|
289
|
+
}}
|
|
290
|
+
key={index}
|
|
291
|
+
>
|
|
292
|
+
{pageNr}
|
|
293
|
+
</button>
|
|
294
|
+
) : (
|
|
295
|
+
''
|
|
296
|
+
);
|
|
297
|
+
})}
|
|
298
|
+
{currentPage !== numberOfPages ? (
|
|
299
|
+
<button
|
|
300
|
+
className="ui button next single-angle"
|
|
301
|
+
onClick={() => {
|
|
302
|
+
setCurrentPage(currentPage + 1);
|
|
303
|
+
}}
|
|
304
|
+
></button>
|
|
305
|
+
) : (
|
|
306
|
+
''
|
|
307
|
+
)}
|
|
308
|
+
{currentPage !== numberOfPages ? (
|
|
309
|
+
<button
|
|
310
|
+
className="ui button next double-angle"
|
|
311
|
+
onClick={() => {
|
|
312
|
+
setCurrentPage(numberOfPages);
|
|
313
|
+
}}
|
|
314
|
+
></button>
|
|
315
|
+
) : (
|
|
316
|
+
''
|
|
317
|
+
)}{' '}
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
) : (
|
|
324
|
+
''
|
|
325
|
+
)}
|
|
326
|
+
</>
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export default withOpenLayers(CaseStudyList);
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, fireEvent } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import CaseStudyList from './CaseStudyListing';
|
|
5
|
+
import {
|
|
6
|
+
centerAndResetMapZoom,
|
|
7
|
+
scrollToElement,
|
|
8
|
+
zoomMapToFeatures,
|
|
9
|
+
} from './utils';
|
|
10
|
+
|
|
11
|
+
jest.mock('@eeacms/volto-openlayers-map', () => ({
|
|
12
|
+
withOpenLayers: (Component) => Component,
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
jest.mock('./utils', () => ({
|
|
16
|
+
centerAndResetMapZoom: jest.fn(),
|
|
17
|
+
scrollToElement: jest.fn(),
|
|
18
|
+
zoomMapToFeatures: jest.fn(),
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
const mockMap = {
|
|
22
|
+
getInteractions: () => ({
|
|
23
|
+
array_: [
|
|
24
|
+
{},
|
|
25
|
+
{},
|
|
26
|
+
{},
|
|
27
|
+
{},
|
|
28
|
+
{},
|
|
29
|
+
{},
|
|
30
|
+
{},
|
|
31
|
+
{},
|
|
32
|
+
{},
|
|
33
|
+
{
|
|
34
|
+
getFeatures: () => ({
|
|
35
|
+
clear: jest.fn(),
|
|
36
|
+
push: jest.fn(),
|
|
37
|
+
}),
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
}),
|
|
41
|
+
getPixelFromCoordinate: jest.fn(() => [100, 200]),
|
|
42
|
+
getFeaturesAtPixel: jest.fn(() => ['mockFeature']),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const mockPointsSource = {
|
|
46
|
+
getFeatures: () => [
|
|
47
|
+
{
|
|
48
|
+
values_: {
|
|
49
|
+
title: 'Feature 1',
|
|
50
|
+
path: '/feature1',
|
|
51
|
+
description: 'Description 1',
|
|
52
|
+
typology_of_measures: ['SectorA'],
|
|
53
|
+
measures_implemented: [{ title: 'M1', path: '/m1' }],
|
|
54
|
+
geometry: { flatCoordinates: [0, 0] },
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const selectedCase = {
|
|
61
|
+
title: 'Selected Title',
|
|
62
|
+
path: '/selected',
|
|
63
|
+
description: 'Selected description',
|
|
64
|
+
typology_of_measures: ['S1', 'S2'],
|
|
65
|
+
measures_implemented: [{ title: 'M1', path: '/m1' }],
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
describe('CaseStudyList', () => {
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
jest.clearAllMocks();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('renders empty state when no features', () => {
|
|
74
|
+
const emptyPointsSource = { getFeatures: () => [] };
|
|
75
|
+
const { getByText } = render(
|
|
76
|
+
<CaseStudyList
|
|
77
|
+
selectedCase={null}
|
|
78
|
+
onSelectedCase={jest.fn()}
|
|
79
|
+
pointsSource={emptyPointsSource}
|
|
80
|
+
searchInput=""
|
|
81
|
+
ol={{}}
|
|
82
|
+
/>,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
expect(
|
|
86
|
+
getByText('We could not find any results for your search criteria'),
|
|
87
|
+
).toBeInTheDocument();
|
|
88
|
+
expect(getByText('check the selected filters')).toBeInTheDocument();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('renders selectedCase details', () => {
|
|
92
|
+
const { getByText } = render(
|
|
93
|
+
<CaseStudyList
|
|
94
|
+
selectedCase={selectedCase}
|
|
95
|
+
onSelectedCase={jest.fn()}
|
|
96
|
+
pointsSource={mockPointsSource}
|
|
97
|
+
map={mockMap}
|
|
98
|
+
searchInput=""
|
|
99
|
+
ol={{}}
|
|
100
|
+
/>,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(getByText('Selected Title')).toBeInTheDocument();
|
|
104
|
+
expect(getByText('Selected description')).toBeInTheDocument();
|
|
105
|
+
// Note: Sectors and NWRMs sections are commented out in the component
|
|
106
|
+
// So we only check the title and description render
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('calls reset map utils when clicking Reset map', () => {
|
|
110
|
+
const { getByTestId } = render(
|
|
111
|
+
<CaseStudyList
|
|
112
|
+
selectedCase={selectedCase}
|
|
113
|
+
onSelectedCase={jest.fn()}
|
|
114
|
+
pointsSource={mockPointsSource}
|
|
115
|
+
map={mockMap}
|
|
116
|
+
searchInput=""
|
|
117
|
+
ol={{}}
|
|
118
|
+
/>,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
fireEvent.click(getByTestId('reset-map'));
|
|
122
|
+
|
|
123
|
+
expect(scrollToElement).toHaveBeenCalledWith('search-input');
|
|
124
|
+
expect(centerAndResetMapZoom).toHaveBeenCalledWith({
|
|
125
|
+
map: mockMap,
|
|
126
|
+
ol: {},
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('renders features and highlights search term', () => {
|
|
131
|
+
const { getByText } = render(
|
|
132
|
+
<CaseStudyList
|
|
133
|
+
selectedCase={null}
|
|
134
|
+
onSelectedCase={jest.fn()}
|
|
135
|
+
pointsSource={mockPointsSource}
|
|
136
|
+
map={mockMap}
|
|
137
|
+
searchInput="match"
|
|
138
|
+
ol={{}}
|
|
139
|
+
/>,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
expect(getByText('Feature 1')).toBeInTheDocument();
|
|
143
|
+
expect(getByText('Feature 1').getAttribute('href')).toBe('/feature1');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('calls zoomMapToFeatures and onSelectedCase when clicking Show on map', async () => {
|
|
147
|
+
const onSelectedCase = jest.fn();
|
|
148
|
+
|
|
149
|
+
const { getByText } = render(
|
|
150
|
+
<CaseStudyList
|
|
151
|
+
selectedCase={null}
|
|
152
|
+
onSelectedCase={onSelectedCase}
|
|
153
|
+
pointsSource={mockPointsSource}
|
|
154
|
+
map={mockMap}
|
|
155
|
+
searchInput=""
|
|
156
|
+
ol={{}}
|
|
157
|
+
/>,
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
fireEvent.click(getByText('Show on map'));
|
|
161
|
+
|
|
162
|
+
expect(scrollToElement).toHaveBeenCalledWith('ol-map-container');
|
|
163
|
+
expect(zoomMapToFeatures).toHaveBeenCalled();
|
|
164
|
+
expect(onSelectedCase).toHaveBeenCalled();
|
|
165
|
+
});
|
|
166
|
+
});
|