@eeacms/volto-eea-website-theme 3.7.0 → 3.9.0
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 +19 -2
- package/package.json +3 -1
- package/src/actions/index.js +1 -0
- package/src/actions/navigation.js +24 -0
- package/src/actions/print.js +9 -1
- package/src/components/manage/Blocks/ContextNavigation/variations/Accordion.jsx +42 -35
- package/src/components/manage/Blocks/LayoutSettings/LayoutSettingsEdit.test.jsx +383 -0
- package/src/components/manage/Blocks/Title/variations/WebReportPage.test.jsx +232 -0
- package/src/components/theme/Banner/View.jsx +11 -92
- package/src/components/theme/PrintLoader/PrintLoader.jsx +56 -0
- package/src/components/theme/PrintLoader/PrintLoader.test.jsx +91 -0
- package/src/components/theme/PrintLoader/style.less +12 -0
- package/src/components/theme/WebReport/WebReportSectionView.test.jsx +462 -0
- package/src/components/theme/Widgets/ImageViewWidget.test.jsx +26 -0
- package/src/components/theme/Widgets/NavigationBehaviorWidget.jsx +601 -0
- package/src/components/theme/Widgets/NavigationBehaviorWidget.test.jsx +507 -0
- package/src/components/theme/Widgets/SimpleArrayWidget.jsx +183 -0
- package/src/components/theme/Widgets/SimpleArrayWidget.test.jsx +283 -0
- package/src/constants/ActionTypes.js +2 -0
- package/src/customizations/volto/components/manage/History/History.diff +207 -0
- package/src/customizations/volto/components/manage/History/History.jsx +444 -0
- package/src/customizations/volto/components/theme/Comments/Comments.jsx +9 -2
- package/src/customizations/volto/components/theme/Comments/Comments.test.jsx +4 -4
- package/src/customizations/volto/components/theme/Comments/comments.less +16 -0
- package/src/customizations/volto/components/theme/Header/Header.jsx +60 -1
- package/src/customizations/volto/components/theme/View/DefaultView.jsx +42 -33
- package/src/customizations/volto/helpers/Html/Html.jsx +212 -0
- package/src/customizations/volto/helpers/Html/Readme.md +1 -0
- package/src/customizations/volto/server.jsx +375 -0
- package/src/helpers/loadLazyImages.js +11 -0
- package/src/helpers/loadLazyImages.test.js +22 -0
- package/src/helpers/setupPrintView.js +134 -0
- package/src/helpers/setupPrintView.test.js +49 -0
- package/src/index.js +11 -1
- package/src/index.test.js +6 -0
- package/src/middleware/voltoCustom.test.js +282 -0
- package/src/reducers/index.js +2 -1
- package/src/reducers/navigation/navigation.js +47 -0
- package/src/reducers/navigation/navigation.test.js +348 -0
- package/src/reducers/navigation.js +55 -0
- package/src/reducers/print.js +18 -8
- package/src/reducers/print.test.js +117 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import WebReportPage from './WebReportPage';
|
|
4
|
+
|
|
5
|
+
// Add jest-dom matchers
|
|
6
|
+
import '@testing-library/jest-dom';
|
|
7
|
+
|
|
8
|
+
// Mock dependencies
|
|
9
|
+
jest.mock('react-portal', () => ({
|
|
10
|
+
Portal: ({ children, node }) => (
|
|
11
|
+
<div data-testid="portal" data-node={node?.tagName}>
|
|
12
|
+
{children}
|
|
13
|
+
</div>
|
|
14
|
+
),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
jest.mock('@plone/volto/components', () => ({
|
|
18
|
+
MaybeWrap: ({ children, condition, as: Component }) =>
|
|
19
|
+
condition ? <Component>{children}</Component> : <div>{children}</div>,
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
jest.mock(
|
|
23
|
+
'@eeacms/volto-eea-website-theme/components/theme/Banner/View',
|
|
24
|
+
() => {
|
|
25
|
+
return function MockBannerView({ data, ...props }) {
|
|
26
|
+
// Safe JSON stringify that handles circular references
|
|
27
|
+
const safeStringify = (obj) => {
|
|
28
|
+
try {
|
|
29
|
+
return JSON.stringify(obj, (key, value) => {
|
|
30
|
+
if (key === 'aboveTitle') return '[React Element]';
|
|
31
|
+
if (typeof value === 'object' && value !== null && value.$$typeof)
|
|
32
|
+
return '[React Element]';
|
|
33
|
+
return value;
|
|
34
|
+
});
|
|
35
|
+
} catch (e) {
|
|
36
|
+
return '[Circular Reference]';
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div data-testid="banner-view" data-props={safeStringify(props)}>
|
|
42
|
+
<div data-testid="banner-data">{safeStringify(data)}</div>
|
|
43
|
+
{data.aboveTitle && (
|
|
44
|
+
<div data-testid="above-title">{data.aboveTitle}</div>
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
jest.mock('clsx', () => jest.fn((classes) => classes));
|
|
53
|
+
|
|
54
|
+
jest.mock('@plone/volto/helpers', () => ({
|
|
55
|
+
BodyClass: ({ className }) => (
|
|
56
|
+
<div data-testid="body-class" data-classname={className} />
|
|
57
|
+
),
|
|
58
|
+
}));
|
|
59
|
+
|
|
60
|
+
describe('WebReportPage', () => {
|
|
61
|
+
const defaultProps = {
|
|
62
|
+
data: {
|
|
63
|
+
title: 'Test Report Title',
|
|
64
|
+
subtitle: 'Test Subtitle',
|
|
65
|
+
content_type: 'Report',
|
|
66
|
+
hideContentType: false,
|
|
67
|
+
},
|
|
68
|
+
properties: {
|
|
69
|
+
type_title: 'Default Type Title',
|
|
70
|
+
},
|
|
71
|
+
isEditMode: false,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
beforeEach(() => {
|
|
75
|
+
// Mock document.querySelector for Portal
|
|
76
|
+
document.querySelector = jest.fn().mockReturnValue({
|
|
77
|
+
tagName: 'HEADER',
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
afterEach(() => {
|
|
82
|
+
jest.restoreAllMocks();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('renders without crashing', () => {
|
|
86
|
+
render(<WebReportPage {...defaultProps} />);
|
|
87
|
+
expect(screen.getByTestId('banner-view')).toBeInTheDocument();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('renders in Portal when not in edit mode', () => {
|
|
91
|
+
render(<WebReportPage {...defaultProps} />);
|
|
92
|
+
expect(screen.getByTestId('portal')).toBeInTheDocument();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('does not render in Portal when in edit mode', () => {
|
|
96
|
+
const props = { ...defaultProps, isEditMode: true };
|
|
97
|
+
render(<WebReportPage {...props} />);
|
|
98
|
+
expect(screen.queryByTestId('portal')).not.toBeInTheDocument();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('renders BodyClass with correct className', () => {
|
|
102
|
+
render(<WebReportPage {...defaultProps} />);
|
|
103
|
+
expect(screen.getByTestId('body-class')).toHaveAttribute(
|
|
104
|
+
'data-classname',
|
|
105
|
+
'homepage-inverse light-header',
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('renders content type when not hidden', () => {
|
|
110
|
+
render(<WebReportPage {...defaultProps} />);
|
|
111
|
+
const aboveTitle = screen.getByTestId('above-title');
|
|
112
|
+
expect(aboveTitle).toHaveTextContent('Report');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('does not render content type when hidden', () => {
|
|
116
|
+
const props = {
|
|
117
|
+
...defaultProps,
|
|
118
|
+
data: { ...defaultProps.data, hideContentType: true },
|
|
119
|
+
};
|
|
120
|
+
render(<WebReportPage {...props} />);
|
|
121
|
+
const aboveTitle = screen.getByTestId('above-title');
|
|
122
|
+
expect(aboveTitle).not.toHaveTextContent('Report');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('uses properties.type_title when data.content_type is not provided', () => {
|
|
126
|
+
const props = {
|
|
127
|
+
...defaultProps,
|
|
128
|
+
data: { ...defaultProps.data, content_type: undefined },
|
|
129
|
+
};
|
|
130
|
+
render(<WebReportPage {...props} />);
|
|
131
|
+
const aboveTitle = screen.getByTestId('above-title');
|
|
132
|
+
expect(aboveTitle).toHaveTextContent('Default Type Title');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('renders subtitle', () => {
|
|
136
|
+
render(<WebReportPage {...defaultProps} />);
|
|
137
|
+
const aboveTitle = screen.getByTestId('above-title');
|
|
138
|
+
expect(aboveTitle).toHaveTextContent('Test Subtitle');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('passes all props to BannerView', () => {
|
|
142
|
+
const customProps = {
|
|
143
|
+
...defaultProps,
|
|
144
|
+
customProp: 'custom-value',
|
|
145
|
+
anotherProp: { nested: 'object' },
|
|
146
|
+
};
|
|
147
|
+
render(<WebReportPage {...customProps} />);
|
|
148
|
+
|
|
149
|
+
const bannerPropsText = screen
|
|
150
|
+
.getByTestId('banner-view')
|
|
151
|
+
.getAttribute('data-props');
|
|
152
|
+
expect(bannerPropsText).toContain('custom-value');
|
|
153
|
+
expect(bannerPropsText).toContain('nested');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('merges data with aboveTitle correctly', () => {
|
|
157
|
+
render(<WebReportPage {...defaultProps} />);
|
|
158
|
+
|
|
159
|
+
const bannerDataText = screen.getByTestId('banner-data').textContent;
|
|
160
|
+
expect(bannerDataText).toContain('Test Report Title');
|
|
161
|
+
expect(bannerDataText).toContain('Test Subtitle');
|
|
162
|
+
expect(bannerDataText).toContain('[React Element]'); // aboveTitle is a React element
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('handles missing subtitle gracefully', () => {
|
|
166
|
+
const props = {
|
|
167
|
+
...defaultProps,
|
|
168
|
+
data: { ...defaultProps.data, subtitle: undefined },
|
|
169
|
+
};
|
|
170
|
+
render(<WebReportPage {...props} />);
|
|
171
|
+
expect(screen.getByTestId('banner-view')).toBeInTheDocument();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('handles missing content_type and type_title gracefully', () => {
|
|
175
|
+
const props = {
|
|
176
|
+
...defaultProps,
|
|
177
|
+
data: { ...defaultProps.data, content_type: undefined },
|
|
178
|
+
properties: { ...defaultProps.properties, type_title: undefined },
|
|
179
|
+
};
|
|
180
|
+
render(<WebReportPage {...props} />);
|
|
181
|
+
expect(screen.getByTestId('banner-view')).toBeInTheDocument();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe('IsomorphicPortal', () => {
|
|
185
|
+
it('renders children directly on server side', () => {
|
|
186
|
+
// Mock useState to simulate server-side rendering
|
|
187
|
+
const originalUseState = React.useState;
|
|
188
|
+
React.useState = jest.fn().mockReturnValue([false, jest.fn()]);
|
|
189
|
+
|
|
190
|
+
render(<WebReportPage {...defaultProps} />);
|
|
191
|
+
expect(screen.getByTestId('banner-view')).toBeInTheDocument();
|
|
192
|
+
|
|
193
|
+
React.useState = originalUseState;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('renders in Portal on client side', () => {
|
|
197
|
+
// Mock useState to simulate client-side rendering
|
|
198
|
+
const originalUseState = React.useState;
|
|
199
|
+
const mockSetIsClient = jest.fn();
|
|
200
|
+
React.useState = jest.fn().mockReturnValue([true, mockSetIsClient]);
|
|
201
|
+
|
|
202
|
+
render(<WebReportPage {...defaultProps} />);
|
|
203
|
+
expect(screen.getByTestId('portal')).toBeInTheDocument();
|
|
204
|
+
|
|
205
|
+
React.useState = originalUseState;
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('calls setIsClient in useEffect', () => {
|
|
209
|
+
const originalUseState = React.useState;
|
|
210
|
+
const originalUseEffect = React.useEffect;
|
|
211
|
+
|
|
212
|
+
const mockSetIsClient = jest.fn();
|
|
213
|
+
React.useState = jest.fn().mockReturnValue([false, mockSetIsClient]);
|
|
214
|
+
React.useEffect = jest.fn().mockImplementation((fn) => fn());
|
|
215
|
+
|
|
216
|
+
render(<WebReportPage {...defaultProps} />);
|
|
217
|
+
|
|
218
|
+
expect(mockSetIsClient).toHaveBeenCalledWith(true);
|
|
219
|
+
|
|
220
|
+
React.useState = originalUseState;
|
|
221
|
+
React.useEffect = originalUseEffect;
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('handles document.querySelector returning null', () => {
|
|
226
|
+
document.querySelector = jest.fn().mockReturnValue(null);
|
|
227
|
+
|
|
228
|
+
expect(() => {
|
|
229
|
+
render(<WebReportPage {...defaultProps} />);
|
|
230
|
+
}).not.toThrow();
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -5,7 +5,7 @@ import { connect, useDispatch } from 'react-redux';
|
|
|
5
5
|
import { withRouter } from 'react-router';
|
|
6
6
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
7
7
|
import startCase from 'lodash/startCase';
|
|
8
|
-
import { Icon
|
|
8
|
+
import { Icon } from 'semantic-ui-react';
|
|
9
9
|
import Popup from '@eeacms/volto-eea-design-system/ui/Popup/Popup';
|
|
10
10
|
import config from '@plone/volto/registry';
|
|
11
11
|
import Banner from '@eeacms/volto-eea-design-system/ui/Banner/Banner';
|
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
sharePage,
|
|
15
15
|
} from '@eeacms/volto-eea-design-system/ui/Banner/Banner';
|
|
16
16
|
import Copyright from '@eeacms/volto-eea-design-system/ui/Copyright/Copyright';
|
|
17
|
-
import {
|
|
18
|
-
|
|
17
|
+
import { setupPrintView } from '@eeacms/volto-eea-website-theme/helpers/setupPrintView';
|
|
18
|
+
|
|
19
19
|
import './styles.less';
|
|
20
20
|
|
|
21
21
|
const messages = defineMessages({
|
|
@@ -173,95 +173,14 @@ const View = (props) => {
|
|
|
173
173
|
</>
|
|
174
174
|
)}
|
|
175
175
|
{!hideDownloadButton && (
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
Array.from(tabs).forEach((tab) => {
|
|
185
|
-
tab.style.display = 'block';
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
dispatch(setIsPrint(true));
|
|
189
|
-
// display loader
|
|
190
|
-
const printLoader = document.getElementById(
|
|
191
|
-
'download-print-loader',
|
|
192
|
-
);
|
|
193
|
-
printLoader.style.display = 'flex';
|
|
194
|
-
|
|
195
|
-
let timeoutValue = 1000;
|
|
196
|
-
// if we have plotlycharts increase timeout
|
|
197
|
-
setTimeout(() => {
|
|
198
|
-
const plotlyCharts = document.getElementsByClassName(
|
|
199
|
-
'visualization-wrapper',
|
|
200
|
-
);
|
|
201
|
-
if (plotlyCharts.length > 0) {
|
|
202
|
-
timeoutValue = timeoutValue + 1000;
|
|
203
|
-
}
|
|
204
|
-
}, timeoutValue);
|
|
205
|
-
|
|
206
|
-
// scroll to iframes to make them be in the viewport
|
|
207
|
-
// use timeout to wait for load
|
|
208
|
-
setTimeout(() => {
|
|
209
|
-
const iframes = document.getElementsByTagName('iframe');
|
|
210
|
-
if (iframes.length > 0) {
|
|
211
|
-
timeoutValue = timeoutValue + 2000;
|
|
212
|
-
Array.from(iframes).forEach((element, index) => {
|
|
213
|
-
setTimeout(() => {
|
|
214
|
-
element.scrollIntoView({
|
|
215
|
-
behavior: 'instant',
|
|
216
|
-
block: 'nearest',
|
|
217
|
-
inline: 'center',
|
|
218
|
-
});
|
|
219
|
-
}, timeoutValue);
|
|
220
|
-
timeoutValue = timeoutValue + 3000;
|
|
221
|
-
});
|
|
222
|
-
timeoutValue = timeoutValue + 1000;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
setTimeout(() => {
|
|
226
|
-
window.scrollTo({
|
|
227
|
-
top: 0,
|
|
228
|
-
});
|
|
229
|
-
Array.from(tabs).forEach((tab) => {
|
|
230
|
-
tab.style.display = '';
|
|
231
|
-
});
|
|
232
|
-
printLoader.style.display = 'none';
|
|
233
|
-
dispatch(setIsPrint(false));
|
|
234
|
-
window.print();
|
|
235
|
-
}, timeoutValue);
|
|
236
|
-
}, timeoutValue);
|
|
237
|
-
}}
|
|
238
|
-
/>
|
|
239
|
-
<div
|
|
240
|
-
id="download-print-loader"
|
|
241
|
-
className={cx('ui warning message')}
|
|
242
|
-
style={{
|
|
243
|
-
position: 'fixed',
|
|
244
|
-
left: '40%',
|
|
245
|
-
right: '40%',
|
|
246
|
-
backgroundColor: '#fff',
|
|
247
|
-
padding: '1em',
|
|
248
|
-
display: 'none',
|
|
249
|
-
flexDirection: 'column',
|
|
250
|
-
alignItems: 'center',
|
|
251
|
-
top: '40%',
|
|
252
|
-
zIndex: '9999',
|
|
253
|
-
}}
|
|
254
|
-
>
|
|
255
|
-
<Loader
|
|
256
|
-
disabled={false}
|
|
257
|
-
indeterminate
|
|
258
|
-
active
|
|
259
|
-
inline
|
|
260
|
-
size="medium"
|
|
261
|
-
></Loader>
|
|
262
|
-
<div>Preparing download</div>
|
|
263
|
-
</div>
|
|
264
|
-
</>
|
|
176
|
+
<Banner.Action
|
|
177
|
+
icon="ri-download-2-fill"
|
|
178
|
+
title={intl.formatMessage(messages.download)}
|
|
179
|
+
className="download"
|
|
180
|
+
onClick={() => {
|
|
181
|
+
setupPrintView(dispatch);
|
|
182
|
+
}}
|
|
183
|
+
/>
|
|
265
184
|
)}
|
|
266
185
|
{rssLinks?.map((rssLink, index) => (
|
|
267
186
|
<>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { Loader } from 'semantic-ui-react';
|
|
3
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
4
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
5
|
+
import { loadLazyImages } from '@eeacms/volto-eea-website-theme/helpers/loadLazyImages';
|
|
6
|
+
import { setupPrintView } from '@eeacms/volto-eea-website-theme/helpers/setupPrintView';
|
|
7
|
+
|
|
8
|
+
import './style.less';
|
|
9
|
+
|
|
10
|
+
const messages = defineMessages({
|
|
11
|
+
preparingDownload: {
|
|
12
|
+
id: 'Preparing download',
|
|
13
|
+
defaultMessage: 'Preparing download',
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const PrintLoader = () => {
|
|
18
|
+
const intl = useIntl();
|
|
19
|
+
const dispatch = useDispatch();
|
|
20
|
+
const showLoader = useSelector((state) => state.print.isPrintLoading);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const handleBeforePrint = () => {
|
|
24
|
+
loadLazyImages();
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const handleKeyDown = (event) => {
|
|
28
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'p') {
|
|
29
|
+
event.preventDefault();
|
|
30
|
+
setupPrintView(dispatch);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
35
|
+
window.addEventListener('beforeprint', handleBeforePrint);
|
|
36
|
+
|
|
37
|
+
return () => {
|
|
38
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
39
|
+
window.removeEventListener('beforeprint', handleBeforePrint);
|
|
40
|
+
};
|
|
41
|
+
}, [dispatch]);
|
|
42
|
+
|
|
43
|
+
return showLoader ? (
|
|
44
|
+
<div
|
|
45
|
+
id="download-print-loader"
|
|
46
|
+
className="ui warning message"
|
|
47
|
+
role="status"
|
|
48
|
+
aria-live="polite"
|
|
49
|
+
>
|
|
50
|
+
<Loader active inline size="medium" />
|
|
51
|
+
<div>{intl.formatMessage(messages.preparingDownload)}</div>
|
|
52
|
+
</div>
|
|
53
|
+
) : null;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default PrintLoader;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
3
|
+
import { render, fireEvent } from '@testing-library/react';
|
|
4
|
+
import { Provider } from 'react-redux';
|
|
5
|
+
import configureStore from 'redux-mock-store';
|
|
6
|
+
import PrintLoader from './PrintLoader';
|
|
7
|
+
import { IntlProvider } from 'react-intl';
|
|
8
|
+
|
|
9
|
+
jest.mock('@eeacms/volto-eea-website-theme/helpers/setupPrintView', () => ({
|
|
10
|
+
setupPrintView: jest.fn(),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock('@eeacms/volto-eea-website-theme/helpers/loadLazyImages', () => ({
|
|
14
|
+
loadLazyImages: jest.fn(),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const mockStore = configureStore();
|
|
18
|
+
|
|
19
|
+
describe('PrintLoader', () => {
|
|
20
|
+
it('should render loader when showLoader is true', () => {
|
|
21
|
+
const store = mockStore({
|
|
22
|
+
print: { isPrintLoading: true },
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const { getByText } = render(
|
|
26
|
+
<Provider store={store}>
|
|
27
|
+
<IntlProvider locale="en" messages={{}}>
|
|
28
|
+
<PrintLoader />
|
|
29
|
+
</IntlProvider>
|
|
30
|
+
</Provider>,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
expect(getByText('Preparing download')).toBeInTheDocument();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should not render anything when showLoader is false', () => {
|
|
37
|
+
const store = mockStore({
|
|
38
|
+
print: { isPrintLoading: false },
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const { container } = render(
|
|
42
|
+
<Provider store={store}>
|
|
43
|
+
<IntlProvider locale="en" messages={{}}>
|
|
44
|
+
<PrintLoader />
|
|
45
|
+
</IntlProvider>
|
|
46
|
+
</Provider>,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(container.firstChild).toBeNull();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should call setupPrintView when Ctrl+P is pressed', () => {
|
|
53
|
+
const store = mockStore({
|
|
54
|
+
print: { isPrintLoading: false },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
render(
|
|
58
|
+
<Provider store={store}>
|
|
59
|
+
<IntlProvider locale="en" messages={{}}>
|
|
60
|
+
<PrintLoader />
|
|
61
|
+
</IntlProvider>
|
|
62
|
+
</Provider>,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
fireEvent.keyDown(window, { key: 'p', ctrlKey: true });
|
|
66
|
+
expect(
|
|
67
|
+
require('@eeacms/volto-eea-website-theme/helpers/setupPrintView')
|
|
68
|
+
.setupPrintView,
|
|
69
|
+
).toHaveBeenCalled();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should call loadLazyImages before printing', () => {
|
|
73
|
+
const store = mockStore({
|
|
74
|
+
print: { isPrintLoading: false },
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
render(
|
|
78
|
+
<Provider store={store}>
|
|
79
|
+
<IntlProvider locale="en" messages={{}}>
|
|
80
|
+
<PrintLoader />
|
|
81
|
+
</IntlProvider>
|
|
82
|
+
</Provider>,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
window.dispatchEvent(new Event('beforeprint'));
|
|
86
|
+
expect(
|
|
87
|
+
require('@eeacms/volto-eea-website-theme/helpers/loadLazyImages')
|
|
88
|
+
.loadLazyImages,
|
|
89
|
+
).toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
});
|