@squiz/resource-browser 1.32.1-alpha.14 → 1.32.1-alpha.16

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 (90) hide show
  1. package/jest.config.ts +12 -1
  2. package/lib/Hooks/useCategorisedSources.d.ts +14 -0
  3. package/lib/Hooks/useCategorisedSources.js +38 -0
  4. package/lib/Hooks/useChildResources.d.ts +19 -0
  5. package/lib/Hooks/useChildResources.js +35 -0
  6. package/lib/Hooks/useResourcePath.d.ts +16 -0
  7. package/lib/Hooks/useResourcePath.js +64 -0
  8. package/lib/Hooks/useSources.d.ts +16 -0
  9. package/lib/Hooks/useSources.js +29 -0
  10. package/lib/Icons/Icon.d.ts +7 -7
  11. package/lib/Icons/Icon.js +7 -9
  12. package/lib/Icons/MatrixResources/Audio.js +1 -1
  13. package/lib/Icons/MatrixResources/Excel.js +1 -1
  14. package/lib/Icons/MatrixResources/MatrixResourceMap.d.ts +6 -6
  15. package/lib/Icons/MatrixResources/MatrixResourceMap.js +6 -6
  16. package/lib/Icons/MatrixResources/Pdf.js +1 -1
  17. package/lib/Icons/MatrixResources/Powerpoint.js +1 -1
  18. package/lib/Icons/MatrixResources/Video.js +1 -1
  19. package/lib/Icons/MatrixResources/Word.js +1 -1
  20. package/lib/Modal/Modal.js +1 -1
  21. package/lib/PreviewPanel/PreviewModal.js +1 -1
  22. package/lib/PreviewPanel/PreviewPanel.d.ts +4 -6
  23. package/lib/PreviewPanel/PreviewPanel.js +11 -39
  24. package/lib/PreviewPanel/details/MatrixResource.d.ts +4 -9
  25. package/lib/PreviewPanel/details/MatrixResource.js +20 -16
  26. package/lib/ResourceBreadcrumb/ResourceBreadcrumb.d.ts +5 -5
  27. package/lib/ResourceBreadcrumb/ResourceBreadcrumb.js +3 -3
  28. package/lib/ResourceItem/ResourceItem.d.ts +6 -8
  29. package/lib/ResourceItem/ResourceItem.js +3 -3
  30. package/lib/ResourceList/ResourceList.d.ts +5 -4
  31. package/lib/ResourceList/ResourceList.js +3 -3
  32. package/lib/ResourcePickerContainer/ResourcePickerContainer.d.ts +4 -5
  33. package/lib/ResourcePickerContainer/ResourcePickerContainer.js +34 -89
  34. package/lib/SourceDropdown/SourceDropdown.d.ts +5 -5
  35. package/lib/SourceDropdown/SourceDropdown.js +19 -27
  36. package/lib/SourceList/SourceList.d.ts +4 -4
  37. package/lib/SourceList/SourceList.js +7 -5
  38. package/lib/index.css +6 -0
  39. package/lib/index.d.ts +6 -29
  40. package/lib/index.js +2 -3
  41. package/lib/uuid.js +1 -3
  42. package/package.json +3 -2
  43. package/src/Hooks/useCategorisedSources.spec.ts +39 -0
  44. package/src/Hooks/useCategorisedSources.ts +46 -0
  45. package/src/Hooks/useChildResources.spec.ts +49 -0
  46. package/src/Hooks/useChildResources.ts +43 -0
  47. package/src/Hooks/useResourcePath.spec.ts +124 -0
  48. package/src/Hooks/useResourcePath.ts +76 -0
  49. package/src/Hooks/useSources.spec.ts +33 -0
  50. package/src/Hooks/useSources.ts +33 -0
  51. package/src/Icons/Icon.stories.tsx +7 -7
  52. package/src/Icons/Icon.tsx +9 -14
  53. package/src/Icons/MatrixResources/Audio.tsx +1 -1
  54. package/src/Icons/MatrixResources/Excel.tsx +1 -1
  55. package/src/Icons/MatrixResources/MatrixResourceMap.ts +7 -7
  56. package/src/Icons/MatrixResources/Pdf.tsx +1 -1
  57. package/src/Icons/MatrixResources/Powerpoint.tsx +1 -1
  58. package/src/Icons/MatrixResources/Video.tsx +1 -1
  59. package/src/Icons/MatrixResources/Word.tsx +1 -1
  60. package/src/Modal/Modal.tsx +1 -1
  61. package/src/PreviewPanel/PreviewModal.tsx +1 -1
  62. package/src/PreviewPanel/PreviewPanel.spec.tsx +20 -62
  63. package/src/PreviewPanel/PreviewPanel.stories.tsx +16 -24
  64. package/src/PreviewPanel/PreviewPanel.tsx +15 -51
  65. package/src/PreviewPanel/details/MatrixResource.tsx +23 -19
  66. package/src/ResourceBreadcrumb/ResourceBreadcrumb.spec.tsx +13 -23
  67. package/src/ResourceBreadcrumb/ResourceBreadcrumb.stories.tsx +1 -1
  68. package/src/ResourceBreadcrumb/ResourceBreadcrumb.tsx +8 -9
  69. package/src/ResourceBreadcrumb/sample-hierarchy.json +15 -25
  70. package/src/ResourceItem/ResourceItem.tsx +10 -12
  71. package/src/ResourceList/ResourceList.spec.tsx +8 -53
  72. package/src/ResourceList/ResourceList.stories.tsx +2 -2
  73. package/src/ResourceList/ResourceList.tsx +12 -10
  74. package/src/ResourceList/sample-resources.json +551 -49
  75. package/src/ResourcePickerContainer/ResourcePickerContainer.spec.tsx +196 -315
  76. package/src/ResourcePickerContainer/ResourcePickerContainer.stories.tsx +7 -29
  77. package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +63 -127
  78. package/src/SourceDropdown/SourceDropdown.spec.tsx +63 -60
  79. package/src/SourceDropdown/SourceDropdown.stories.tsx +4 -7
  80. package/src/SourceDropdown/SourceDropdown.tsx +34 -41
  81. package/src/SourceList/SourceList.spec.tsx +38 -32
  82. package/src/SourceList/SourceList.tsx +17 -19
  83. package/src/SourceList/sample-sources.json +186 -77
  84. package/src/__mocks__/MockModels.ts +30 -0
  85. package/src/__mocks__/StorybookHelpers.ts +46 -0
  86. package/src/index.stories.tsx +13 -38
  87. package/src/index.tsx +5 -29
  88. package/src/types.d.ts +71 -0
  89. package/src/uuid.ts +2 -4
  90. package/src/SourceDropdown/sample-sources.json +0 -110
