@plone/volto 17.0.0-alpha.25 → 17.0.0-alpha.26

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 (95) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +52 -5
  3. package/README.md +8 -7
  4. package/cypress/support/commands.js +12 -9
  5. package/cypress.config.js +1 -0
  6. package/locales/ca/LC_MESSAGES/volto.po +36 -15
  7. package/locales/ca.json +1 -1
  8. package/locales/de/LC_MESSAGES/volto.po +36 -15
  9. package/locales/de.json +1 -1
  10. package/locales/en/LC_MESSAGES/volto.po +35 -14
  11. package/locales/en.json +1 -1
  12. package/locales/es/LC_MESSAGES/volto.po +65 -44
  13. package/locales/es.json +1 -1
  14. package/locales/eu/LC_MESSAGES/volto.po +35 -14
  15. package/locales/eu.json +1 -1
  16. package/locales/fi/LC_MESSAGES/volto.po +35 -14
  17. package/locales/fi.json +1 -1
  18. package/locales/fr/LC_MESSAGES/volto.po +36 -15
  19. package/locales/fr.json +1 -1
  20. package/locales/it/LC_MESSAGES/volto.po +35 -14
  21. package/locales/it.json +1 -1
  22. package/locales/ja/LC_MESSAGES/volto.po +35 -14
  23. package/locales/ja.json +1 -1
  24. package/locales/nl/LC_MESSAGES/volto.po +36 -15
  25. package/locales/nl.json +1 -1
  26. package/locales/pt/LC_MESSAGES/volto.po +36 -15
  27. package/locales/pt.json +1 -1
  28. package/locales/pt_BR/LC_MESSAGES/volto.po +35 -14
  29. package/locales/pt_BR.json +1 -1
  30. package/locales/ro/LC_MESSAGES/volto.po +36 -15
  31. package/locales/ro.json +1 -1
  32. package/locales/volto.pot +35 -14
  33. package/locales/zh_CN/LC_MESSAGES/volto.po +36 -15
  34. package/locales/zh_CN.json +1 -1
  35. package/package.json +4 -4
  36. package/packages/volto-slate/package.json +1 -1
  37. package/packages/volto-slate/src/editor/render.jsx +2 -3
  38. package/src/actions/index.js +3 -0
  39. package/src/actions/navroot/navroot.js +16 -0
  40. package/src/actions/navroot/navroot.test.js +15 -0
  41. package/src/actions/site/site.js +16 -0
  42. package/src/actions/site/site.test.js +15 -0
  43. package/src/actions/userSession/userSession.js +17 -1
  44. package/src/components/manage/Blocks/Block/Settings.jsx +2 -0
  45. package/src/components/manage/Blocks/Block/Settings.test.jsx +90 -0
  46. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +1 -1
  47. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +42 -25
  48. package/src/components/manage/Blocks/ToC/View.jsx +75 -13
  49. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +2 -12
  50. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +65 -38
  51. package/src/components/manage/Controlpanels/Rules/AddRule.jsx +1 -1
  52. package/src/components/manage/Controlpanels/Rules/EditRule.jsx +1 -1
  53. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +95 -5
  54. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +116 -103
  55. package/src/components/manage/Form/BlockDataForm.jsx +3 -2
  56. package/src/components/manage/Form/BlockDataForm.test.jsx +34 -2
  57. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +4 -1
  58. package/src/components/manage/Messages/Messages.jsx +32 -99
  59. package/src/components/manage/Messages/Messages.test.jsx +0 -1
  60. package/src/components/manage/Sharing/Sharing.jsx +39 -16
  61. package/src/components/manage/UniversalLink/UniversalLink.jsx +4 -6
  62. package/src/components/manage/Widgets/ArrayWidget.jsx +3 -1
  63. package/src/components/manage/Widgets/ArrayWidget.test.jsx +45 -1
  64. package/src/components/manage/Widgets/RegistryImageWidget.jsx +210 -0
  65. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +91 -0
  66. package/src/components/manage/Widgets/SelectWidget.jsx +15 -1
  67. package/src/components/manage/Widgets/SelectWidget.test.jsx +45 -1
  68. package/src/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +37 -3
  69. package/src/components/theme/Login/Login.jsx +159 -241
  70. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +131 -1
  71. package/src/components/theme/Logo/Logo.jsx +35 -29
  72. package/src/components/theme/Logo/Logo.test.jsx +135 -1
  73. package/src/components/theme/Logout/Logout.jsx +1 -1
  74. package/src/components/theme/Navigation/Navigation.jsx +86 -171
  75. package/src/components/theme/SearchWidget/SearchWidget.jsx +15 -3
  76. package/src/components/theme/SearchWidget/SearchWidget.test.jsx +8 -0
  77. package/src/components/theme/View/View.jsx +2 -0
  78. package/src/config/ControlPanels.js +0 -1
  79. package/src/config/Widgets.jsx +2 -0
  80. package/src/config/index.js +15 -3
  81. package/src/constants/ActionTypes.js +3 -0
  82. package/src/express-middleware/images.js +1 -0
  83. package/src/helpers/MessageLabels/MessageLabels.js +26 -4
  84. package/src/helpers/Site/index.js +21 -0
  85. package/src/helpers/index.js +1 -0
  86. package/src/reducers/index.js +4 -0
  87. package/src/reducers/navroot/navroot.js +79 -0
  88. package/src/reducers/navroot/navroot.test.js +110 -0
  89. package/src/reducers/site/site.js +51 -0
  90. package/src/reducers/site/site.test.js +67 -0
  91. package/src/reducers/userSession/userSession.js +15 -1
  92. package/test-setup-config.js +1 -0
  93. package/theme/themes/pastanaga/elements/input.overrides +5 -1
  94. package/theme/themes/pastanaga/extras/login.less +3 -0
  95. package/webpack-plugins/webpack-less-plugin.js +19 -0
