@blaze-cms/react-page-builder 0.146.0-node18-core-styles-tooltips.20 → 0.146.0-node18-tooltips.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 +25 -63
- package/lib/components/ContentGroup/ContentGroup.js +41 -10
- package/lib/components/ContentGroup/ContentGroup.js.map +1 -1
- package/lib/components/ContentGroup/ContentGroupAccordion.js +175 -0
- package/lib/components/ContentGroup/ContentGroupAccordion.js.map +1 -0
- package/lib/components/ContentGroup/constants.js +13 -1
- package/lib/components/ContentGroup/constants.js.map +1 -1
- package/lib/components/ContentGroup/helpers/get-structured-data-properties.js +40 -0
- package/lib/components/ContentGroup/helpers/get-structured-data-properties.js.map +1 -0
- package/lib/components/Menu/Menu.js +1 -4
- package/lib/components/Menu/Menu.js.map +1 -1
- package/lib/components/Menu/MenuContext.js +1 -2
- package/lib/components/Menu/MenuContext.js.map +1 -1
- package/lib/components/MenuItem/MenuItemRender.js +12 -27
- package/lib/components/MenuItem/MenuItemRender.js.map +1 -1
- package/lib/components/MenuItem/helpers/index.js +0 -14
- package/lib/components/MenuItem/helpers/index.js.map +1 -1
- package/lib/components/SearchContent/SearchContent.js +4 -3
- package/lib/components/SearchContent/SearchContent.js.map +1 -1
- package/lib/system-components/EditorMode/helpers/add-editor-mode-event-listeners.js +0 -1
- package/lib/system-components/EditorMode/helpers/add-editor-mode-event-listeners.js.map +1 -1
- package/lib-es/components/ContentGroup/ContentGroup.js +25 -10
- package/lib-es/components/ContentGroup/ContentGroup.js.map +1 -1
- package/lib-es/components/ContentGroup/ContentGroupAccordion.js +138 -0
- package/lib-es/components/ContentGroup/ContentGroupAccordion.js.map +1 -0
- package/lib-es/components/ContentGroup/constants.js +12 -1
- package/lib-es/components/ContentGroup/constants.js.map +1 -1
- package/lib-es/components/ContentGroup/helpers/get-structured-data-properties.js +33 -0
- package/lib-es/components/ContentGroup/helpers/get-structured-data-properties.js.map +1 -0
- package/lib-es/components/Menu/Menu.js +1 -4
- package/lib-es/components/Menu/Menu.js.map +1 -1
- package/lib-es/components/Menu/MenuContext.js +1 -2
- package/lib-es/components/Menu/MenuContext.js.map +1 -1
- package/lib-es/components/MenuItem/MenuItemRender.js +11 -25
- package/lib-es/components/MenuItem/MenuItemRender.js.map +1 -1
- package/lib-es/components/MenuItem/helpers/index.js +1 -3
- package/lib-es/components/MenuItem/helpers/index.js.map +1 -1
- package/lib-es/components/SearchContent/SearchContent.js +4 -3
- package/lib-es/components/SearchContent/SearchContent.js.map +1 -1
- package/lib-es/system-components/EditorMode/helpers/add-editor-mode-event-listeners.js +0 -1
- package/lib-es/system-components/EditorMode/helpers/add-editor-mode-event-listeners.js.map +1 -1
- package/package.json +10 -10
- package/src/components/ContentGroup/ContentGroup.js +37 -13
- package/src/components/ContentGroup/ContentGroupAccordion.js +163 -0
- package/src/components/ContentGroup/constants.js +14 -1
- package/src/components/ContentGroup/helpers/get-structured-data-properties.js +36 -0
- package/src/components/Menu/Menu.js +1 -3
- package/src/components/Menu/MenuContext.js +1 -1
- package/src/components/MenuItem/MenuItemRender.js +12 -40
- package/src/components/MenuItem/helpers/index.js +1 -3
- package/src/components/SearchContent/SearchContent.js +6 -5
- package/src/system-components/EditorMode/helpers/add-editor-mode-event-listeners.js +3 -1
- package/tests/unit/src/components/ContentGroup/ContentGroup.test.js +32 -2
- package/tests/unit/src/components/ContentGroup/ContentGroupAccordion.test.js +283 -0
- package/tests/unit/src/components/ContentGroup/__snapshots__/ContentGroup.test.js.snap +2 -2
- package/tests/unit/src/components/ContentGroup/__snapshots__/ContentGroupAccordion.test.js.snap +243 -0
- package/tests/unit/src/components/ContentGroup/helpers/get-structured-data-properties.test.js +105 -0
- package/tests/unit/src/components/MenuItem/MenuItem.test.js +0 -5
- package/tests/unit/src/components/MenuItem/MenuItemRender.test.js +3 -11
- package/lib/components/MenuItem/helpers/has-active-child.js +0 -19
- package/lib/components/MenuItem/helpers/has-active-child.js.map +0 -1
- package/lib/components/MenuItem/helpers/isUrlPathMatch.js +0 -18
- package/lib/components/MenuItem/helpers/isUrlPathMatch.js.map +0 -1
- package/lib-es/components/MenuItem/helpers/has-active-child.js +0 -5
- package/lib-es/components/MenuItem/helpers/has-active-child.js.map +0 -1
- package/lib-es/components/MenuItem/helpers/isUrlPathMatch.js +0 -8
- package/lib-es/components/MenuItem/helpers/isUrlPathMatch.js.map +0 -1
- package/src/components/MenuItem/helpers/has-active-child.js +0 -10
- package/src/components/MenuItem/helpers/isUrlPathMatch.js +0 -10
- package/tests/unit/src/components/MenuItem/helpers/constants.js +0 -73
- package/tests/unit/src/components/MenuItem/helpers/has-active-child.test.js +0 -35
- package/tests/unit/src/components/MenuItem/helpers/is-url-path-match.test.js +0 -53
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import '@testing-library/jest-dom';
|
|
6
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
7
|
+
import { useRouter } from 'next/router';
|
|
8
|
+
import ContentGroupAccordion from '../../../../../src/components/ContentGroup/ContentGroupAccordion';
|
|
9
|
+
import { OPEN_STATES } from '../../../../../src/components/ContentGroup/constants';
|
|
10
|
+
|
|
11
|
+
const RESOLVER = '/Resolver';
|
|
12
|
+
|
|
13
|
+
// Test constants
|
|
14
|
+
const TEST_CONSTANTS = {
|
|
15
|
+
ACCORDION_URL: 'accordion-url',
|
|
16
|
+
SECTION_ONE_ID: 'section-one',
|
|
17
|
+
SECTION_TWO_ID: 'section-two',
|
|
18
|
+
SECTION_ONE_CAMEL: 'sectionOne',
|
|
19
|
+
SECTION_TWO_CAMEL: 'sectionTwo',
|
|
20
|
+
SECTION_ONE_TEXT: 'section one',
|
|
21
|
+
SECTION_TWO_TEXT: 'section two',
|
|
22
|
+
TEST_ACCORDION_NAME: 'testAccordion',
|
|
23
|
+
VARIANT_TESTID: 'variant',
|
|
24
|
+
BUTTON_ROLE: 'button',
|
|
25
|
+
ARIA_EXPANDED: 'aria-expanded',
|
|
26
|
+
ARIA_CONTROLS: 'aria-controls',
|
|
27
|
+
TRUE: 'true',
|
|
28
|
+
FALSE: 'false'
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
jest.mock('next/router', () => ({
|
|
32
|
+
useRouter: jest.fn()
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
const buildRouter = (overrides = {}) => ({
|
|
36
|
+
asPath: TEST_CONSTANTS.ACCORDION_URL,
|
|
37
|
+
push: jest.fn(),
|
|
38
|
+
replace: jest.fn(),
|
|
39
|
+
...overrides
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const VariantComponent = ({ children }) => (
|
|
43
|
+
<div data-testid={TEST_CONSTANTS.VARIANT_TESTID}>{children}</div>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const mockedProps = {
|
|
47
|
+
name: TEST_CONSTANTS.TEST_ACCORDION_NAME,
|
|
48
|
+
groupSections: [
|
|
49
|
+
<div key="s1">{TEST_CONSTANTS.SECTION_ONE_TEXT}</div>,
|
|
50
|
+
<div key="s2">{TEST_CONSTANTS.SECTION_TWO_TEXT}</div>
|
|
51
|
+
],
|
|
52
|
+
sectionsData: [
|
|
53
|
+
[TEST_CONSTANTS.SECTION_ONE_ID, TEST_CONSTANTS.SECTION_ONE_CAMEL],
|
|
54
|
+
[TEST_CONSTANTS.SECTION_TWO_ID, TEST_CONSTANTS.SECTION_TWO_CAMEL]
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
jest.clearAllMocks();
|
|
60
|
+
useRouter.mockReturnValue(buildRouter());
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('ContentGroupAccordion component', () => {
|
|
64
|
+
it('matches snapshot and renders basic accordion', () => {
|
|
65
|
+
const { asFragment } = render(<ContentGroupAccordion {...mockedProps} />);
|
|
66
|
+
expect(asFragment()).toMatchSnapshot();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('matches snapshot and renders variant accordion', () => {
|
|
70
|
+
const { asFragment } = render(
|
|
71
|
+
<ContentGroupAccordion {...mockedProps} VariantComponent={VariantComponent} />
|
|
72
|
+
);
|
|
73
|
+
expect(asFragment()).toMatchSnapshot();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('opens the section indicated by the URL hash on first render', () => {
|
|
77
|
+
useRouter.mockReturnValue(
|
|
78
|
+
buildRouter({ asPath: `${TEST_CONSTANTS.ACCORDION_URL}#${TEST_CONSTANTS.SECTION_TWO_ID}` })
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
82
|
+
|
|
83
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
84
|
+
expect(headers.length).toBeGreaterThanOrEqual(2);
|
|
85
|
+
|
|
86
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.FALSE);
|
|
87
|
+
expect(headers[1]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('toggles a section when its header is clicked', () => {
|
|
91
|
+
const router = buildRouter();
|
|
92
|
+
useRouter.mockReturnValue(router);
|
|
93
|
+
|
|
94
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
95
|
+
|
|
96
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
97
|
+
|
|
98
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.FALSE);
|
|
99
|
+
|
|
100
|
+
fireEvent.click(headers[0]);
|
|
101
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
102
|
+
expect(router.replace).toHaveBeenLastCalledWith(
|
|
103
|
+
RESOLVER,
|
|
104
|
+
`${TEST_CONSTANTS.ACCORDION_URL}#${TEST_CONSTANTS.SECTION_ONE_ID}`,
|
|
105
|
+
expect.objectContaining({ shallow: true, scroll: false })
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
fireEvent.click(headers[0]);
|
|
109
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.FALSE);
|
|
110
|
+
expect(router.replace).toHaveBeenLastCalledWith(
|
|
111
|
+
RESOLVER,
|
|
112
|
+
TEST_CONSTANTS.ACCORDION_URL,
|
|
113
|
+
expect.objectContaining({ shallow: true, scroll: false })
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('opens another section when its header is clicked', () => {
|
|
118
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
119
|
+
|
|
120
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
121
|
+
|
|
122
|
+
fireEvent.click(headers[0]);
|
|
123
|
+
fireEvent.click(headers[1]);
|
|
124
|
+
|
|
125
|
+
expect(headers[1]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('renders accordion with child content inside (content present in DOM)', () => {
|
|
129
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
130
|
+
expect(screen.getByText(TEST_CONSTANTS.SECTION_ONE_TEXT)).toBeInTheDocument();
|
|
131
|
+
expect(screen.getByText(TEST_CONSTANTS.SECTION_TWO_TEXT)).toBeInTheDocument();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('has basic accessibility attributes expected by Lighthouse (ARIA)', () => {
|
|
135
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
136
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
137
|
+
|
|
138
|
+
headers.forEach(hdr => {
|
|
139
|
+
expect(hdr).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED);
|
|
140
|
+
const controls = hdr.getAttribute(TEST_CONSTANTS.ARIA_CONTROLS);
|
|
141
|
+
expect(controls).toBeTruthy();
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('opens the item matching the hash after a "reload" (initial asPath contains hash)', () => {
|
|
146
|
+
useRouter.mockReturnValue(
|
|
147
|
+
buildRouter({ asPath: `${TEST_CONSTANTS.ACCORDION_URL}#${TEST_CONSTANTS.SECTION_ONE_ID}` })
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
151
|
+
|
|
152
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
153
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('supports opening more than one accordion item at a time', () => {
|
|
157
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
158
|
+
|
|
159
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
160
|
+
|
|
161
|
+
fireEvent.click(headers[0]);
|
|
162
|
+
fireEvent.click(headers[1]);
|
|
163
|
+
|
|
164
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
165
|
+
expect(headers[1]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('renders all item panels in HTML and uses CSS to show/hide (no unmount on close)', () => {
|
|
169
|
+
render(<ContentGroupAccordion {...mockedProps} />);
|
|
170
|
+
|
|
171
|
+
const contentOne = screen.getByText(TEST_CONSTANTS.SECTION_ONE_TEXT);
|
|
172
|
+
const contentTwo = screen.getByText(TEST_CONSTANTS.SECTION_TWO_TEXT);
|
|
173
|
+
|
|
174
|
+
expect(contentOne).toBeInTheDocument();
|
|
175
|
+
expect(contentTwo).toBeInTheDocument();
|
|
176
|
+
|
|
177
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
178
|
+
fireEvent.click(headers[0]);
|
|
179
|
+
fireEvent.click(headers[0]);
|
|
180
|
+
|
|
181
|
+
expect(contentOne).toBeInTheDocument();
|
|
182
|
+
expect(contentTwo).toBeInTheDocument();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('openState="first open" opens only the first item by default no hash', () => {
|
|
186
|
+
render(<ContentGroupAccordion {...mockedProps} openState={OPEN_STATES.FIRST_OPEN} />);
|
|
187
|
+
|
|
188
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
189
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
190
|
+
expect(headers[1]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.FALSE);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('openState="all open" opens all items by default no hash', () => {
|
|
194
|
+
render(<ContentGroupAccordion {...mockedProps} openState={OPEN_STATES.ALL_OPEN} />);
|
|
195
|
+
|
|
196
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
197
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
198
|
+
expect(headers[1]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('openState="all closed" starts with all items closed by default no hash', () => {
|
|
202
|
+
render(<ContentGroupAccordion {...mockedProps} openState={OPEN_STATES.ALL_CLOSED} />);
|
|
203
|
+
|
|
204
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
205
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.FALSE);
|
|
206
|
+
expect(headers[1]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.FALSE);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('URL hash overrides openState on first render', () => {
|
|
210
|
+
useRouter.mockReturnValue(
|
|
211
|
+
buildRouter({ asPath: `${TEST_CONSTANTS.ACCORDION_URL}#${TEST_CONSTANTS.SECTION_TWO_ID}` })
|
|
212
|
+
);
|
|
213
|
+
render(<ContentGroupAccordion {...mockedProps} openState={OPEN_STATES.ALL_CLOSED} />);
|
|
214
|
+
|
|
215
|
+
const headers = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
216
|
+
|
|
217
|
+
expect(headers[0]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.FALSE);
|
|
218
|
+
expect(headers[1]).toHaveAttribute(TEST_CONSTANTS.ARIA_EXPANDED, TEST_CONSTANTS.TRUE);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('toggling updates the URL hash appropriately with scroll disabled', () => {
|
|
222
|
+
const router = buildRouter();
|
|
223
|
+
useRouter.mockReturnValue(router);
|
|
224
|
+
|
|
225
|
+
render(<ContentGroupAccordion {...mockedProps} openState={OPEN_STATES.ALL_CLOSED} />);
|
|
226
|
+
|
|
227
|
+
const [first, second] = screen.getAllByRole(TEST_CONSTANTS.BUTTON_ROLE);
|
|
228
|
+
|
|
229
|
+
fireEvent.click(first);
|
|
230
|
+
expect(router.replace).toHaveBeenLastCalledWith(
|
|
231
|
+
RESOLVER,
|
|
232
|
+
`${TEST_CONSTANTS.ACCORDION_URL}#${TEST_CONSTANTS.SECTION_ONE_ID}`,
|
|
233
|
+
expect.objectContaining({ shallow: true, scroll: false })
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
fireEvent.click(second);
|
|
237
|
+
expect(router.replace).toHaveBeenLastCalledWith(
|
|
238
|
+
RESOLVER,
|
|
239
|
+
`${TEST_CONSTANTS.ACCORDION_URL}#${TEST_CONSTANTS.SECTION_TWO_ID}`,
|
|
240
|
+
expect.objectContaining({ shallow: true, scroll: false })
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
fireEvent.click(second);
|
|
244
|
+
expect(router.replace).toHaveBeenLastCalledWith(
|
|
245
|
+
RESOLVER,
|
|
246
|
+
TEST_CONSTANTS.ACCORDION_URL,
|
|
247
|
+
expect.objectContaining({ shallow: true, scroll: false })
|
|
248
|
+
);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('structured data props', () => {
|
|
252
|
+
it('applies groupSectionProps to accordion sections', () => {
|
|
253
|
+
const customProperties = {
|
|
254
|
+
groupSectionProps: {
|
|
255
|
+
'data-testid': 'custom-section'
|
|
256
|
+
},
|
|
257
|
+
groupSectionTitleProps: {
|
|
258
|
+
'data-testid': 'custom-title'
|
|
259
|
+
},
|
|
260
|
+
groupContentWrapperProps: {
|
|
261
|
+
'data-testid': 'custom-content-wrapper'
|
|
262
|
+
},
|
|
263
|
+
groupContentProps: {
|
|
264
|
+
'data-testid': 'custom-content'
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
render(<ContentGroupAccordion {...mockedProps} {...customProperties} />);
|
|
269
|
+
|
|
270
|
+
const sections = screen.getAllByTestId('custom-section');
|
|
271
|
+
expect(sections.length).toBe(2);
|
|
272
|
+
|
|
273
|
+
const titles = screen.getAllByTestId('custom-title');
|
|
274
|
+
expect(titles.length).toBe(2);
|
|
275
|
+
|
|
276
|
+
const contentWrappers = screen.getAllByTestId('custom-content-wrapper');
|
|
277
|
+
expect(contentWrappers.length).toBe(2);
|
|
278
|
+
|
|
279
|
+
const contents = screen.getAllByTestId('custom-content');
|
|
280
|
+
expect(contents.length).toBe(2);
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`ContentGroup component
|
|
3
|
+
exports[`ContentGroup component matches snapshots for tab and sidepanel 1`] = `<DocumentFragment />`;
|
|
4
4
|
|
|
5
|
-
exports[`ContentGroup component
|
|
5
|
+
exports[`ContentGroup component matches snapshots for tab and sidepanel 2`] = `<DocumentFragment />`;
|
package/tests/unit/src/components/ContentGroup/__snapshots__/ContentGroupAccordion.test.js.snap
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`ContentGroupAccordion component matches snapshot and renders basic accordion 1`] = `
|
|
4
|
+
<DocumentFragment>
|
|
5
|
+
<div
|
|
6
|
+
class="content-group-accordion"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
aria-label="testAccordion"
|
|
10
|
+
class="content-group-accordion__items"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="content-group-accordion__item"
|
|
14
|
+
>
|
|
15
|
+
<h3
|
|
16
|
+
class="content-group-accordion__heading"
|
|
17
|
+
>
|
|
18
|
+
<button
|
|
19
|
+
aria-controls="section-one-panel"
|
|
20
|
+
aria-expanded="false"
|
|
21
|
+
class="content-group-accordion__header-btn"
|
|
22
|
+
id="section-one"
|
|
23
|
+
type="button"
|
|
24
|
+
>
|
|
25
|
+
<span
|
|
26
|
+
class="content-group-accordion__title"
|
|
27
|
+
>
|
|
28
|
+
sectionOne
|
|
29
|
+
</span>
|
|
30
|
+
<span
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
class="content-group-accordion__chevron"
|
|
33
|
+
>
|
|
34
|
+
<svg
|
|
35
|
+
class="content-group-accordion__chevron-icon"
|
|
36
|
+
fill="currentColor"
|
|
37
|
+
height="1em"
|
|
38
|
+
stroke="currentColor"
|
|
39
|
+
stroke-width="0"
|
|
40
|
+
viewBox="0 0 16 16"
|
|
41
|
+
width="1em"
|
|
42
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
43
|
+
>
|
|
44
|
+
<path
|
|
45
|
+
clip-rule="evenodd"
|
|
46
|
+
d="M7.976 10.072l4.357-4.357.62.618L8.284 11h-.618L3 6.333l.619-.618 4.357 4.357z"
|
|
47
|
+
fill-rule="evenodd"
|
|
48
|
+
/>
|
|
49
|
+
</svg>
|
|
50
|
+
</span>
|
|
51
|
+
</button>
|
|
52
|
+
</h3>
|
|
53
|
+
<div
|
|
54
|
+
aria-labelledby="section-one"
|
|
55
|
+
class="content-group-accordion__panel"
|
|
56
|
+
data-section="section-one"
|
|
57
|
+
hidden=""
|
|
58
|
+
id="section-one-panel"
|
|
59
|
+
role="region"
|
|
60
|
+
>
|
|
61
|
+
<div>
|
|
62
|
+
<div>
|
|
63
|
+
section one
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
<div
|
|
69
|
+
class="content-group-accordion__item"
|
|
70
|
+
>
|
|
71
|
+
<h3
|
|
72
|
+
class="content-group-accordion__heading"
|
|
73
|
+
>
|
|
74
|
+
<button
|
|
75
|
+
aria-controls="section-two-panel"
|
|
76
|
+
aria-expanded="false"
|
|
77
|
+
class="content-group-accordion__header-btn"
|
|
78
|
+
id="section-two"
|
|
79
|
+
type="button"
|
|
80
|
+
>
|
|
81
|
+
<span
|
|
82
|
+
class="content-group-accordion__title"
|
|
83
|
+
>
|
|
84
|
+
sectionTwo
|
|
85
|
+
</span>
|
|
86
|
+
<span
|
|
87
|
+
aria-hidden="true"
|
|
88
|
+
class="content-group-accordion__chevron"
|
|
89
|
+
>
|
|
90
|
+
<svg
|
|
91
|
+
class="content-group-accordion__chevron-icon"
|
|
92
|
+
fill="currentColor"
|
|
93
|
+
height="1em"
|
|
94
|
+
stroke="currentColor"
|
|
95
|
+
stroke-width="0"
|
|
96
|
+
viewBox="0 0 16 16"
|
|
97
|
+
width="1em"
|
|
98
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
99
|
+
>
|
|
100
|
+
<path
|
|
101
|
+
clip-rule="evenodd"
|
|
102
|
+
d="M7.976 10.072l4.357-4.357.62.618L8.284 11h-.618L3 6.333l.619-.618 4.357 4.357z"
|
|
103
|
+
fill-rule="evenodd"
|
|
104
|
+
/>
|
|
105
|
+
</svg>
|
|
106
|
+
</span>
|
|
107
|
+
</button>
|
|
108
|
+
</h3>
|
|
109
|
+
<div
|
|
110
|
+
aria-labelledby="section-two"
|
|
111
|
+
class="content-group-accordion__panel"
|
|
112
|
+
data-section="section-two"
|
|
113
|
+
hidden=""
|
|
114
|
+
id="section-two-panel"
|
|
115
|
+
role="region"
|
|
116
|
+
>
|
|
117
|
+
<div>
|
|
118
|
+
<div>
|
|
119
|
+
section two
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</DocumentFragment>
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
exports[`ContentGroupAccordion component matches snapshot and renders variant accordion 1`] = `
|
|
130
|
+
<DocumentFragment>
|
|
131
|
+
<div
|
|
132
|
+
class="content-group-accordion"
|
|
133
|
+
>
|
|
134
|
+
<div
|
|
135
|
+
aria-label="testAccordion"
|
|
136
|
+
class="content-group-accordion__items"
|
|
137
|
+
>
|
|
138
|
+
<div
|
|
139
|
+
class="content-group-accordion__item"
|
|
140
|
+
>
|
|
141
|
+
<h3
|
|
142
|
+
class="content-group-accordion__heading"
|
|
143
|
+
>
|
|
144
|
+
<button
|
|
145
|
+
aria-controls="section-one-panel"
|
|
146
|
+
aria-expanded="false"
|
|
147
|
+
class="content-group-accordion__header-btn"
|
|
148
|
+
id="section-one"
|
|
149
|
+
type="button"
|
|
150
|
+
>
|
|
151
|
+
<span
|
|
152
|
+
class="content-group-accordion__title"
|
|
153
|
+
>
|
|
154
|
+
sectionOne
|
|
155
|
+
</span>
|
|
156
|
+
<span
|
|
157
|
+
aria-hidden="true"
|
|
158
|
+
class="content-group-accordion__chevron"
|
|
159
|
+
>
|
|
160
|
+
<svg
|
|
161
|
+
class="content-group-accordion__chevron-icon"
|
|
162
|
+
fill="currentColor"
|
|
163
|
+
height="1em"
|
|
164
|
+
stroke="currentColor"
|
|
165
|
+
stroke-width="0"
|
|
166
|
+
viewBox="0 0 16 16"
|
|
167
|
+
width="1em"
|
|
168
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
169
|
+
>
|
|
170
|
+
<path
|
|
171
|
+
clip-rule="evenodd"
|
|
172
|
+
d="M7.976 10.072l4.357-4.357.62.618L8.284 11h-.618L3 6.333l.619-.618 4.357 4.357z"
|
|
173
|
+
fill-rule="evenodd"
|
|
174
|
+
/>
|
|
175
|
+
</svg>
|
|
176
|
+
</span>
|
|
177
|
+
</button>
|
|
178
|
+
</h3>
|
|
179
|
+
<div
|
|
180
|
+
data-testid="variant"
|
|
181
|
+
>
|
|
182
|
+
<div>
|
|
183
|
+
<div>
|
|
184
|
+
section one
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
<div
|
|
190
|
+
class="content-group-accordion__item"
|
|
191
|
+
>
|
|
192
|
+
<h3
|
|
193
|
+
class="content-group-accordion__heading"
|
|
194
|
+
>
|
|
195
|
+
<button
|
|
196
|
+
aria-controls="section-two-panel"
|
|
197
|
+
aria-expanded="false"
|
|
198
|
+
class="content-group-accordion__header-btn"
|
|
199
|
+
id="section-two"
|
|
200
|
+
type="button"
|
|
201
|
+
>
|
|
202
|
+
<span
|
|
203
|
+
class="content-group-accordion__title"
|
|
204
|
+
>
|
|
205
|
+
sectionTwo
|
|
206
|
+
</span>
|
|
207
|
+
<span
|
|
208
|
+
aria-hidden="true"
|
|
209
|
+
class="content-group-accordion__chevron"
|
|
210
|
+
>
|
|
211
|
+
<svg
|
|
212
|
+
class="content-group-accordion__chevron-icon"
|
|
213
|
+
fill="currentColor"
|
|
214
|
+
height="1em"
|
|
215
|
+
stroke="currentColor"
|
|
216
|
+
stroke-width="0"
|
|
217
|
+
viewBox="0 0 16 16"
|
|
218
|
+
width="1em"
|
|
219
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
220
|
+
>
|
|
221
|
+
<path
|
|
222
|
+
clip-rule="evenodd"
|
|
223
|
+
d="M7.976 10.072l4.357-4.357.62.618L8.284 11h-.618L3 6.333l.619-.618 4.357 4.357z"
|
|
224
|
+
fill-rule="evenodd"
|
|
225
|
+
/>
|
|
226
|
+
</svg>
|
|
227
|
+
</span>
|
|
228
|
+
</button>
|
|
229
|
+
</h3>
|
|
230
|
+
<div
|
|
231
|
+
data-testid="variant"
|
|
232
|
+
>
|
|
233
|
+
<div>
|
|
234
|
+
<div>
|
|
235
|
+
section two
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</DocumentFragment>
|
|
243
|
+
`;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import getStructuredDataProperties from '../../../../../../src/components/ContentGroup/helpers/get-structured-data-properties';
|
|
2
|
+
|
|
3
|
+
describe('getStructuredDataProperties helper', () => {
|
|
4
|
+
describe('when isFaqContent is false/true', () => {
|
|
5
|
+
it('should return empty properties object', () => {
|
|
6
|
+
const result = getStructuredDataProperties(false);
|
|
7
|
+
|
|
8
|
+
expect(result).toEqual({
|
|
9
|
+
topWrapperProps: {},
|
|
10
|
+
groupSectionProps: {},
|
|
11
|
+
groupSectionTitleProps: {},
|
|
12
|
+
groupContentWrapperProps: {},
|
|
13
|
+
groupContentProps: {}
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should return structured data properties for FAQ content', () => {
|
|
18
|
+
const result = getStructuredDataProperties(true);
|
|
19
|
+
|
|
20
|
+
expect(result).toEqual({
|
|
21
|
+
topWrapperProps: {
|
|
22
|
+
itemScope: true,
|
|
23
|
+
itemType: 'https://schema.org/FAQPage'
|
|
24
|
+
},
|
|
25
|
+
groupSectionProps: {
|
|
26
|
+
itemScope: true,
|
|
27
|
+
itemProp: 'mainEntity',
|
|
28
|
+
itemType: 'https://schema.org/Question'
|
|
29
|
+
},
|
|
30
|
+
groupSectionTitleProps: {
|
|
31
|
+
itemProp: 'name'
|
|
32
|
+
},
|
|
33
|
+
groupContentWrapperProps: {
|
|
34
|
+
itemScope: true,
|
|
35
|
+
itemProp: 'acceptedAnswer',
|
|
36
|
+
itemType: 'https://schema.org/Answer'
|
|
37
|
+
},
|
|
38
|
+
groupContentProps: {
|
|
39
|
+
itemProp: 'text'
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('structured data compliance', () => {
|
|
46
|
+
it('should provide valid schema.org URLs for FAQ structured data', () => {
|
|
47
|
+
const result = getStructuredDataProperties(true);
|
|
48
|
+
|
|
49
|
+
expect(result.topWrapperProps.itemType).toBe('https://schema.org/FAQPage');
|
|
50
|
+
expect(result.groupSectionProps.itemType).toBe('https://schema.org/Question');
|
|
51
|
+
expect(result.groupContentWrapperProps.itemType).toBe('https://schema.org/Answer');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should provide correct microdata properties for FAQ structure', () => {
|
|
55
|
+
const result = getStructuredDataProperties(true);
|
|
56
|
+
|
|
57
|
+
// Check that all itemScope properties are boolean true
|
|
58
|
+
expect(result.topWrapperProps.itemScope).toBe(true);
|
|
59
|
+
expect(result.groupSectionProps.itemScope).toBe(true);
|
|
60
|
+
expect(result.groupContentWrapperProps.itemScope).toBe(true);
|
|
61
|
+
|
|
62
|
+
// Check itemProp values
|
|
63
|
+
expect(result.groupSectionProps.itemProp).toBe('mainEntity');
|
|
64
|
+
expect(result.groupSectionTitleProps.itemProp).toBe('name');
|
|
65
|
+
expect(result.groupContentWrapperProps.itemProp).toBe('acceptedAnswer');
|
|
66
|
+
expect(result.groupContentProps.itemProp).toBe('text');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should maintain consistent property structure', () => {
|
|
70
|
+
const faqResult = getStructuredDataProperties(true);
|
|
71
|
+
const nonFaqResult = getStructuredDataProperties(false);
|
|
72
|
+
|
|
73
|
+
// Both should have the same property keys
|
|
74
|
+
expect(Object.keys(faqResult)).toEqual(Object.keys(nonFaqResult));
|
|
75
|
+
expect(Object.keys(faqResult)).toEqual([
|
|
76
|
+
'topWrapperProps',
|
|
77
|
+
'groupSectionProps',
|
|
78
|
+
'groupSectionTitleProps',
|
|
79
|
+
'groupContentWrapperProps',
|
|
80
|
+
'groupContentProps'
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('return value immutability', () => {
|
|
86
|
+
it('should return a new object each time it is called', () => {
|
|
87
|
+
const result1 = getStructuredDataProperties(true);
|
|
88
|
+
const result2 = getStructuredDataProperties(true);
|
|
89
|
+
|
|
90
|
+
expect(result1).not.toBe(result2);
|
|
91
|
+
expect(result1).toEqual(result2);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should return nested objects that are independent', () => {
|
|
95
|
+
const result1 = getStructuredDataProperties(true);
|
|
96
|
+
const result2 = getStructuredDataProperties(true);
|
|
97
|
+
|
|
98
|
+
expect(result1.topWrapperProps).not.toBe(result2.topWrapperProps);
|
|
99
|
+
expect(result1.groupSectionProps).not.toBe(result2.groupSectionProps);
|
|
100
|
+
expect(result1.groupSectionTitleProps).not.toBe(result2.groupSectionTitleProps);
|
|
101
|
+
expect(result1.groupContentWrapperProps).not.toBe(result2.groupContentWrapperProps);
|
|
102
|
+
expect(result1.groupContentProps).not.toBe(result2.groupContentProps);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -19,11 +19,6 @@ jest.mock('next/router', () => ({
|
|
|
19
19
|
useRouter: () => ({ asPath: '/' })
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
|
-
// todo: add extra tests to support this util
|
|
23
|
-
jest.mock('../../../../../src/components/MenuItem/helpers/has-active-child', () =>
|
|
24
|
-
jest.fn(() => false)
|
|
25
|
-
);
|
|
26
|
-
|
|
27
22
|
const componentProps = {
|
|
28
23
|
id: 'id',
|
|
29
24
|
name: 'mock name',
|
|
@@ -11,22 +11,14 @@ const MENU_ITEM_CHILDREN_CLASS = 'menu--item-children';
|
|
|
11
11
|
|
|
12
12
|
let mockAsPathValue = '/';
|
|
13
13
|
|
|
14
|
-
jest.mock('next/router', () => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
useRouter: () => router
|
|
18
|
-
};
|
|
19
|
-
});
|
|
14
|
+
jest.mock('next/router', () => ({
|
|
15
|
+
useRouter: () => ({ asPath: mockAsPathValue })
|
|
16
|
+
}));
|
|
20
17
|
|
|
21
18
|
jest.mock('@blaze-cms/utils-handlebars', () => ({
|
|
22
19
|
useStringTemplate: jest.fn((parent, [title]) => ({ loading: false, data: [title] }))
|
|
23
20
|
}));
|
|
24
21
|
|
|
25
|
-
// todo: add extra tests to support this util
|
|
26
|
-
jest.mock('../../../../../src/components/MenuItem/helpers/has-active-child', () =>
|
|
27
|
-
jest.fn(() => false)
|
|
28
|
-
);
|
|
29
|
-
|
|
30
22
|
describe('MenuRender component', () => {
|
|
31
23
|
it('renders menu item with link when URL is provided', () => {
|
|
32
24
|
const { getByText } = render(<MenuRender eventType="click" text="Home" url="/home" />);
|