@@ -2,11 +2,11 @@
2
2
  import React from 'react';
3
3
  import { screen, render, waitFor, within } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
-
5
+ import { mockResource, mockSource } from '../__mocks__/MockModels';
6
+ import { Resource, Source, Hierarchy } from '../types';
6
7
  import { Context as ResponsiveContext } from 'react-responsive';
7
8
  import { OverlayTriggerState } from 'react-stately';
8
9
 
9
- import type { Hierarchy } from '../index';
10
10
  import ResourcePickerContainer from './ResourcePickerContainer';
11
11
 
12
12
  import SourceList, { SourceListProps } from '../SourceList/SourceList'; // Import Functional Component
@@ -37,51 +37,39 @@ const baseProps = {
37
37
  title: 'Testing',
38
38
  titleAriaProps: {},
39
39
  allowedTypes: undefined,
40
- onClose: () => {},
40
+ onClose: jest.fn(),
41
41
  onRequestSources: () => {
42
42
  return Promise.resolve([
43
- {
43
+ mockSource({
44
44
  id: '1',
45
45
  name: 'Test system',
46
46
  nodes: [
47
47
  {
48
- id: {
49
- id: '1',
50
- source: '1',
48
+ id: '1',
49
+ type: {
50
+ code: 'site',
51
+ name: 'Site',
51
52
  },
52
- type: 'site',
53
- selected: false,
54
- label: 'Test Website',
53
+ name: 'Test Website',
55
54
  childCount: 21,
56
55
  },
57
56
  ],
58
- },
57
+ }),
59
58
  ]);
60
59
  },
61
60
  onRequestChildren: () => {
62
61
  return Promise.resolve([
63
- {
64
- id: {
65
- id: '1',
66
- source: '1',
62
+ mockResource({
63
+ id: '123',
64
+ type: {
65
+ code: 'page',
66
+ name: 'Mocked Page',
67
67
  },
68
- type: 'page',
69
- selected: false,
70
- label: 'Test Page',
68
+ name: 'Test Page',
71
69
  childCount: 0,
72
- },
70
+ }),
73
71
  ]);
74
72
  },
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
73
  onChange: () => {},
86
74
  };
87
75
 
@@ -100,52 +88,47 @@ describe('ResourcePickerContainer', () => {
100
88
  });
101
89
 
102
90
  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,
91
+ const onRequestSources = jest.fn().mockResolvedValue([
92
+ mockSource({
93
+ id: '1',
94
+ name: 'Test system 1',
95
+ nodes: [
96
+ {
97
+ id: '1',
98
+ type: {
99
+ code: 'site',
100
+ name: 'Site',
118
101
  },
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,
102
+ name: 'Test Website 1',
103
+ childCount: 21,
104
+ },
105
+ ],
106
+ }),
107
+ mockSource({
108
+ id: '2',
109
+ name: 'Test system 2',
110
+ nodes: [
111
+ {
112
+ id: '1',
113
+ type: {
114
+ code: 'site',
115
+ name: 'Site',
134
116
  },
135
- {
136
- id: {
137
- id: '2',
138
- source: '2',
139
- },
140
- type: 'site',
141
- selected: false,
142
- label: 'Test Website 3',
143
- childCount: 21,
117
+ name: 'Test Website 2',
118
+ childCount: 21,
119
+ },
120
+ {
121
+ id: '2',
122
+ type: {
123
+ code: 'site',
124
+ name: 'Site',
144
125
  },
145
- ],
146
- },
147
- ]);
148
- });
126
+ name: 'Test Website 3',
127
+ childCount: 21,
128
+ },
129
+ ],
130
+ }),
131
+ ]);
149
132
 