@@ -1,14 +1,6 @@
1
- /**
2
- * Login container.
3
- * @module components/theme/Login/Login
4
- */
5
-
6
- import React, { Component } from 'react';
7
- import PropTypes from 'prop-types';
8
- import { Helmet } from '@plone/volto/helpers';
9
- import { connect } from 'react-redux';
10
- import { compose } from 'redux';
11
- import { Link } from 'react-router-dom';
1
+ import { useEffect } from 'react';
2
+ import { useDispatch, useSelector, shallowEqual } from 'react-redux';
3
+ import { Link, useHistory, useLocation } from 'react-router-dom';
12
4
  import {
13
5
  Container,
14
6
  Button,
@@ -17,20 +9,18 @@ import {
17
9
  Segment,
18
10
  Grid,
19
11
  } from 'semantic-ui-react';
20
- import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
12
+ import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
21
13
  import qs from 'query-string';
22
- import { withRouter } from 'react-router-dom';
23
14
 
15
+ import { Helmet } from '@plone/volto/helpers';
16
+ import config from '@plone/volto/registry';
24
17
  import { Icon } from '@plone/volto/components';
25
- import { login } from '@plone/volto/actions';
18
+ import { login, resetLoginRequest } from '@plone/volto/actions';
26
19
  import { toast } from 'react-toastify';
27
20
  import { Toast } from '@plone/volto/components';
28
-
29
21
  import aheadSVG from '@plone/volto/icons/ahead.svg';
30
22
  import clearSVG from '@plone/volto/icons/clear.svg';
31
23
 
32
- import config from '@plone/volto/registry';
33
-
34
24
  const messages = defineMessages({
35
25
  login: {
36
26
  id: 'Log in',
@@ -76,59 +66,21 @@ const messages = defineMessages({
76
66
  },
77
67
  });
78
68
 
79
- /**
80
- * Login class.
81
- * @class Login
82
- * @extends Component
83
- */
84
- class Login extends Component {
85
- /**
86
- * Property types.
87
- * @property {Object} propTypes Property types.
88
- * @static
89
- */
90
- static propTypes = {
91
- login: PropTypes.func.isRequired,
92
- error: PropTypes.shape({
93
- message: PropTypes.string,
94
- }),
95
- loading: PropTypes.bool,
96
- token: PropTypes.string, // eslint-disable-line react/no-unused-prop-types
97
- returnUrl: PropTypes.string,
98
- };
99
-
100
- /**
101
- * Default properties.
102
- * @property {Object} defaultProps Default properties.
103
- * @static
104
- */
105
- static defaultProps = {
106
- error: null,
107
- loading: null,
108
- token: null,
109
- returnUrl: null,
110
- };
111
-
112
- /**
113
- * Constructor
114
- * @method constructor
115
- * @param {Object} props Component properties
116
- * @constructs WysiwygEditor
117
- */
118
- constructor(props) {
119
- super(props);
120
- this.onLogin = this.onLogin.bind(this);
121
- }
122
-
123
- /**
124
- * Component will receive props
125
- * @method componentWillReceiveProps
126
- * @param {Object} nextProps Next properties
127
- * @returns {undefined}
128
- */
129
- UNSAFE_componentWillReceiveProps(nextProps) {
130
- if (nextProps.token) {
131
- this.props.history.push(this.props.returnUrl || '/');
69
+ const Login = (props) => {
70
+ const intl = useIntl();
71
+ const history = useHistory();
72
+ const location = useLocation();
73
+ const dispatch = useDispatch();
74
+ const token = useSelector((state) => state.userSession.token, shallowEqual);
75
+ const error = useSelector((state) => state.userSession.login.error);
76
+ const loading = useSelector((state) => state.userSession.login.loading);
77
+ const returnUrl =
78
+ qs.parse(props.location.search ?? location.search).return_url ||
79
+ location.pathname.replace(/\/login\/?$/, '').replace(/\/logout\/?$/, '') ||
80
+ '/';
81
+ useEffect(() => {
82
+ if (token && !props.isLogout) {
83
+ history.push(returnUrl || '/');
132
84
  if (toast.isActive('loggedOut')) {
133
85
  toast.dismiss('loggedOut');
134
86
  }
@@ -136,7 +88,7 @@ class Login extends Component {
136
88
  toast.dismiss('loginFailed');
137
89
  }
138
90
  }
139
- if (nextProps.error) {
91
+ if (error) {
140
92
  if (toast.isActive('loggedOut')) {
141
93
  toast.dismiss('loggedOut');
142
94
  }
@@ -144,189 +96,155 @@ class Login extends Component {
144
96
  toast.error(
145
97
  <Toast
146
98
  error
147
- title={this.props.intl.formatMessage(messages.loginFailed)}
148
- content={this.props.intl.formatMessage(messages.loginFailedContent)}
99
+ title={intl.formatMessage(messages.loginFailed)}
100
+ content={intl.formatMessage(messages.loginFailedContent)}
149
101
  />,
150
102
  { autoClose: false, toastId: 'loginFailed' },
151
103
  );
152
104
  }
153
105
  }
154
- }
155
-
156
- componentWillUnmount() {
157
- if (toast.isActive('loginFailed')) {
158
- toast.dismiss('loginFailed');
159
- }
160
- }
106
+ return () => {
107
+ if (toast.isActive('loginFailed')) {
108
+ toast.dismiss('loginFailed');
109
+ dispatch(resetLoginRequest());
110
+ }
111
+ };
112
+ }, [dispatch, token, error, intl, history, returnUrl, props.isLogout]);
161
113
 
162
- /**
163
- * On login handler
164
- * @method onLogin
165
- * @param {Object} event Event object.
166
- * @returns {undefined}
167
- */
168
- onLogin(event) {
169
- this.props.login(
170
- document.getElementsByName('login')[0].value,
171
- document.getElementsByName('password')[0].value,
114
+ const onLogin = (event) => {
115
+ dispatch(
116
+ login(
117
+ document.getElementsByName('login')[0].value,
118
+ document.getElementsByName('password')[0].value,
119
+ ),
172
120
  );
173
121
  event.preventDefault();
174
- }
122
+ };
175
123
 
176
- /**
177
- * Render method.
178
- * @method render
179
- * @returns {string} Markup for the component.
180
- */
181
- render() {
182
- return (
183
- <div id="page-login">
184
- <Helmet title={this.props.intl.formatMessage(messages.Login)} />
185
- <Container text>
186
- <Form method="post" onSubmit={this.onLogin}>
187
- <Segment.Group raised>
188
- <Segment className="primary">
189
- <FormattedMessage id="Log In" defaultMessage="Login" />
190
- </Segment>
191
- <Segment secondary>
192
- <FormattedMessage
193
- id="Sign in to start session"
194
- defaultMessage="Sign in to start session"
195
- />
196
- </Segment>
197
- <Segment className="form">
198
- <Form.Field inline className="help">
199
- <Grid>
200
- <Grid.Row stretched>
201
- <Grid.Column width="4">
202
- <div className="wrapper">
203
- <label htmlFor="login">
204
- <FormattedMessage
205
- id="Login Name"
206
- defaultMessage="Login Name"
207
- />
208
- </label>
209
- </div>
210
- </Grid.Column>
211
- <Grid.Column width="8">
212
- {/* eslint-disable jsx-a11y/no-autofocus */}
213
- <Input
214
- id="login"
215
- name="login"
216
- placeholder={this.props.intl.formatMessage(
217
- messages.loginName,
218
- )}
219
- autoFocus
220
- />
221
- </Grid.Column>
222
- </Grid.Row>
223
- </Grid>
224
- </Form.Field>
225
- <Form.Field inline className="help">
226
- <Grid>
227
- <Grid.Row stretched>
228
- <Grid.Column stretched width="4">
229
- <div className="wrapper">
230
- <label htmlFor="password">
231
- <FormattedMessage
232
- id="Password"
233
- defaultMessage="Password"
234
- />
235
- </label>
236
- </div>
237
- </Grid.Column>
238
- <Grid.Column stretched width="8">
239
- <Input
240
- type="password"
241
- id="password"
242
- autoComplete="current-password"
243
- name="password"
244
- placeholder={this.props.intl.formatMessage(
245
- messages.password,
246
- )}
247
- tabIndex={0}
248
- />
249
- </Grid.Column>
250
- </Grid.Row>
251
- </Grid>
252
- </Form.Field>
253
- <Form.Field inline className="help">
254
- <Grid>
255
- <Grid.Row stretched>
256
- {config.settings.showSelfRegistration && (
257
- <Grid.Column stretched width="12">
258
- <p className="help">
259
- <Link to="/register">
260
- {this.props.intl.formatMessage(messages.register)}
261
- </Link>
262
- </p>
263
- </Grid.Column>
264
- )}
124
+ return (
125
+ <div id="page-login">
126
+ <Helmet title={intl.formatMessage(messages.Login)} />
127
+ <Container text>
128
+ <Form method="post" onSubmit={onLogin}>
129
+ <Segment.Group raised>
130
+ <Segment className="primary">
131
+ <FormattedMessage id="Log In" defaultMessage="Login" />
132
+ </Segment>
133
+ <Segment secondary>
134
+ <FormattedMessage
135
+ id="Sign in to start session"
136
+ defaultMessage="Sign in to start session"
137
+ />
138
+ </Segment>
139
+ <Segment className="form">
140
+ <Form.Field inline className="help">
141
+ <Grid>
142
+ <Grid.Row stretched>
143
+ <Grid.Column width="4">
144
+ <div className="wrapper">
145
+ <label htmlFor="login">
146
+ <FormattedMessage
147
+ id="Login Name"
148
+ defaultMessage="Login Name"
149
+ />
150
+ </label>
151
+ </div>
152
+ </Grid.Column>
153
+ <Grid.Column width="8">
154
+ {/* eslint-disable jsx-a11y/no-autofocus */}
155
+ <Input
156
+ id="login"
157
+ name="login"
158
+ placeholder={intl.formatMessage(messages.loginName)}
159
+ autoFocus
160
+ />
161
+ </Grid.Column>
162
+ </Grid.Row>
163
+ </Grid>
164
+ </Form.Field>
165
+ <Form.Field inline className="help">
166
+ <Grid>
167
+ <Grid.Row stretched>
168
+ <Grid.Column stretched width="4">
169
+ <div className="wrapper">
170
+ <label htmlFor="password">
171
+ <FormattedMessage
172
+ id="Password"
173
+ defaultMessage="Password"
174
+ />
175
+ </label>
176
+ </div>
177
+ </Grid.Column>
178
+ <Grid.Column stretched width="8">
179
+ <Input
180
+ type="password"
181
+ id="password"
182
+ autoComplete="current-password"
183
+ name="password"
184
+ placeholder={intl.formatMessage(messages.password)}
185
+ tabIndex={0}
186
+ />
187
+ </Grid.Column>
188
+ </Grid.Row>
189
+ </Grid>
190
+ </Form.Field>
191
+ <Form.Field inline className="help">
192
+ <Grid>
193
+ <Grid.Row stretched>
194
+ {config.settings.showSelfRegistration && (
265
195
  <Grid.Column stretched width="12">
266
196
  <p className="help">
267
- <Link to="/passwordreset">
268
- {this.props.intl.formatMessage(
269
- messages.forgotPassword,
270
- )}
197
+ <Link to="/register">
198
+ {intl.formatMessage(messages.register)}
271
199
  </Link>
272
200
  </p>
273
201
  </Grid.Column>
274
- </Grid.Row>
275
- </Grid>
276
- </Form.Field>
277
- </Segment>
278
- <Segment className="actions" clearing>
279
- <Button
280
- basic
281
- primary
282
- icon
283
- floated="right"
284
- type="submit"
285
- id="login-form-submit"
286
- aria-label={this.props.intl.formatMessage(messages.login)}
287
- title={this.props.intl.formatMessage(messages.login)}
288
- loading={this.props.loading}
289
- >
290
- <Icon className="circled" name={aheadSVG} size="30px" />
291
- </Button>
202
+ )}
203
+ <Grid.Column stretched width="12">
204
+ <p className="help">
205
+ <Link to="/passwordreset">
206
+ {intl.formatMessage(messages.forgotPassword)}
207
+ </Link>
208
+ </p>
209
+ </Grid.Column>
210
+ </Grid.Row>
211
+ </Grid>
212
+ </Form.Field>
213
+ </Segment>
214
+ <Segment className="actions" clearing>
215
+ <Button
216
+ basic
217
+ primary
218
+ icon
219
+ floated="right"
220
+ type="submit"
221
+ id="login-form-submit"
222
+ aria-label={intl.formatMessage(messages.login)}
223
+ title={intl.formatMessage(messages.login)}
224
+ loading={loading}
225
+ >
226
+ <Icon className="circled" name={aheadSVG} size="30px" />
227
+ </Button>
292
228
 
293
- <Button
294
- basic
295
- secondary
296
- icon
297
- floated="right"
298
- id="login-form-cancel"
299
- as={Link}
300
- to="/"
301
- aria-label={this.props.intl.formatMessage(messages.cancel)}
302
- title={this.props.intl.formatMessage(messages.cancel)}
303
- >
304
- <Icon className="circled" name={clearSVG} size="30px" />
305
- </Button>
306
- </Segment>
307
- </Segment.Group>
308
- </Form>
309
- </Container>
310
- </div>
311
- );
312
- }
313
- }
229
+ <Button
230
+ basic
231
+ secondary
232
+ icon
233
+ floated="right"
234
+ id="login-form-cancel"
235
+ as={Link}
236
+ to="/"
237
+ aria-label={intl.formatMessage(messages.cancel)}
238
+ title={intl.formatMessage(messages.cancel)}
239
+ >
240
+ <Icon className="circled" name={clearSVG} size="30px" />
241
+ </Button>
242
+ </Segment>
243
+ </Segment.Group>
244
+ </Form>
245
+ </Container>
246
+ </div>
247
+ );
248
+ };
314
249
 
315
- export default compose(
316
- withRouter,
317
- injectIntl,
318
- connect(
319
- (state, props) => ({
320
- error: state.userSession.login.error,
321
- loading: state.userSession.login.loading,
322
- token: state.userSession.token,
323
- returnUrl:
324
- qs.parse(props.location.search).return_url ||
325
- props.location.pathname
326
- .replace(/\/login\/?$/, '')
327
- .replace(/\/logout\/?$/, '') ||
328
- '/',
329
- }),
330
- { login },
331
- ),
332
- )(Login);
250
+ export default Login;
@@ -14,12 +14,142 @@ beforeAll(() => {
14
14
  const mockStore = configureStore();
15
15
 
16
16
  describe('Multilingual Logo', () => {
17
- it('renders a logo component with multilingual', () => {
17
+ it('renders a logo component in a multilingual site root', () => {
18
18
  const store = mockStore({
19
19
  intl: {
20
20
  locale: 'en',
21
21
  messages: {},
22
22
  },
23
+ navroot: {
24
+ data: {
25
+ id: 'http://localhost:3000/@navroot',
26
+ navroot: {
27
+ '@id': 'http://localhost:3000',
28
+ title: 'Plone Site',
29
+ },
30
+ },
31
+ },
32
+ router: {
33
+ location: {
34
+ pathname: '/',
35
+ },
36
+ },
37
+ site: {
38
+ data: {},
39
+ },
40
+ });
41
+ const component = renderer.create(
42
+ <Provider store={store}>
43
+ <MemoryRouter>
44
+ <Logo />
45
+ </MemoryRouter>
46
+ </Provider>,
47
+ );
48
+ const json = component.toJSON();
49
+ expect(json).toMatchSnapshot();
50
+ });
51
+
52
+ it('renders a logo component in a multilingual site language root', () => {
53
+ const store = mockStore({
54
+ intl: {
55
+ locale: 'en',
56
+ messages: {},
57
+ },
58
+ navroot: {
59
+ data: {
60
+ id: 'http://localhost:3000/en/@navroot',
61
+ navroot: {
62
+ '@id': 'http://localhost:3000/en',
63
+ title: 'English',
64
+ },
65
+ },
66
+ },
67
+ router: {
68
+ location: {
69
+ pathname: '/en',
70
+ },
71
+ },
72
+ site: {
73
+ data: {
74
+ 'plone.site_title': 'Plone Site',
75
+ },
76
+ },
77
+ });
78
+ const component = renderer.create(
79
+ <Provider store={store}>
80
+ <MemoryRouter>
81
+ <Logo />
82
+ </MemoryRouter>
83
+ </Provider>,
84
+ );
85
+ const json = component.toJSON();
86
+ expect(json).toMatchSnapshot();
87
+ });
88
+
89
+ it('renders a logo component with a custom logo in a non-root url', () => {
90
+ const store = mockStore({
91
+ intl: {
92
+ locale: 'en',
93
+ messages: {},
94
+ },
95
+ navroot: {
96
+ data: {
97
+ id: 'http://localhost:3000/en/@navroot',
98
+ navroot: {
99
+ '@id': 'http://localhost:3000/en',
100
+ title: 'English',
101
+ },
102
+ },
103
+ },
104
+ router: {
105
+ location: {
106
+ pathname: '/en',
107
+ },
108
+ },
109
+ site: {
110
+ data: {
111
+ 'plone.site_logo':
112
+ 'http://localhost:3000/@@site-logo/logo.cab945d8.svg',
113
+ },
114
+ },
115
+ });
116
+ const component = renderer.create(
117
+ <Provider store={store}>
118
+ <MemoryRouter>
119
+ <Logo />
120
+ </MemoryRouter>
121
+ </Provider>,
122
+ );
123
+ const json = component.toJSON();
124
+ expect(json).toMatchSnapshot();
125
+ });
126
+
127
+ it('renders a logo component with a custom logo in a non-root url with path', () => {
128
+ const store = mockStore({
129
+ intl: {
130
+ locale: 'en',
131
+ messages: {},
132
+ },
133
+ navroot: {
134
+ data: {
135
+ id: 'http://localhost:3000/en/@navroot',
136
+ navroot: {
137
+ '@id': 'http://localhost:3000/en',
138
+ title: 'English',
139
+ },
140
+ },
141
+ },
142
+ router: {
143
+ location: {
144
+ pathname: '/en/my/path',
145
+ },
146
+ },
147
+ site: {
148
+ data: {
149
+ 'plone.site_logo':
150
+ 'http://localhost:3000/@@site-logo/logo.cab945d8.svg',
151
+ },
152
+ },
23
153
  });
24
154
  const component = renderer.create(
25
155
  <Provider store={store}>