@squiz/resource-browser 1.32.1-alpha.12
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/.storybook/main.ts +23 -0
- package/.storybook/preview-head.html +15 -0
- package/.storybook/preview.ts +16 -0
- package/build.js +21 -0
- package/jest.config.ts +18 -0
- package/lib/Icons/Generics/ArrowDown.d.ts +15 -0
- package/lib/Icons/Generics/ArrowDown.js +23 -0
- package/lib/Icons/Generics/ArrowRight.d.ts +15 -0
- package/lib/Icons/Generics/ArrowRight.js +23 -0
- package/lib/Icons/Generics/Close.d.ts +15 -0
- package/lib/Icons/Generics/Close.js +23 -0
- package/lib/Icons/Generics/GenericIconMap.d.ts +10 -0
- package/lib/Icons/Generics/GenericIconMap.js +14 -0
- package/lib/Icons/Generics/ResourceSelect.d.ts +15 -0
- package/lib/Icons/Generics/ResourceSelect.js +28 -0
- package/lib/Icons/Generics/Root.d.ts +15 -0
- package/lib/Icons/Generics/Root.js +23 -0
- package/lib/Icons/Generics/Selected.d.ts +15 -0
- package/lib/Icons/Generics/Selected.js +23 -0
- package/lib/Icons/Generics/index.d.ts +6 -0
- package/lib/Icons/Generics/index.js +19 -0
- package/lib/Icons/Icon.d.ts +47 -0
- package/lib/Icons/Icon.js +44 -0
- package/lib/Icons/MatrixResources/Audio.d.ts +15 -0
- package/lib/Icons/MatrixResources/Audio.js +28 -0
- package/lib/Icons/MatrixResources/Excel.d.ts +15 -0
- package/lib/Icons/MatrixResources/Excel.js +27 -0
- package/lib/Icons/MatrixResources/Folder.d.ts +15 -0
- package/lib/Icons/MatrixResources/Folder.js +24 -0
- package/lib/Icons/MatrixResources/GenericFile.d.ts +15 -0
- package/lib/Icons/MatrixResources/GenericFile.js +28 -0
- package/lib/Icons/MatrixResources/Image.d.ts +15 -0
- package/lib/Icons/MatrixResources/Image.js +26 -0
- package/lib/Icons/MatrixResources/MatrixResourceMap.d.ts +15 -0
- package/lib/Icons/MatrixResources/MatrixResourceMap.js +19 -0
- package/lib/Icons/MatrixResources/Page.d.ts +15 -0
- package/lib/Icons/MatrixResources/Page.js +30 -0
- package/lib/Icons/MatrixResources/Pdf.d.ts +15 -0
- package/lib/Icons/MatrixResources/Pdf.js +31 -0
- package/lib/Icons/MatrixResources/Powerpoint.d.ts +15 -0
- package/lib/Icons/MatrixResources/Powerpoint.js +28 -0
- package/lib/Icons/MatrixResources/Site.d.ts +15 -0
- package/lib/Icons/MatrixResources/Site.js +30 -0
- package/lib/Icons/MatrixResources/Video.d.ts +15 -0
- package/lib/Icons/MatrixResources/Video.js +24 -0
- package/lib/Icons/MatrixResources/Word.d.ts +17 -0
- package/lib/Icons/MatrixResources/Word.js +28 -0
- package/lib/Icons/MatrixResources/index.d.ts +11 -0
- package/lib/Icons/MatrixResources/index.js +29 -0
- package/lib/Modal/Modal.d.ts +11 -0
- package/lib/Modal/Modal.js +46 -0
- package/lib/Modal/ModalOpeningButton.d.ts +10 -0
- package/lib/Modal/ModalOpeningButton.js +13 -0
- package/lib/Modal/ModalTrigger.d.ts +9 -0
- package/lib/Modal/ModalTrigger.js +24 -0
- package/lib/PreviewPanel/PreviewModal.d.ts +11 -0
- package/lib/PreviewPanel/PreviewModal.js +81 -0
- package/lib/PreviewPanel/PreviewPanel.d.ts +16 -0
- package/lib/PreviewPanel/PreviewPanel.js +87 -0
- package/lib/PreviewPanel/details/MatrixResource.d.ts +12 -0
- package/lib/PreviewPanel/details/MatrixResource.js +41 -0
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.d.ts +9 -0
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.js +20 -0
- package/lib/ResourceItem/ResourceItem.d.ts +19 -0
- package/lib/ResourceItem/ResourceItem.js +26 -0
- package/lib/ResourceList/ResourceList.d.ts +14 -0
- package/lib/ResourceList/ResourceList.js +51 -0
- package/lib/ResourcePickerContainer/ResourcePickerContainer.d.ts +15 -0
- package/lib/ResourcePickerContainer/ResourcePickerContainer.js +145 -0
- package/lib/Skeleton/List/SkeletonList.d.ts +6 -0
- package/lib/Skeleton/List/SkeletonList.js +13 -0
- package/lib/Skeleton/ListItem/SkeletonListItem.d.ts +2 -0
- package/lib/Skeleton/ListItem/SkeletonListItem.js +15 -0
- package/lib/SourceDropdown/SourceDropdown.d.ts +9 -0
- package/lib/SourceDropdown/SourceDropdown.js +106 -0
- package/lib/SourceList/SourceList.d.ts +14 -0
- package/lib/SourceList/SourceList.js +58 -0
- package/lib/Spinner/Spinner.d.ts +8 -0
- package/lib/Spinner/Spinner.js +12 -0
- package/lib/index.css +968 -0
- package/lib/index.d.ts +37 -0
- package/lib/index.js +15 -0
- package/lib/uuid.d.ts +1 -0
- package/lib/uuid.js +8 -0
- package/package.json +74 -0
- package/postcss.config.js +11 -0
- package/src/Icons/Generics/ArrowDown.tsx +27 -0
- package/src/Icons/Generics/ArrowRight.tsx +27 -0
- package/src/Icons/Generics/Close.tsx +26 -0
- package/src/Icons/Generics/GenericIconMap.ts +14 -0
- package/src/Icons/Generics/ResourceSelect.tsx +40 -0
- package/src/Icons/Generics/Root.tsx +24 -0
- package/src/Icons/Generics/Selected.tsx +27 -0
- package/src/Icons/Generics/index.tsx +7 -0
- package/src/Icons/Icon.spec.tsx +62 -0
- package/src/Icons/Icon.stories.tsx +105 -0
- package/src/Icons/Icon.tsx +61 -0
- package/src/Icons/MatrixResources/Audio.tsx +30 -0
- package/src/Icons/MatrixResources/Excel.tsx +29 -0
- package/src/Icons/MatrixResources/Folder.tsx +29 -0
- package/src/Icons/MatrixResources/GenericFile.tsx +34 -0
- package/src/Icons/MatrixResources/Image.tsx +36 -0
- package/src/Icons/MatrixResources/MatrixResourceMap.ts +19 -0
- package/src/Icons/MatrixResources/Page.tsx +33 -0
- package/src/Icons/MatrixResources/Pdf.tsx +34 -0
- package/src/Icons/MatrixResources/Powerpoint.tsx +34 -0
- package/src/Icons/MatrixResources/Site.tsx +37 -0
- package/src/Icons/MatrixResources/Video.tsx +27 -0
- package/src/Icons/MatrixResources/Word.tsx +30 -0
- package/src/Icons/MatrixResources/index.tsx +12 -0
- package/src/Modal/Modal.spec.tsx +244 -0
- package/src/Modal/Modal.tsx +58 -0
- package/src/Modal/ModalContainer.stories.tsx +33 -0
- package/src/Modal/ModalOpeningButton.tsx +20 -0
- package/src/Modal/ModalTrigger.tsx +45 -0
- package/src/PreviewPanel/PreviewModal.spec.tsx +164 -0
- package/src/PreviewPanel/PreviewModal.tsx +92 -0
- package/src/PreviewPanel/PreviewPanel.spec.tsx +197 -0
- package/src/PreviewPanel/PreviewPanel.stories.tsx +61 -0
- package/src/PreviewPanel/PreviewPanel.tsx +123 -0
- package/src/PreviewPanel/details/MatrixResource.tsx +59 -0
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.spec.tsx +76 -0
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.stories.tsx +24 -0
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.tsx +39 -0
- package/src/ResourceBreadcrumb/sample-hierarchy.json +23 -0
- package/src/ResourceItem/ResourceItem.spec.tsx +69 -0
- package/src/ResourceItem/ResourceItem.tsx +82 -0
- package/src/ResourceList/ResourceList.spec.tsx +196 -0
- package/src/ResourceList/ResourceList.stories.tsx +40 -0
- package/src/ResourceList/ResourceList.tsx +74 -0
- package/src/ResourceList/sample-resources.json +75 -0
- package/src/ResourcePickerContainer/ResourcePickerContainer.spec.tsx +706 -0
- package/src/ResourcePickerContainer/ResourcePickerContainer.stories.tsx +56 -0
- package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +224 -0
- package/src/Skeleton/List/SkeletonList.spec.tsx +18 -0
- package/src/Skeleton/List/SkeletonList.stories.tsx +15 -0
- package/src/Skeleton/List/SkeletonList.tsx +16 -0
- package/src/Skeleton/ListItem/SkeletonListItem.stories.tsx +15 -0
- package/src/Skeleton/ListItem/SkeletonListItem.tsx +14 -0
- package/src/SourceDropdown/SourceDropdown.spec.tsx +263 -0
- package/src/SourceDropdown/SourceDropdown.stories.tsx +36 -0
- package/src/SourceDropdown/SourceDropdown.tsx +175 -0
- package/src/SourceDropdown/sample-sources.json +110 -0
- package/src/SourceList/SourceList.spec.tsx +224 -0
- package/src/SourceList/SourceList.stories.tsx +40 -0
- package/src/SourceList/SourceList.tsx +93 -0
- package/src/SourceList/sample-sources.json +110 -0
- package/src/Spinner/Spinner.spec.tsx +18 -0
- package/src/Spinner/Spinner.stories.tsx +26 -0
- package/src/Spinner/Spinner.tsx +18 -0
- package/src/Spinner/_spinner.scss +11 -0
- package/src/__mocks__/JestHelpers.ts +65 -0
- package/src/__mocks__/jestHelpers.spec.ts +38 -0
- package/src/__mocks__/styleMock.ts +1 -0
- package/src/index.scss +7 -0
- package/src/index.stories.tsx +70 -0
- package/src/index.tsx +71 -0
- package/src/uuid.ts +7 -0
- package/tailwind.config.cjs +84 -0
- package/tsconfig.json +22 -0
@@ -0,0 +1,706 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
2
|
+
import React from 'react';
|
3
|
+
import { screen, render, waitFor, within } from '@testing-library/react';
|
4
|
+
import userEvent from '@testing-library/user-event';
|
5
|
+
|
6
|
+
import { Context as ResponsiveContext } from 'react-responsive';
|
7
|
+
import { OverlayTriggerState } from 'react-stately';
|
8
|
+
|
9
|
+
import type { Hierarchy } from '../index';
|
10
|
+
import ResourcePickerContainer from './ResourcePickerContainer';
|
11
|
+
|
12
|
+
import SourceList, { SourceListProps } from '../SourceList/SourceList'; // Import Functional Component
|
13
|
+
jest.mock('../SourceList/SourceList'); // Mock the Functional Component
|
14
|
+
const ActualSourceList = jest.requireActual('../SourceList/SourceList').default; // Grab the real copy of it as normally we don't want the mock
|
15
|
+
const MockSourceList = SourceList as jest.MockedFunction<typeof SourceList>; // Cast the mocked function so TS stops complaining
|
16
|
+
MockSourceList.mockImplementation(ActualSourceList); // Return the actual function unless overridden
|
17
|
+
|
18
|
+
import ResourceList, { ResourceListProps } from '../ResourceList/ResourceList'; // Import Functional Component
|
19
|
+
jest.mock('../ResourceList/ResourceList'); // Mock the Functional Component
|
20
|
+
const ActualResourceList = jest.requireActual('../ResourceList/ResourceList').default; // Grab the real copy of it as normally we don't want the mock
|
21
|
+
const MockResourceList = ResourceList as jest.MockedFunction<typeof ResourceList>; // Cast the mocked function so TS stops complaining
|
22
|
+
MockResourceList.mockImplementation(ActualResourceList); // Return the actual function unless overridden
|
23
|
+
|
24
|
+
import PreviewPanel, { PreviewPanelProps } from '../PreviewPanel/PreviewPanel'; // Import Functional Component
|
25
|
+
jest.mock('../PreviewPanel/PreviewPanel'); // Mock the Functional Component
|
26
|
+
const ActualPreviewPanel = jest.requireActual('../PreviewPanel/PreviewPanel').default; // Grab the real copy of it as normally we don't want the mock
|
27
|
+
const MockPreviewPanel = PreviewPanel as jest.MockedFunction<typeof PreviewPanel>; // Cast the mocked function so TS stops complaining
|
28
|
+
MockPreviewPanel.mockImplementation(ActualPreviewPanel); // Return the actual function unless overridden
|
29
|
+
|
30
|
+
import ResourceBreadcrumb, { ResourceBreadcrumbProps } from '../ResourceBreadcrumb/ResourceBreadcrumb'; // Import Functional Component
|
31
|
+
jest.mock('../ResourceBreadcrumb/ResourceBreadcrumb'); // Mock the Functional Component
|
32
|
+
const ActualResourceBreadcrumb = jest.requireActual('../ResourceBreadcrumb/ResourceBreadcrumb').default; // Grab the real copy of it as normally we don't want the mock
|
33
|
+
const MockResourceBreadcrumb = ResourceBreadcrumb as jest.MockedFunction<typeof ResourceBreadcrumb>; // Cast the mocked function so TS stops complaining
|
34
|
+
MockResourceBreadcrumb.mockImplementation(ActualResourceBreadcrumb); // Return the actual function unless overridden
|
35
|
+
|
36
|
+
const baseProps = {
|
37
|
+
title: 'Testing',
|
38
|
+
titleAriaProps: {},
|
39
|
+
allowedTypes: undefined,
|
40
|
+
onClose: () => {},
|
41
|
+
onRequestSources: () => {
|
42
|
+
return Promise.resolve([
|
43
|
+
{
|
44
|
+
id: '1',
|
45
|
+
name: 'Test system',
|
46
|
+
nodes: [
|
47
|
+
{
|
48
|
+
id: {
|
49
|
+
id: '1',
|
50
|
+
source: '1',
|
51
|
+
},
|
52
|
+
type: 'site',
|
53
|
+
selected: false,
|
54
|
+
label: 'Test Website',
|
55
|
+
childCount: 21,
|
56
|
+
},
|
57
|
+
],
|
58
|
+
},
|
59
|
+
]);
|
60
|
+
},
|
61
|
+
onRequestChildren: () => {
|
62
|
+
return Promise.resolve([
|
63
|
+
{
|
64
|
+
id: {
|
65
|
+
id: '1',
|
66
|
+
source: '1',
|
67
|
+
},
|
68
|
+
type: 'page',
|
69
|
+
selected: false,
|
70
|
+
label: 'Test Page',
|
71
|
+
childCount: 0,
|
72
|
+
},
|
73
|
+
]);
|
74
|
+
},
|
75
|
+
onRequestResource: () => {
|
76
|
+
return Promise.resolve({
|
77
|
+
type: 'page',
|
78
|
+
name: 'Products',
|
79
|
+
properties: new Map([
|
80
|
+
['assetId', '12345'],
|
81
|
+
['status', 'UnderConstruction'],
|
82
|
+
]),
|
83
|
+
});
|
84
|
+
},
|
85
|
+
onChange: () => {},
|
86
|
+
};
|
87
|
+
|
88
|
+
describe('ResourcePickerContainer', () => {
|
89
|
+
it('Queries onRequestSources for source list on startup', async () => {
|
90
|
+
const onRequestSources = jest.fn(() => {
|
91
|
+
return Promise.resolve([]);
|
92
|
+
});
|
93
|
+
|
94
|
+
const { getByLabelText } = render(<ResourcePickerContainer {...baseProps} onRequestSources={onRequestSources} />);
|
95
|
+
await waitFor(() => {
|
96
|
+
expect(getByLabelText('Source list')).toBeInTheDocument();
|
97
|
+
});
|
98
|
+
|
99
|
+
expect(onRequestSources).toHaveBeenCalled();
|
100
|
+
});
|
101
|
+
|
102
|
+
it('Renders provided sources from onRequestSources', async () => {
|
103
|
+
const onRequestSources = jest.fn(() => {
|
104
|
+
return Promise.resolve([
|
105
|
+
{
|
106
|
+
id: '1',
|
107
|
+
name: 'Test system 1',
|
108
|
+
nodes: [
|
109
|
+
{
|
110
|
+
id: {
|
111
|
+
id: '1',
|
112
|
+
source: '1',
|
113
|
+
},
|
114
|
+
type: 'site',
|
115
|
+
selected: false,
|
116
|
+
label: 'Test Website 1',
|
117
|
+
childCount: 21,
|
118
|
+
},
|
119
|
+
],
|
120
|
+
},
|
121
|
+
{
|
122
|
+
id: '2',
|
123
|
+
name: 'Test system 2',
|
124
|
+
nodes: [
|
125
|
+
{
|
126
|
+
id: {
|
127
|
+
id: '1',
|
128
|
+
source: '2',
|
129
|
+
},
|
130
|
+
type: 'site',
|
131
|
+
selected: false,
|
132
|
+
label: 'Test Website 2',
|
133
|
+
childCount: 21,
|
134
|
+
},
|
135
|
+
{
|
136
|
+
id: {
|
137
|
+
id: '2',
|
138
|
+
source: '2',
|
139
|
+
},
|
140
|
+
type: 'site',
|
141
|
+
selected: false,
|
142
|
+
label: 'Test Website 3',
|
143
|
+
childCount: 21,
|
144
|
+
},
|
145
|
+
],
|
146
|
+
},
|
147
|
+
]);
|
148
|
+
});
|
149
|
+
|
150
|
+
const { getAllByText } = render(<ResourcePickerContainer {...baseProps} onRequestSources={onRequestSources} />);
|
151
|
+
await waitFor(() => {
|
152
|
+
expect(getAllByText('Test system 1')[0]).toBeInTheDocument();
|
153
|
+
});
|
154
|
+
|
155
|
+
await waitFor(() => {
|
156
|
+
const sourceList = screen.getByLabelText('Source list');
|
157
|
+
expect(within(sourceList).getByText('Test system 1')).toBeTruthy();
|
158
|
+
expect(within(sourceList).getByText('Test Website 1')).toBeTruthy();
|
159
|
+
|
160
|
+
expect(within(sourceList).getByText('Test system 2')).toBeTruthy();
|
161
|
+
expect(within(sourceList).getByText('Test Website 2')).toBeTruthy();
|
162
|
+
expect(within(sourceList).getByText('Test Website 3')).toBeTruthy();
|
163
|
+
});
|
164
|
+
});
|
165
|
+
|
166
|
+
it('Selecting a child count drills down', async () => {
|
167
|
+
const onRequestChildren = jest.fn(() => {
|
168
|
+
return Promise.resolve([]);
|
169
|
+
});
|
170
|
+
|
171
|
+
// Component has finished initial render
|
172
|
+
const { getAllByText } = render(<ResourcePickerContainer {...baseProps} onRequestChildren={onRequestChildren} />);
|
173
|
+
await waitFor(() => {
|
174
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
175
|
+
});
|
176
|
+
|
177
|
+
// Click the drill down counter
|
178
|
+
const user = userEvent.setup();
|
179
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
|
180
|
+
|
181
|
+
await waitFor(() => {
|
182
|
+
expect(onRequestChildren).toHaveBeenCalled();
|
183
|
+
});
|
184
|
+
});
|
185
|
+
|
186
|
+
it('Drill down renders provided resources from onRequestChildren', async () => {
|
187
|
+
const onRequestChildren = jest.fn(() => {
|
188
|
+
return Promise.resolve([
|
189
|
+
{
|
190
|
+
id: {
|
191
|
+
id: '1',
|
192
|
+
source: '1',
|
193
|
+
},
|
194
|
+
type: 'page',
|
195
|
+
selected: false,
|
196
|
+
label: 'Test Page 1',
|
197
|
+
childCount: 0,
|
198
|
+
},
|
199
|
+
{
|
200
|
+
id: {
|
201
|
+
id: '2',
|
202
|
+
source: '1',
|
203
|
+
},
|
204
|
+
type: 'page',
|
205
|
+
selected: false,
|
206
|
+
label: 'Test Page 2',
|
207
|
+
childCount: 0,
|
208
|
+
},
|
209
|
+
{
|
210
|
+
id: {
|
211
|
+
id: '3',
|
212
|
+
source: '1',
|
213
|
+
},
|
214
|
+
type: 'folder',
|
215
|
+
selected: false,
|
216
|
+
label: 'Test Page 3',
|
217
|
+
childCount: 31,
|
218
|
+
},
|
219
|
+
]);
|
220
|
+
});
|
221
|
+
|
222
|
+
// Component has finished initial render
|
223
|
+
const { getAllByText } = render(<ResourcePickerContainer {...baseProps} onRequestChildren={onRequestChildren} />);
|
224
|
+
await waitFor(() => {
|
225
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
226
|
+
});
|
227
|
+
|
228
|
+
// Click the drill down counter
|
229
|
+
const user = userEvent.setup();
|
230
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
|
231
|
+
|
232
|
+
await waitFor(() => {
|
233
|
+
expect(screen.getByText('Test Page 1')).toBeTruthy();
|
234
|
+
expect(screen.getByText('Test Page 2')).toBeTruthy();
|
235
|
+
expect(screen.getByText('Test Page 3')).toBeTruthy();
|
236
|
+
});
|
237
|
+
});
|
238
|
+
|
239
|
+
it('Selecting a node shows its properties in the details panel', async () => {
|
240
|
+
const { getByText, getAllByText } = render(<ResourcePickerContainer {...baseProps} />);
|
241
|
+
await waitFor(() => {
|
242
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
243
|
+
});
|
244
|
+
|
245
|
+
// Is on base page
|
246
|
+
expect(screen.getByLabelText('Source list')).toBeTruthy();
|
247
|
+
|
248
|
+
// Click the drill down counter
|
249
|
+
const user = userEvent.setup();
|
250
|
+
user.click(screen.getByRole('button', { name: 'site Test Website' }));
|
251
|
+
|
252
|
+
await waitFor(() => {
|
253
|
+
expect(getByText('Products')).toBeInTheDocument();
|
254
|
+
});
|
255
|
+
|
256
|
+
await waitFor(() => {
|
257
|
+
expect(screen.getByText('Products')).toBeTruthy();
|
258
|
+
expect(screen.getByText('page')).toBeTruthy();
|
259
|
+
expect(screen.getByText('#12345')).toBeTruthy();
|
260
|
+
});
|
261
|
+
});
|
262
|
+
|
263
|
+
it('Mobile: Selecting a node shows its properties in the details panel', async () => {
|
264
|
+
const { getByText, getAllByText } = render(
|
265
|
+
<ResponsiveContext.Provider value={{ width: 360 }}>
|
266
|
+
<ResourcePickerContainer {...baseProps} />
|
267
|
+
</ResponsiveContext.Provider>,
|
268
|
+
);
|
269
|
+
await waitFor(() => {
|
270
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
271
|
+
});
|
272
|
+
|
273
|
+
// Click the drill down counter
|
274
|
+
const user = userEvent.setup();
|
275
|
+
user.click(screen.getByRole('button', { name: 'site Test Website' }));
|
276
|
+
|
277
|
+
await waitFor(() => {
|
278
|
+
expect(getByText('Products')).toBeInTheDocument();
|
279
|
+
});
|
280
|
+
|
281
|
+
await waitFor(() => {
|
282
|
+
expect(screen.getByText('Products')).toBeTruthy();
|
283
|
+
expect(screen.getByText('page')).toBeTruthy();
|
284
|
+
expect(screen.getByText('#12345')).toBeTruthy();
|
285
|
+
});
|
286
|
+
});
|
287
|
+
|
288
|
+
it('Closing the details panel deselects the node', async () => {
|
289
|
+
const { getByText, getAllByText } = render(
|
290
|
+
<ResponsiveContext.Provider value={{ width: 360 }}>
|
291
|
+
<ResourcePickerContainer {...baseProps} />
|
292
|
+
</ResponsiveContext.Provider>,
|
293
|
+
);
|
294
|
+
await waitFor(() => {
|
295
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
296
|
+
});
|
297
|
+
|
298
|
+
// Click the drill down counter
|
299
|
+
const user = userEvent.setup();
|
300
|
+
user.click(screen.getByRole('button', { name: 'site Test Website' }));
|
301
|
+
await waitFor(() => {
|
302
|
+
expect(getByText('Products')).toBeInTheDocument();
|
303
|
+
});
|
304
|
+
|
305
|
+
user.click(screen.getByRole('button', { name: 'Close details' }));
|
306
|
+
|
307
|
+
await waitFor(() => {
|
308
|
+
// Is now on child page
|
309
|
+
expect(screen.queryByText('Products')).toBeFalsy();
|
310
|
+
expect(screen.queryByText('page')).toBeFalsy();
|
311
|
+
expect(screen.queryByText('#12345')).toBeFalsy();
|
312
|
+
});
|
313
|
+
});
|
314
|
+
|
315
|
+
it('Passes modal state down to child components: SourceList', async () => {
|
316
|
+
let mockModalState: OverlayTriggerState | null = null;
|
317
|
+
|
318
|
+
MockSourceList.mockImplementation((args: SourceListProps) => {
|
319
|
+
mockModalState = args.previewModalState;
|
320
|
+
return ActualSourceList(args);
|
321
|
+
});
|
322
|
+
|
323
|
+
render(<ResourcePickerContainer {...baseProps} />);
|
324
|
+
|
325
|
+
expect(mockModalState).toEqual(
|
326
|
+
expect.objectContaining({
|
327
|
+
close: expect.any(Function),
|
328
|
+
isOpen: expect.any(Boolean),
|
329
|
+
open: expect.any(Function),
|
330
|
+
setOpen: expect.any(Function),
|
331
|
+
toggle: expect.any(Function),
|
332
|
+
}),
|
333
|
+
);
|
334
|
+
});
|
335
|
+
|
336
|
+
it('Passes modal state down to child components: ResourceList', async () => {
|
337
|
+
let mockModalState: OverlayTriggerState | null = null;
|
338
|
+
|
339
|
+
MockResourceList.mockImplementation((args: ResourceListProps) => {
|
340
|
+
mockModalState = args.previewModalState;
|
341
|
+
return ActualResourceList(args);
|
342
|
+
});
|
343
|
+
|
344
|
+
const { getByText, getAllByText } = render(<ResourcePickerContainer {...baseProps} />);
|
345
|
+
await waitFor(() => {
|
346
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
347
|
+
});
|
348
|
+
|
349
|
+
// Click the drill down counter
|
350
|
+
const user = userEvent.setup();
|
351
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
|
352
|
+
await waitFor(() => {
|
353
|
+
expect(getByText('Test Page')).toBeInTheDocument();
|
354
|
+
});
|
355
|
+
|
356
|
+
expect(mockModalState).toEqual(
|
357
|
+
expect.objectContaining({
|
358
|
+
close: expect.any(Function),
|
359
|
+
isOpen: expect.any(Boolean),
|
360
|
+
open: expect.any(Function),
|
361
|
+
setOpen: expect.any(Function),
|
362
|
+
toggle: expect.any(Function),
|
363
|
+
}),
|
364
|
+
);
|
365
|
+
});
|
366
|
+
|
367
|
+
it('Passes modal state down to child components: Details Panel', async () => {
|
368
|
+
let mockModalState: OverlayTriggerState | null = null;
|
369
|
+
|
370
|
+
MockPreviewPanel.mockImplementation((args: PreviewPanelProps) => {
|
371
|
+
mockModalState = args.modalState;
|
372
|
+
return ActualPreviewPanel(args);
|
373
|
+
});
|
374
|
+
|
375
|
+
const { getAllByText } = render(<ResourcePickerContainer {...baseProps} />);
|
376
|
+
await waitFor(() => {
|
377
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
378
|
+
});
|
379
|
+
|
380
|
+
const user = userEvent.setup();
|
381
|
+
user.click(screen.getByRole('button', { name: 'site Test Website' }));
|
382
|
+
|
383
|
+
expect(mockModalState).toEqual(
|
384
|
+
expect.objectContaining({
|
385
|
+
close: expect.any(Function),
|
386
|
+
isOpen: expect.any(Boolean),
|
387
|
+
open: expect.any(Function),
|
388
|
+
setOpen: expect.any(Function),
|
389
|
+
toggle: expect.any(Function),
|
390
|
+
}),
|
391
|
+
);
|
392
|
+
});
|
393
|
+
|
394
|
+
it('Breadcrumb hierarchy is added to on drill down', async () => {
|
395
|
+
let mockHierarchy: Array<Hierarchy> = [];
|
396
|
+
|
397
|
+
MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
|
398
|
+
mockHierarchy = args.hierarchy;
|
399
|
+
return ActualResourceBreadcrumb(args);
|
400
|
+
});
|
401
|
+
|
402
|
+
const { getByLabelText, getAllByText } = render(<ResourcePickerContainer {...baseProps} />);
|
403
|
+
await waitFor(() => {
|
404
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
405
|
+
});
|
406
|
+
|
407
|
+
const user = userEvent.setup();
|
408
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
|
409
|
+
|
410
|
+
// Breadcrumb is showing
|
411
|
+
await waitFor(() => {
|
412
|
+
expect(getByLabelText('Resource breadcrumb')).toBeInTheDocument();
|
413
|
+
});
|
414
|
+
|
415
|
+
// Expect the clicked child was added to breadcrumb
|
416
|
+
expect(mockHierarchy).toEqual([{ id: { id: '1', source: '1' }, label: 'Test Website' }]);
|
417
|
+
});
|
418
|
+
|
419
|
+
it('Multiple hierarchy is tracked on on drill down', async () => {
|
420
|
+
let mockHierarchy: Array<Hierarchy> = [];
|
421
|
+
|
422
|
+
MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
|
423
|
+
mockHierarchy = args.hierarchy;
|
424
|
+
return ActualResourceBreadcrumb(args);
|
425
|
+
});
|
426
|
+
|
427
|
+
const onRequestChildren = jest
|
428
|
+
.fn()
|
429
|
+
.mockImplementationOnce(() => {
|
430
|
+
return Promise.resolve([
|
431
|
+
{
|
432
|
+
id: {
|
433
|
+
id: '11',
|
434
|
+
source: '1',
|
435
|
+
},
|
436
|
+
type: 'page',
|
437
|
+
selected: false,
|
438
|
+
label: 'Test Page',
|
439
|
+
childCount: 4,
|
440
|
+
},
|
441
|
+
]);
|
442
|
+
})
|
443
|
+
.mockImplementationOnce(() => {
|
444
|
+
return Promise.resolve([
|
445
|
+
{
|
446
|
+
id: {
|
447
|
+
id: '111',
|
448
|
+
source: '1',
|
449
|
+
},
|
450
|
+
type: 'page',
|
451
|
+
selected: false,
|
452
|
+
label: 'Second Page',
|
453
|
+
childCount: 0,
|
454
|
+
},
|
455
|
+
]);
|
456
|
+
});
|
457
|
+
|
458
|
+
const { getByLabelText, getByText, getAllByText } = render(
|
459
|
+
<ResourcePickerContainer {...baseProps} onRequestChildren={onRequestChildren} />,
|
460
|
+
);
|
461
|
+
await waitFor(() => {
|
462
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
463
|
+
});
|
464
|
+
|
465
|
+
const user = userEvent.setup();
|
466
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
|
467
|
+
|
468
|
+
// Breadcrumb is showing
|
469
|
+
await waitFor(() => {
|
470
|
+
expect(getByLabelText('Resource breadcrumb')).toBeInTheDocument();
|
471
|
+
});
|
472
|
+
|
473
|
+
// Drill down again
|
474
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Page children' }));
|
475
|
+
|
476
|
+
await waitFor(() => {
|
477
|
+
expect(getByText('Second Page')).toBeInTheDocument();
|
478
|
+
});
|
479
|
+
|
480
|
+
// Expect the clicked child was added to breadcrumb
|
481
|
+
expect(mockHierarchy).toEqual([
|
482
|
+
{
|
483
|
+
id: {
|
484
|
+
id: '1',
|
485
|
+
source: '1',
|
486
|
+
},
|
487
|
+
label: 'Test Website',
|
488
|
+
},
|
489
|
+
{
|
490
|
+
id: {
|
491
|
+
id: '11',
|
492
|
+
source: '1',
|
493
|
+
},
|
494
|
+
label: 'Test Page',
|
495
|
+
},
|
496
|
+
]);
|
497
|
+
});
|
498
|
+
|
499
|
+
it('Can track multiple hierarchy jumping back', async () => {
|
500
|
+
let mockHierarchy: Array<Hierarchy> = [];
|
501
|
+
|
502
|
+
MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
|
503
|
+
mockHierarchy = args.hierarchy;
|
504
|
+
return ActualResourceBreadcrumb(args);
|
505
|
+
});
|
506
|
+
|
507
|
+
const onRequestChildren = jest
|
508
|
+
.fn()
|
509
|
+
.mockImplementationOnce(() => {
|
510
|
+
return Promise.resolve([
|
511
|
+
{
|
512
|
+
id: {
|
513
|
+
id: '11',
|
514
|
+
source: '1',
|
515
|
+
},
|
516
|
+
type: 'page',
|
517
|
+
selected: false,
|
518
|
+
label: 'Test Page',
|
519
|
+
childCount: 4,
|
520
|
+
},
|
521
|
+
]);
|
522
|
+
})
|
523
|
+
.mockImplementationOnce(() => {
|
524
|
+
return Promise.resolve([
|
525
|
+
{
|
526
|
+
id: {
|
527
|
+
id: '111',
|
528
|
+
source: '1',
|
529
|
+
},
|
530
|
+
type: 'page',
|
531
|
+
selected: false,
|
532
|
+
label: 'Second Page',
|
533
|
+
childCount: 0,
|
534
|
+
},
|
535
|
+
]);
|
536
|
+
})
|
537
|
+
.mockImplementationOnce(() => {
|
538
|
+
return Promise.resolve([
|
539
|
+
{
|
540
|
+
id: {
|
541
|
+
id: '11',
|
542
|
+
source: '1',
|
543
|
+
},
|
544
|
+
type: 'page',
|
545
|
+
selected: false,
|
546
|
+
label: 'Test Page',
|
547
|
+
childCount: 4,
|
548
|
+
},
|
549
|
+
]);
|
550
|
+
});
|
551
|
+
|
552
|
+
const { getByLabelText, getByText, getAllByText, queryByText } = render(
|
553
|
+
<ResourcePickerContainer {...baseProps} onRequestChildren={onRequestChildren} />,
|
554
|
+
);
|
555
|
+
await waitFor(() => {
|
556
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
557
|
+
});
|
558
|
+
|
559
|
+
const user = userEvent.setup();
|
560
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
|
561
|
+
|
562
|
+
// Breadcrumb is showing
|
563
|
+
await waitFor(() => {
|
564
|
+
expect(getByLabelText('Resource breadcrumb')).toBeInTheDocument();
|
565
|
+
});
|
566
|
+
|
567
|
+
// Drill down again
|
568
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Page children' }));
|
569
|
+
|
570
|
+
await waitFor(() => {
|
571
|
+
expect(getByText('Second Page')).toBeInTheDocument();
|
572
|
+
});
|
573
|
+
|
574
|
+
// Click on previous breadcrumb item
|
575
|
+
const breadcrumb = screen.getByLabelText('Resource breadcrumb');
|
576
|
+
user.click(within(breadcrumb).getByRole('button', { name: 'Test Website' }));
|
577
|
+
|
578
|
+
await waitFor(() => {
|
579
|
+
expect(queryByText('Second Page')).not.toBeInTheDocument();
|
580
|
+
});
|
581
|
+
|
582
|
+
// Expect the clicked child was added to breadcrumb
|
583
|
+
expect(mockHierarchy).toEqual([
|
584
|
+
{
|
585
|
+
id: {
|
586
|
+
id: '1',
|
587
|
+
source: '1',
|
588
|
+
},
|
589
|
+
label: 'Test Website',
|
590
|
+
},
|
591
|
+
]);
|
592
|
+
});
|
593
|
+
|
594
|
+
it('Multiple hierarchy can handle reset to new source', async () => {
|
595
|
+
let mockHierarchy: Array<Hierarchy> = [];
|
596
|
+
|
597
|
+
MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
|
598
|
+
mockHierarchy = args.hierarchy;
|
599
|
+
return ActualResourceBreadcrumb(args);
|
600
|
+
});
|
601
|
+
|
602
|
+
const onRequestChildren = jest
|
603
|
+
.fn()
|
604
|
+
.mockImplementationOnce(() => {
|
605
|
+
return Promise.resolve([
|
606
|
+
{
|
607
|
+
id: {
|
608
|
+
id: '11',
|
609
|
+
source: '1',
|
610
|
+
},
|
611
|
+
type: 'page',
|
612
|
+
selected: false,
|
613
|
+
label: 'Test Page',
|
614
|
+
childCount: 4,
|
615
|
+
},
|
616
|
+
]);
|
617
|
+
})
|
618
|
+
.mockImplementationOnce(() => {
|
619
|
+
return Promise.resolve([
|
620
|
+
{
|
621
|
+
id: {
|
622
|
+
id: '111',
|
623
|
+
source: '1',
|
624
|
+
},
|
625
|
+
type: 'page',
|
626
|
+
selected: false,
|
627
|
+
label: 'Second Page',
|
628
|
+
childCount: 0,
|
629
|
+
},
|
630
|
+
]);
|
631
|
+
});
|
632
|
+
|
633
|
+
const onRequestSources = jest.fn().mockImplementation(() => {
|
634
|
+
return Promise.resolve([
|
635
|
+
{
|
636
|
+
id: '1',
|
637
|
+
name: 'Test system',
|
638
|
+
nodes: [
|
639
|
+
{
|
640
|
+
id: {
|
641
|
+
id: '1',
|
642
|
+
source: '1',
|
643
|
+
},
|
644
|
+
type: 'site',
|
645
|
+
selected: false,
|
646
|
+
label: 'Test Website',
|
647
|
+
childCount: 21,
|
648
|
+
},
|
649
|
+
{
|
650
|
+
id: {
|
651
|
+
id: '2',
|
652
|
+
source: '1',
|
653
|
+
},
|
654
|
+
type: 'site',
|
655
|
+
selected: false,
|
656
|
+
label: 'Second Website',
|
657
|
+
childCount: 21,
|
658
|
+
},
|
659
|
+
],
|
660
|
+
},
|
661
|
+
]);
|
662
|
+
});
|
663
|
+
|
664
|
+
const { getByLabelText, getAllByText, getByText, getByRole } = render(
|
665
|
+
<ResourcePickerContainer
|
666
|
+
{...baseProps}
|
667
|
+
onRequestSources={onRequestSources}
|
668
|
+
onRequestChildren={onRequestChildren}
|
669
|
+
/>,
|
670
|
+
);
|
671
|
+
await waitFor(() => {
|
672
|
+
expect(getAllByText('Test system')[0]).toBeInTheDocument();
|
673
|
+
});
|
674
|
+
|
675
|
+
const user = userEvent.setup();
|
676
|
+
user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
|
677
|
+
|
678
|
+
// Breadcrumb is showing
|
679
|
+
await waitFor(() => {
|
680
|
+
expect(getByLabelText('Resource breadcrumb')).toBeInTheDocument();
|
681
|
+
});
|
682
|
+
|
683
|
+
user.click(screen.getByRole('button', { name: 'Source quick select' }));
|
684
|
+
|
685
|
+
await waitFor(() => {
|
686
|
+
expect(getByRole('button', { name: 'site Second Website' })).toBeInTheDocument();
|
687
|
+
});
|
688
|
+
|
689
|
+
user.click(getByRole('button', { name: 'site Second Website' }));
|
690
|
+
|
691
|
+
await waitFor(() => {
|
692
|
+
expect(getByText('Second Page')).toBeInTheDocument();
|
693
|
+
});
|
694
|
+
|
695
|
+
// Expect the clicked child was added to breadcrumb
|
696
|
+
expect(mockHierarchy).toEqual([
|
697
|
+
{
|
698
|
+
id: {
|
699
|
+
id: '2',
|
700
|
+
source: '1',
|
701
|
+
},
|
702
|
+
label: 'Second Website',
|
703
|
+
},
|
704
|
+
]);
|
705
|
+
});
|
706
|
+
});
|