150
133
  const { getAllByText } = render(<ResourcePickerContainer {...baseProps} onRequestSources={onRequestSources} />);
151
134
  await waitFor(() => {
@@ -154,12 +137,12 @@ describe('ResourcePickerContainer', () => {
154
137
 
155
138
  await waitFor(() => {
156
139
  const sourceList = screen.getByLabelText('Source list');
157
- expect(within(sourceList).getByText('Test system 1')).toBeTruthy();
158
- expect(within(sourceList).getByText('Test Website 1')).toBeTruthy();
140
+ expect(within(sourceList).getByText('Test system 1')).toBeInTheDocument();
141
+ expect(within(sourceList).getByText('Test Website 1')).toBeInTheDocument();
159
142
 
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();
143
+ expect(within(sourceList).getByText('Test system 2')).toBeInTheDocument();
144
+ expect(within(sourceList).getByText('Test Website 2')).toBeInTheDocument();
145
+ expect(within(sourceList).getByText('Test Website 3')).toBeInTheDocument();
163
146
  });
164
147
  });
165
148
 
@@ -184,40 +167,13 @@ describe('ResourcePickerContainer', () => {
184
167
  });
185
168
 
186
169
  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
- },
170
+ const onRequestChildren = jest
171
+ .fn()
172
+ .mockResolvedValue([
173
+ mockResource({ id: '1', name: 'Test Page 1' }),
174
+ mockResource({ id: '2', name: 'Test Page 2' }),
175
+ mockResource({ id: '3', name: 'Test Page 3' }),
219
176
  ]);
220
- });
221
177
 
222
178
  // Component has finished initial render
223
179
  const { getAllByText } = render(<ResourcePickerContainer {...baseProps} onRequestChildren={onRequestChildren} />);
@@ -230,85 +186,75 @@ describe('ResourcePickerContainer', () => {
230
186
  user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
231
187
 
232
188
  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();
189
+ expect(screen.getByText('Test Page 1')).toBeInTheDocument();
190
+ expect(screen.getByText('Test Page 2')).toBeInTheDocument();
191
+ expect(screen.getByText('Test Page 3')).toBeInTheDocument();
236
192
  });
237
193
  });
238
194
 
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
- });
195
+ it.each([
196
+ ['mobile', 360, 1],
197
+ ['desktop', 1920, 0],
198
+ ])(
199
+ 'Selecting a node on %s shows its properties in the details panel',
200
+ async (description: string, width: number, expectedPreviewPanelCloseButtons: number) => {
201
+ render(
202
+ <ResponsiveContext.Provider value={{ width }}>
203
+ <ResourcePickerContainer {...baseProps} />
204
+ </ResponsiveContext.Provider>,
205
+ );
206
+ await waitFor(() => {
207
+ expect(screen.getByRole('button', { name: 'Drill down to Test Website children' })).toBeInTheDocument();
208
+ });
244
209
 
245
- // Is on base page
246
- expect(screen.getByLabelText('Source list')).toBeTruthy();
210
+ // Is on base page
211
+ expect(screen.getByLabelText('Source list')).toBeInTheDocument();
247
212
 
248
- // Click the drill down counter
249
- const user = userEvent.setup();
250
- user.click(screen.getByRole('button', { name: 'site Test Website' }));
213
+ // Drill into the source
214
+ const user = userEvent.setup();
215
+ user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
216
+ await waitFor(() => expect(screen.getByRole('button', { name: 'page Test Page' })).toBeInTheDocument());
251
217
 
252
- await waitFor(() => {
253
- expect(getByText('Products')).toBeInTheDocument();
254
- });
218
+ // Select the resource
219
+ user.click(screen.getByRole('button', { name: 'page Test Page' }));
255
220
 
256
- await waitFor(() => {
257
- expect(screen.getByText('Products')).toBeTruthy();
258
- expect(screen.getByText('page')).toBeTruthy();
259
- expect(screen.getByText('#12345')).toBeTruthy();
260
- });
261
- });
221
+ // Asset that the preview panel containing the asset type/ID/etc. is visible
222
+ await waitFor(() => expect(screen.getByText('Asset ID')).toBeInTheDocument());
223
+ expect(screen.getByText('Mocked Page')).toBeInTheDocument();
224
+ expect(screen.getByText('#123')).toBeInTheDocument();
225
+ expect(screen.queryAllByRole('button', { name: 'Close details' })).toHaveLength(expectedPreviewPanelCloseButtons);
226
+ },
227
+ );
262
228
 
263
- it('Mobile: Selecting a node shows its properties in the details panel', async () => {
264
- const { getByText, getAllByText } = render(
229
+ it('Closing the details panel deselects the node', async () => {
230
+ render(
265
231
  <ResponsiveContext.Provider value={{ width: 360 }}>
266
232
  <ResourcePickerContainer {...baseProps} />
267
233
  </ResponsiveContext.Provider>,
268
234
  );
269
235
  await waitFor(() => {
270
- expect(getAllByText('Test system')[0]).toBeInTheDocument();
236
+ expect(screen.getByRole('button', { name: 'Drill down to Test Website children' })).toBeInTheDocument();
271
237
  });
272
238
 
273
- // Click the drill down counter
239
+ // Drill into the source
274
240
  const user = userEvent.setup();
275
- user.click(screen.getByRole('button', { name: 'site Test Website' }));
241
+ user.click(screen.getByRole('button', { name: 'Drill down to Test Website children' }));
242
+ await waitFor(() => expect(screen.getByRole('button', { name: 'page Test Page' })).toBeInTheDocument());
276
243
 
277
- await waitFor(() => {
278
- expect(getByText('Products')).toBeInTheDocument();
279
- });
244
+ // Select the resource
245
+ user.click(screen.getByRole('button', { name: 'page Test Page' }));
280
246
 
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
- });
247
+ // Wait for the preview panel to open
248
+ await waitFor(() => expect(screen.getByText('Mocked Page')).toBeInTheDocument());
249
+ await waitFor(() => expect(screen.getByText('#123')).toBeInTheDocument());
304
250
 
251
+ // Close the preview panel
305
252
  user.click(screen.getByRole('button', { name: 'Close details' }));
306
253
 
307
254
  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();
255
+ // Resource should be unselected and preview modal should disappear
256
+ expect(screen.getByText('Mocked Page')).toBeInTheDocument();
257
+ expect(screen.getByText('#123')).toBeInTheDocument();
312
258
  });
313
259
  });
314
260
 
@@ -392,10 +338,10 @@ describe('ResourcePickerContainer', () => {
392
338
  });
393
339
 
394
340
  it('Breadcrumb hierarchy is added to on drill down', async () => {
395
- let mockHierarchy: Array<Hierarchy> = [];
341
+ let mockHierarchy: Hierarchy<Source | Resource> = [];
396
342
 
397
- MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
398
- mockHierarchy = args.hierarchy;
343
+ MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps<unknown>) => {
344
+ mockHierarchy = args.hierarchy as Hierarchy<Source | Resource>;
399
345
  return ActualResourceBreadcrumb(args);
400
346
  });
401
347
 
@@ -413,47 +359,39 @@ describe('ResourcePickerContainer', () => {
413
359
  });
414
360
 
415
361
  // Expect the clicked child was added to breadcrumb
416
- expect(mockHierarchy).toEqual([{ id: { id: '1', source: '1' }, label: 'Test Website' }]);
362
+ expect(mockHierarchy).toEqual([
363
+ {
364
+ key: 'source:1-resource:1',
365
+ label: 'Test Website',
366
+ node: expect.any(Object),
367
+ },
368
+ ]);
417
369
  });
418
370
 
419
371
  it('Multiple hierarchy is tracked on on drill down', async () => {
420
- let mockHierarchy: Array<Hierarchy> = [];
372
+ let mockHierarchy: Hierarchy<Source | Resource> = [];
421
373
 
422
- MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
423
- mockHierarchy = args.hierarchy;
374
+ MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps<unknown>) => {
375
+ mockHierarchy = args.hierarchy as Hierarchy<Source | Resource>;
424
376
  return ActualResourceBreadcrumb(args);
425
377
  });
426
378
 
427
379
  const onRequestChildren = jest
428
380
  .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
- });
381
+ .mockResolvedValueOnce([
382
+ mockResource({
383
+ id: '11',
384
+ name: 'Test Page',
385
+ childCount: 4,
386
+ }),
387
+ ])
388
+ .mockResolvedValueOnce([
389
+ mockResource({
390
+ id: '111',
391
+ name: 'Second Page',
392
+ childCount: 0,
393
+ }),
394
+ ]);
457
395
 
458
396
  const { getByLabelText, getByText, getAllByText } = render(
459
397
  <ResourcePickerContainer {...baseProps} onRequestChildren={onRequestChildren} />,
@@ -480,76 +418,51 @@ describe('ResourcePickerContainer', () => {
480
418
  // Expect the clicked child was added to breadcrumb
481
419
  expect(mockHierarchy).toEqual([
482
420
  {
483
- id: {
484
- id: '1',
485
- source: '1',
486
- },
421
+ key: 'source:1-resource:1',
487
422
  label: 'Test Website',
423
+ node: expect.any(Object),
488
424
  },
489
425
  {
490
- id: {
491
- id: '11',
492
- source: '1',
493
- },
426
+ key: '11',
494
427
  label: 'Test Page',
428
+ node: expect.any(Object),
495
429
  },
496
430
  ]);
497
431
  });
498
432
 
499
433
  it('Can track multiple hierarchy jumping back', async () => {
500
- let mockHierarchy: Array<Hierarchy> = [];
434
+ let mockHierarchy: Hierarchy<Source | Resource> = [];
501
435
 
502
- MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
503
- mockHierarchy = args.hierarchy;
436
+ MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps<unknown>) => {
437
+ mockHierarchy = args.hierarchy as Hierarchy<Source | Resource>;
504
438
  return ActualResourceBreadcrumb(args);
505
439
  });
506
440
 
507
441
  const onRequestChildren = jest
508
442
  .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
- });
443
+ .mockResolvedValueOnce([
444
+ mockResource({
445
+ id: '11',
446
+ name: 'First Level',
447
+ childCount: 4,
448
+ }),
449
+ ])
450
+ .mockResolvedValueOnce([
451
+ mockResource({
452
+ id: '111',
453
+ name: 'Second Level',
454
+ childCount: 0,
455
+ }),
456
+ ])
457
+ .mockResolvedValueOnce([
458
+ mockResource({
459
+ id: '11',
460
+ name: 'First Level',
461
+ childCount: 4,
462
+ }),
463
+ ]);
551
464
 
552
- const { getByLabelText, getByText, getAllByText, queryByText } = render(
465
+ const { getByText, getAllByText, queryByText } = render(
553
466
  <ResourcePickerContainer {...baseProps} onRequestChildren={onRequestChildren} />,
554
467
  );
555
468
  await waitFor(() => {
@@ -561,14 +474,14 @@ describe('ResourcePickerContainer', () => {
561
474
 
562
475
  // Breadcrumb is showing
563
476
  await waitFor(() => {
564
- expect(getByLabelText('Resource breadcrumb')).toBeInTheDocument();
477
+ expect(getByText('First Level')).toBeInTheDocument();
565
478
  });
566
479
 
567
480
  // Drill down again
568
- user.click(screen.getByRole('button', { name: 'Drill down to Test Page children' }));
481
+ user.click(screen.getByRole('button', { name: 'Drill down to First Level children' }));
569
482
 
570
483
  await waitFor(() => {
571
- expect(getByText('Second Page')).toBeInTheDocument();
484
+ expect(getByText('Second Level')).toBeInTheDocument();
572
485
  });
573
486
 
574
487
  // Click on previous breadcrumb item
@@ -576,88 +489,58 @@ describe('ResourcePickerContainer', () => {
576
489
  user.click(within(breadcrumb).getByRole('button', { name: 'Test Website' }));
577
490
 
578
491
  await waitFor(() => {
579
- expect(queryByText('Second Page')).not.toBeInTheDocument();
492
+ expect(queryByText('Second Level')).not.toBeInTheDocument();
580
493
  });
581
494
 
582
495
  // Expect the clicked child was added to breadcrumb
583
496
  expect(mockHierarchy).toEqual([
584
497
  {
585
- id: {
586
- id: '1',
587
- source: '1',
588
- },
498
+ key: 'source:1-resource:1',
589
499
  label: 'Test Website',
500
+ node: expect.any(Object),
590
501
  },
591
502
  ]);
592
503
  });
593
504
 
594
505
  it('Multiple hierarchy can handle reset to new source', async () => {
595
- let mockHierarchy: Array<Hierarchy> = [];
506
+ let mockHierarchy: Hierarchy<Source | Resource> = [];
596
507
 
597
- MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps) => {
598
- mockHierarchy = args.hierarchy;
508
+ MockResourceBreadcrumb.mockImplementation((args: ResourceBreadcrumbProps<unknown>) => {
509
+ mockHierarchy = args.hierarchy as Hierarchy<Source | Resource>;
599
510
  return ActualResourceBreadcrumb(args);
600
511
  });
601
512
 
602
513
  const onRequestChildren = jest
603
514
  .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
- });
515
+ .mockResolvedValueOnce([mockResource({ name: 'Test Page' })])
516
+ .mockResolvedValueOnce([mockResource({ name: 'Second Page' })]);
632
517
 
633
518
  const onRequestSources = jest.fn().mockImplementation(() => {
634
519
  return Promise.resolve([
635
- {
520
+ mockSource({
636
521
  id: '1',
637
522
  name: 'Test system',
638
523
  nodes: [
639
524
  {
640
- id: {
641
- id: '1',
642
- source: '1',
525
+ id: '1',
526
+ type: {
527
+ code: 'site',
528
+ name: 'Site',
643
529
  },
644
- type: 'site',
645
- selected: false,
646
- label: 'Test Website',
530
+ name: 'Test Website',
647
531
  childCount: 21,
648
532
  },
649
533
  {
650
- id: {
651
- id: '2',
652
- source: '1',
534
+ id: '2',
535
+ type: {
536
+ code: 'site',
537
+ name: 'Site',
653
538
  },
654
- type: 'site',
655
- selected: false,
656
- label: 'Second Website',
539
+ name: 'Second Website',
657
540
  childCount: 21,
658
541
  },
659
542
  ],
660
- },
543
+ }),
661
544
  ]);
662
545
  });
663
546
 
@@ -683,10 +566,10 @@ describe('ResourcePickerContainer', () => {
683
566
  user.click(screen.getByRole('button', { name: 'Source quick select' }));
684
567
 
685
568
  await waitFor(() => {
686
- expect(getByRole('button', { name: 'site Second Website' })).toBeInTheDocument();
569
+ expect(getByRole('button', { name: 'Site Second Website' })).toBeInTheDocument();
687
570
  });
688
571
 
689
- user.click(getByRole('button', { name: 'site Second Website' }));
572
+ user.click(getByRole('button', { name: 'Site Second Website' }));
690
573
 
691
574
  await waitFor(() => {
692
575
  expect(getByText('Second Page')).toBeInTheDocument();
@@ -695,11 +578,9 @@ describe('ResourcePickerContainer', () => {
695
578
  // Expect the clicked child was added to breadcrumb
696
579
  expect(mockHierarchy).toEqual([
697
580
  {
698
- id: {
699
- id: '2',
700
- source: '1',
701
- },
581
+ key: 'source:1-resource:2',
702
582
  label: 'Second Website',
583
+ node: expect.any(Object),
703
584
  },
704
585
  ]);
705
586
  });