@exdst-sitecore-content-sdk/astro 0.0.24 → 0.0.25

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 (70) hide show
  1. package/package.json +7 -12
  2. package/src/context.ts +1 -1
  3. package/src/client/sitecore-astro-client.test.ts +0 -267
  4. package/src/components/AstroImage.astro.test.ts +0 -541
  5. package/src/components/Date.astro.test.ts +0 -197
  6. package/src/components/EditingScripts.astro.test.ts +0 -267
  7. package/src/components/ErrorBoundary.astro.test.ts +0 -252
  8. package/src/components/ErrorComponent.astro.test.ts +0 -31
  9. package/src/components/FieldMetadata.astro.test.ts +0 -40
  10. package/src/components/File.astro.test.ts +0 -68
  11. package/src/components/HiddenRendering.astro.test.ts +0 -36
  12. package/src/components/Image.astro.test.ts +0 -438
  13. package/src/components/Link.astro.test.ts +0 -261
  14. package/src/components/MissingComponent.astro.test.ts +0 -21
  15. package/src/components/Placeholder/Placeholder.astro.test.ts +0 -1088
  16. package/src/components/Placeholder/PlaceholderMetadata.astro.test.ts +0 -228
  17. package/src/components/Placeholder/PlaceholderUtils.astro.test.ts +0 -149
  18. package/src/components/Placeholder/placeholder-utils.test.ts +0 -309
  19. package/src/components/RichText.astro.test.ts +0 -205
  20. package/src/components/Text.astro.test.ts +0 -273
  21. package/src/config/define-config.test.ts +0 -526
  22. package/src/config-cli/define-cli-config.test.ts +0 -67
  23. package/src/editing/editing-config-middleware.test.ts +0 -164
  24. package/src/editing/editing-render-middleware.test.ts +0 -1143
  25. package/src/editing/render-middleware.test.ts +0 -57
  26. package/src/editing/utils.test.ts +0 -1212
  27. package/src/enhancers/WithEmptyFieldEditingComponent.astro.test.ts +0 -380
  28. package/src/enhancers/WithFieldMetadata.astro.test.ts +0 -113
  29. package/src/middleware/middleware.test.ts +0 -520
  30. package/src/middleware/multisite-middleware.test.ts +0 -736
  31. package/src/middleware/robots-middleware.test.ts +0 -129
  32. package/src/middleware/sitemap-middleware.test.ts +0 -184
  33. package/src/tests/astro-helpers.ts +0 -61
  34. package/src/tests/helpers.ts +0 -46
  35. package/src/tests/personalizeData.ts +0 -63
  36. package/src/tests/test-components/CustomErrorComponent.astro +0 -3
  37. package/src/tests/test-components/CustomHiddenRendering.astro +0 -10
  38. package/src/tests/test-components/CustomMissingComponent.astro +0 -9
  39. package/src/tests/test-components/DownloadCallout.astro +0 -12
  40. package/src/tests/test-components/EmptyFieldEditingComponent.astro +0 -5
  41. package/src/tests/test-components/ErrorBoundaryWithError.astro +0 -10
  42. package/src/tests/test-components/Home.astro +0 -12
  43. package/src/tests/test-components/SxaRichText.astro +0 -23
  44. package/src/tests/test-components/SxaRichTextDefault.astro +0 -7
  45. package/src/tests/test-components/SxaRichTextWithTitle.astro +0 -8
  46. package/src/tests/test-components/TestComponent.astro +0 -9
  47. package/src/tests/test-components/TestComponentWithError.astro +0 -4
  48. package/src/tests/test-components/TestComponentWithField.astro +0 -17
  49. package/src/tests/test-components/TestHeader.astro +0 -8
  50. package/src/tests/test-components/TestLogo.astro +0 -5
  51. package/src/tests/test-components/TestParentWrapperComponent.astro +0 -5
  52. package/src/tests/test-components/TestWrapperComponent.astro +0 -5
  53. package/src/tests/test-components/generate-map/Button.astro +0 -4
  54. package/src/tests/test-components/generate-map/Link.astro +0 -4
  55. package/src/tests/test-components/map-components/Bar.astro +0 -0
  56. package/src/tests/test-components/map-components/Baz.astro +0 -0
  57. package/src/tests/test-components/map-components/Foo.astro +0 -0
  58. package/src/tests/test-components/map-components/Hero.variant.astro +0 -0
  59. package/src/tests/test-components/map-components/NotComponent.bsx +0 -0
  60. package/src/tests/test-components/map-components/Qux.astro +0 -0
  61. package/src/tests/test-components/map-components/folded/Folded.astro +0 -0
  62. package/src/tests/test-components/map-components/folded/random-file-2.docx +0 -0
  63. package/src/tests/test-components/map-components/random-file.txt +0 -0
  64. package/src/tests/test-data/metadata-data.ts +0 -86
  65. package/src/tests/test-data/normal-mode-data.ts +0 -466
  66. package/src/tests/vitest.setup.ts +0 -4
  67. package/src/tools/generate-map.test.ts +0 -201
  68. package/src/tools/templating/components.test.ts +0 -318
  69. package/src/tools/templating/default-component.test.ts +0 -31
  70. package/src/utils/utils.test.ts +0 -111
@@ -1,1088 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- /* eslint-disable no-unused-expressions */
3
- /* eslint-disable @typescript-eslint/no-explicit-any */
4
- import { describe, test, expect, vi, beforeEach, afterAll } from 'vitest';
5
- import { mockSitecoreContext, renderAstroComponent } from '../../tests/astro-helpers';
6
-
7
- import {
8
- ComponentRendering,
9
- LayoutServicePageState,
10
- RouteData,
11
- } from '@sitecore-content-sdk/content/layout';
12
- import {
13
- // byocWrapperData,
14
- // feaasWrapperData,
15
- convertedDevData as normalModeDevData,
16
- convertedLayoutServiceData as normalModeLsData,
17
- sxaRenderingColumnSplitterVariant,
18
- sxaRenderingVariantDataWithCommonContainerName as sxaRenderingCommonContainerName,
19
- sxaRenderingVariantData,
20
- sxaRenderingVariantDoubleDigitDynamicPlaceholder as sxaRenderingDoubleDigitContainerName,
21
- sxaRenderingVariantDataWithoutCommonContainerName as sxaRenderingWithoutContainerName,
22
- } from '../../tests/test-data/normal-mode-data';
23
- import * as metadataData from '../../tests/test-data/metadata-data';
24
- import SxaRichText from '../../tests/test-components/SxaRichText.astro';
25
- // import * as BYOCComponent from './BYOCComponent';
26
- // import * as BYOCWrapper from './BYOCWrapper';
27
- // import * as FEAASComponent from './FEaaSComponent';
28
- // import * as FEAASWrapper from './FEaaSWrapper';
29
- import Placeholder from './Placeholder.astro';
30
- import { Page, PageMode } from '@sitecore-content-sdk/content/client';
31
- import { AstroContentSdkComponent } from '../../sharedTypes/component-props';
32
- import Home from '../../tests/test-components/Home.astro';
33
- import DownloadCallout from '../../tests/test-components/DownloadCallout.astro';
34
- import TestWrapperComponent from '../../tests/test-components/TestWrapperComponent.astro';
35
- import TestComponentWithError from '../../tests/test-components/TestComponentWithError.astro';
36
- import CustomErrorComponent from '../../tests/test-components/CustomErrorComponent.astro';
37
- import CustomMissingComponent from '../../tests/test-components/CustomMissingComponent.astro';
38
- import CustomHiddenRendering from '../../tests/test-components/CustomHiddenRendering.astro';
39
- import TestLogo from '../../tests/test-components/TestLogo.astro';
40
- import TestHeader from '../../tests/test-components/TestHeader.astro';
41
- import TestParentWrapperComponent from '../../tests/test-components/TestParentWrapperComponent.astro';
42
-
43
- vi.spyOn(console, 'log').mockImplementation(() => undefined);
44
- vi.spyOn(console, 'warn').mockImplementation(() => undefined);
45
- vi.spyOn(console, 'error').mockImplementation(() => undefined);
46
-
47
- const componentMap = new Map<string, AstroContentSdkComponent>();
48
-
49
- const getPage = (): Page => ({
50
- locale: 'en',
51
- layout: {
52
- sitecore: {
53
- context: {},
54
- route: null,
55
- },
56
- },
57
- mode: {
58
- name: LayoutServicePageState.Normal,
59
- isNormal: true,
60
- isPreview: false,
61
- isEditing: false,
62
- isDesignLibrary: false,
63
- designLibrary: {
64
- isVariantGeneration: false,
65
- },
66
- },
67
- });
68
-
69
- componentMap.set('Home', Home);
70
- componentMap.set('DownloadCallout', DownloadCallout);
71
- componentMap.set('Jumbotron', () => '<div className="jumbotron-mock" />');
72
- // componentMap.set('DynamicComponent', dynamicComponent);
73
-
74
- describe('<Placeholder />', () => {
75
- const testData = [
76
- { label: 'Dev data', data: normalModeDevData },
77
- { label: 'LayoutService data - Editing off', data: normalModeLsData },
78
- ];
79
-
80
- testData.forEach((dataSet) => {
81
- describe(`with ${dataSet.label}`, () => {
82
- test('should render a placeholder with given key', async () => {
83
- const page = getPage();
84
- page.layout = dataSet.data;
85
- mockSitecoreContext(page, componentMap);
86
-
87
- const component = (
88
- dataSet.data.sitecore.route!.placeholders.main as (ComponentRendering | RouteData)[]
89
- ).find((c) => (c as ComponentRendering).componentName);
90
- const phKey = 'page-content';
91
-
92
- const renderedComponent = await renderAstroComponent(Placeholder, {
93
- props: { name: phKey, rendering: component },
94
- });
95
-
96
- expect(renderedComponent.querySelectorAll('.download-callout-mock').length).to.equal(1);
97
- });
98
-
99
- test('should render nested placeholders', async () => {
100
- const page = getPage();
101
- page.layout = dataSet.data;
102
- mockSitecoreContext(page, componentMap);
103
-
104
- const component = dataSet.data.sitecore.route as RouteData;
105
- const phKey = 'main';
106
-
107
- const renderedComponent = await renderAstroComponent(Placeholder, {
108
- props: { name: phKey, rendering: component },
109
- });
110
-
111
- expect(renderedComponent.querySelectorAll('.download-callout-mock').length).to.equal(1);
112
- });
113
-
114
- test('should render components based on the renderEach HTML wrapper', async () => {
115
- const page = getPage();
116
- page.layout = dataSet.data;
117
- mockSitecoreContext(page, componentMap);
118
-
119
- const component = dataSet.data.sitecore.route as RouteData;
120
- const phKey = 'main';
121
-
122
- const renderedComponent = await renderAstroComponent(Placeholder, {
123
- props: {
124
- name: phKey,
125
- rendering: component,
126
- renderEach: '<div class="wrapper">${component}</div>',
127
- },
128
- });
129
-
130
- expect(renderedComponent.querySelectorAll('.wrapper').length).to.equal(1);
131
- });
132
-
133
- test('should render components based on the renderEach Astro wrapper', async () => {
134
- const page = getPage();
135
- page.layout = dataSet.data;
136
- mockSitecoreContext(page, componentMap);
137
-
138
- const component = dataSet.data.sitecore.route as RouteData;
139
- const phKey = 'main';
140
-
141
- const renderedComponent = await renderAstroComponent(Placeholder, {
142
- props: {
143
- name: phKey,
144
- rendering: component,
145
- renderEach: TestWrapperComponent,
146
- },
147
- });
148
-
149
- expect(renderedComponent.querySelectorAll('.wrapper').length).to.equal(1);
150
- });
151
-
152
- test('should use renderEach for each child in the placeholder when page editing is enabled', async () => {
153
- const page = getPage();
154
-
155
- const component = dataSet.data.sitecore.route as RouteData;
156
-
157
- const myComponent = {
158
- ...component,
159
- placeholders: {
160
- ...component.placeholders,
161
- main: [
162
- {
163
- componentName: 'Home',
164
- },
165
- {
166
- componentName: 'DownloadCallout',
167
- },
168
- ],
169
- },
170
- };
171
-
172
- page.mode.isEditing = true;
173
- mockSitecoreContext(page, componentMap);
174
-
175
- const phKey = 'main';
176
-
177
- const renderedComponent = await renderAstroComponent(Placeholder, {
178
- props: {
179
- name: phKey,
180
- rendering: myComponent,
181
- render: TestParentWrapperComponent,
182
- renderEach: TestWrapperComponent,
183
- },
184
- });
185
-
186
- expect(renderedComponent.querySelectorAll('.parent-wrapper').length).to.equal(1);
187
- expect(renderedComponent.querySelectorAll('.wrapper').length).to.equal(2);
188
- });
189
-
190
- test('should render components based on the render HTML wrapper', async () => {
191
- const page = getPage();
192
- page.layout = dataSet.data;
193
- mockSitecoreContext(page, componentMap);
194
-
195
- const component = dataSet.data.sitecore.route as RouteData;
196
- const phKey = 'main';
197
-
198
- const renderedComponent = await renderAstroComponent(Placeholder, {
199
- props: {
200
- name: phKey,
201
- rendering: component,
202
- render: '<div class="wrapper">${component}</div>',
203
- },
204
- });
205
-
206
- expect(renderedComponent.querySelectorAll('.wrapper').length).to.equal(1);
207
- });
208
-
209
- test('should render components based on the render Astro wrapper', async () => {
210
- const page = getPage();
211
- page.layout = dataSet.data;
212
- mockSitecoreContext(page, componentMap);
213
-
214
- const component = dataSet.data.sitecore.route as RouteData;
215
- const phKey = 'main';
216
-
217
- const renderedComponent = await renderAstroComponent(Placeholder, {
218
- props: {
219
- name: phKey,
220
- rendering: component,
221
- render: TestWrapperComponent,
222
- },
223
- });
224
-
225
- expect(renderedComponent.querySelectorAll('.wrapper').length).to.equal(1);
226
- });
227
-
228
- test('should render empty placeholder', async () => {
229
- const page = getPage();
230
- page.layout = dataSet.data;
231
- mockSitecoreContext(page, componentMap);
232
-
233
- const component = dataSet.data.sitecore.route as RouteData;
234
- const phKey = 'mainEmpty';
235
-
236
- const renderedComponent = await renderAstroComponent(Placeholder, {
237
- props: { name: phKey, rendering: component, render: null },
238
- });
239
-
240
- expect(renderedComponent.innerHTML).to.be.equal('');
241
- });
242
-
243
- test('should render output based on the renderEmpty HTML wrapper in case of no renderings', async () => {
244
- const page = getPage();
245
- page.layout = dataSet.data;
246
- mockSitecoreContext(page, componentMap);
247
-
248
- const component = dataSet.data.sitecore.route as RouteData;
249
-
250
- const renderings = component.placeholders.main.filter(
251
- (c) => !(c as ComponentRendering).componentName
252
- );
253
-
254
- const myComponent = {
255
- ...component,
256
- placeholders: {
257
- ...component.placeholders,
258
- main: [...renderings],
259
- },
260
- };
261
-
262
- const phKey = 'main';
263
-
264
- const renderedComponent = await renderAstroComponent(Placeholder, {
265
- props: {
266
- name: phKey,
267
- rendering: myComponent,
268
- renderEmpty: '<div class="wrapper">${component}</div>',
269
- },
270
- });
271
-
272
- expect(renderedComponent.querySelectorAll('.wrapper').length).to.equal(1);
273
- expect(renderedComponent.querySelectorAll('.download-callout-mock').length).to.equal(0);
274
- expect(renderedComponent.querySelectorAll('.home-mock').length).to.equal(0);
275
- expect(renderedComponent.querySelectorAll('.jumbotron-mock').length).to.equal(0);
276
- });
277
- });
278
-
279
- test('should render output based on the renderEmpty Astro wrapper in case of no renderings', async () => {
280
- const page = getPage();
281
- page.layout = dataSet.data;
282
- mockSitecoreContext(page, componentMap);
283
-
284
- const component = dataSet.data.sitecore.route as RouteData;
285
-
286
- const renderings = component.placeholders.main.filter(
287
- (c) => !(c as ComponentRendering).componentName
288
- );
289
-
290
- const myComponent = {
291
- ...component,
292
- placeholders: {
293
- ...component.placeholders,
294
- main: [...renderings],
295
- },
296
- };
297
-
298
- const phKey = 'main';
299
-
300
- const renderedComponent = await renderAstroComponent(Placeholder, {
301
- props: {
302
- name: phKey,
303
- rendering: myComponent,
304
- renderEmpty: TestWrapperComponent,
305
- },
306
- });
307
-
308
- expect(renderedComponent.querySelectorAll('.wrapper').length).to.equal(1);
309
- expect(renderedComponent.querySelectorAll('.download-callout-mock').length).to.equal(0);
310
- expect(renderedComponent.querySelectorAll('.home-mock').length).to.equal(0);
311
- expect(renderedComponent.querySelectorAll('.jumbotron-mock').length).to.equal(0);
312
- });
313
-
314
- test('should pass properties to nested components', async () => {
315
- const page = getPage();
316
- page.layout = dataSet.data;
317
- mockSitecoreContext(page, componentMap);
318
-
319
- const component = dataSet.data.sitecore.route as any;
320
- const phKey = 'main';
321
- const expectedMessage = (component.placeholders.main as any[]).find((c) => c.componentName)
322
- .fields.message;
323
-
324
- const renderedComponent = await renderAstroComponent(Placeholder, {
325
- props: {
326
- name: phKey,
327
- rendering: component,
328
- },
329
- });
330
-
331
- expect(
332
- renderedComponent
333
- .querySelector('.download-callout-mock')
334
- ?.innerHTML.indexOf(expectedMessage.value) !== -1
335
- ).to.be.true;
336
- });
337
- });
338
-
339
- describe('SXA rendering variants', () => {
340
- const componentMap = new Map();
341
-
342
- componentMap.set('RichText', SxaRichText);
343
-
344
- test('should render', async () => {
345
- const page = getPage();
346
- page.layout = sxaRenderingVariantData;
347
- mockSitecoreContext(page, componentMap);
348
-
349
- const component = sxaRenderingVariantData.sitecore.route as RouteData;
350
- const phKey = 'main';
351
-
352
- const renderedComponent = await renderAstroComponent(Placeholder, {
353
- props: {
354
- name: phKey,
355
- rendering: component,
356
- },
357
- });
358
-
359
- expect(renderedComponent.querySelectorAll('.rendering-variant').length).to.equal(1);
360
- expect(renderedComponent.querySelector('.rendering-variant')?.getAttribute('class')).to.equal(
361
- 'rendering-variant col-9|col-sm-10|col-md-12|col-lg-6|col-xl-7|col-xxl-8 test-css-class-x'
362
- );
363
- expect(renderedComponent.querySelectorAll('.title').length).to.equal(1);
364
- expect(renderedComponent.querySelector('.title')?.textContent).to.equal(
365
- 'Rich Text Rendering Variant'
366
- );
367
- expect(renderedComponent.querySelectorAll('.text').length).to.equal(1);
368
- expect(renderedComponent.querySelector('.text')?.textContent).to.equal('Test RichText');
369
- });
370
-
371
- test('should render with container-{*} type dynamic placeholder', async () => {
372
- const page = getPage();
373
- page.layout = sxaRenderingCommonContainerName;
374
- mockSitecoreContext(page, componentMap);
375
-
376
- const component = sxaRenderingCommonContainerName.sitecore.route as RouteData;
377
- const phKey = 'container-1';
378
-
379
- const renderedComponent = await renderAstroComponent(Placeholder, {
380
- props: {
381
- name: phKey,
382
- rendering: component,
383
- },
384
- });
385
-
386
- expect(renderedComponent.querySelectorAll('.rendering-variant').length).to.equal(1);
387
- expect(renderedComponent.querySelector('.rendering-variant')?.getAttribute('class')).to.equal(
388
- 'rendering-variant col-9|col-sm-10|col-md-12|col-lg-6|col-xl-7|col-xxl-8 test-css-class-x'
389
- );
390
- expect(renderedComponent.querySelectorAll('.title').length).to.equal(1);
391
- expect(renderedComponent.querySelector('.title')?.textContent).to.equal(
392
- 'Rich Text Rendering Variant'
393
- );
394
- });
395
-
396
- test('should not render without container-{*} type dynamic placeholder', async () => {
397
- const page = getPage();
398
- page.layout = sxaRenderingWithoutContainerName;
399
- mockSitecoreContext(page, componentMap);
400
-
401
- const component = sxaRenderingWithoutContainerName.sitecore.route as RouteData;
402
- const phKey = 'richText';
403
-
404
- const renderedComponent = await renderAstroComponent(Placeholder, {
405
- props: {
406
- name: phKey,
407
- rendering: component,
408
- },
409
- });
410
-
411
- expect(renderedComponent.querySelectorAll('.rendering-variant').length).to.equal(0);
412
- expect(renderedComponent.querySelectorAll('.title').length).to.equal(0);
413
- });
414
-
415
- test('should render with dynamic-1-{*} type dynamic placeholder', async () => {
416
- const page = getPage();
417
- page.layout = sxaRenderingDoubleDigitContainerName;
418
- mockSitecoreContext(page, componentMap);
419
-
420
- const component = sxaRenderingDoubleDigitContainerName.sitecore.route as RouteData;
421
- const phKey = 'dynamic-1-{*}';
422
-
423
- const renderedComponent = await renderAstroComponent(Placeholder, {
424
- props: {
425
- name: phKey,
426
- rendering: component,
427
- },
428
- });
429
-
430
- expect(renderedComponent.querySelectorAll('.rendering-variant').length).to.equal(1);
431
- expect(renderedComponent.querySelector('.rendering-variant')?.getAttribute('class')).to.equal(
432
- 'rendering-variant col-9|col-sm-10|col-md-12|col-lg-6|col-xl-7|col-xxl-8 test-css-class-x'
433
- );
434
- expect(renderedComponent.querySelectorAll('.title').length).to.equal(1);
435
- expect(renderedComponent.querySelector('.title')?.textContent).to.equal(
436
- 'Rich Text Rendering Variant'
437
- );
438
- });
439
-
440
- test('should render another rendering variant', async () => {
441
- const page = getPage();
442
- page.layout = sxaRenderingVariantData;
443
- mockSitecoreContext(page, componentMap);
444
-
445
- const component = sxaRenderingVariantData.sitecore.route as RouteData;
446
- const phKey = 'main-second';
447
-
448
- const renderedComponent = await renderAstroComponent(Placeholder, {
449
- props: {
450
- name: phKey,
451
- rendering: component,
452
- },
453
- });
454
-
455
- expect(renderedComponent.querySelectorAll('.rendering-variant').length).to.equal(1);
456
- expect(renderedComponent.querySelector('.rendering-variant')?.getAttribute('class')).to.equal(
457
- 'rendering-variant col-9|col-sm-10|col-md-12|col-lg-6|col-xl-7|col-xxl-8 test-css-class-y'
458
- );
459
- expect(renderedComponent.querySelectorAll('.default').length).to.equal(1);
460
- });
461
-
462
- test('should render column splitter rendering variant', async () => {
463
- const page = getPage();
464
- page.layout = sxaRenderingColumnSplitterVariant;
465
- mockSitecoreContext(page, componentMap);
466
-
467
- const component = sxaRenderingColumnSplitterVariant.sitecore.route as RouteData;
468
- const phKey = 'column-1-{*}';
469
-
470
- const renderedComponent = await renderAstroComponent(Placeholder, {
471
- props: {
472
- name: phKey,
473
- rendering: component,
474
- },
475
- });
476
-
477
- expect(renderedComponent.querySelectorAll('.rendering-variant').length).to.equal(1);
478
- expect(renderedComponent.querySelector('.rendering-variant')?.getAttribute('class')).to.equal(
479
- 'rendering-variant col-9|col-sm-10|col-md-12|col-lg-6|col-xl-7|col-xxl-8 test-css-class-y'
480
- );
481
- expect(renderedComponent.querySelectorAll('.default').length).to.equal(1);
482
- });
483
- });
484
- /*
485
- describe('BYOC fallback', () => {
486
- let byocComponentStub;
487
- let byocWrapperStub;
488
-
489
- const componentMap = new Map();
490
-
491
- it('should render', () => {
492
- const page = getPage();
493
- page.layout = byocWrapperData;
494
- const component = byocWrapperData.sitecore.route as RouteData;
495
- const phKey = 'main';
496
-
497
- byocComponentStub = stub(BYOCComponent, 'BYOCComponent').callsFake(() => (
498
- <p className="byoc-component">Foo</p>
499
- ));
500
-
501
- byocWrapperStub = stub(BYOCWrapper, 'BYOCWrapper').callsFake(() => (
502
- <div className="byoc-wrapper">
503
- <BYOCComponent.BYOCComponent />
504
- </div>
505
- ));
506
-
507
- const renderedComponent = render(
508
- <SitecoreProvider componentMap={componentMap} page={page}>
509
- <Placeholder name={phKey} rendering={component} />
510
- </SitecoreProvider>
511
- );
512
-
513
- expect(renderedComponent.container.querySelectorAll('.byoc-component').length).to.equal(2);
514
- expect(renderedComponent.container.querySelectorAll('.byoc-wrapper').length).to.equal(1);
515
-
516
- byocComponentStub.restore();
517
- byocWrapperStub.restore();
518
- });
519
-
520
- it('should render ErrorBoundary without Suspense for byoc wrapper', () => {
521
- const page = getPage();
522
- page.layout = byocWrapperData;
523
- const component = byocWrapperData.sitecore.route as RouteData;
524
- const phKey = 'main';
525
-
526
- byocComponentStub = stub(BYOCComponent, 'BYOCComponent').callsFake(() => (
527
- <p className="byoc-component">Foo</p>
528
- ));
529
-
530
- byocWrapperStub = stub(BYOCWrapper, 'BYOCWrapper').callsFake(() => (
531
- <div className="byoc-wrapper">
532
- <BYOCComponent.BYOCComponent />
533
- </div>
534
- ));
535
-
536
- const errorBoundarySpy = spy(ErrorBoundary, 'default');
537
-
538
- const renderedComponent = render(
539
- <SitecoreProvider componentMap={componentMap} page={page}>
540
- <Placeholder name={phKey} rendering={component} />
541
- </SitecoreProvider>
542
- );
543
-
544
- expect(errorBoundarySpy.calledWithMatch({ isDynamic: true })).to.be.true;
545
- expect(renderedComponent.container.innerHTML).to.not.contain('Loading component...');
546
-
547
- expect(renderedComponent.container.querySelectorAll('.byoc-wrapper').length).to.equal(1);
548
-
549
- const components = renderedComponent.container.querySelectorAll('.byoc-component');
550
-
551
- expect(components.length).to.equal(2);
552
-
553
- expect(components[0].textContent).to.equal('Foo');
554
- expect(components[1].textContent).to.equal('Foo');
555
-
556
- byocComponentStub.restore();
557
- byocWrapperStub.restore();
558
- });
559
- });
560
-
561
- describe('FEaaS fallback', () => {
562
- let feaasComponentStub;
563
- let feaasWrapperStub;
564
-
565
- const componentMap = new Map();
566
-
567
- it('should render', () => {
568
- const page = getPage();
569
- page.layout = feaasWrapperData;
570
- const component = feaasWrapperData.sitecore.route as RouteData;
571
- const phKey = 'main';
572
-
573
- feaasComponentStub = stub(FEAASComponent, 'FEaaSComponent').callsFake(() => (
574
- <p className="feaas-component">Foo</p>
575
- ));
576
-
577
- feaasWrapperStub = stub(FEAASWrapper, 'FEaaSWrapper').callsFake(() => (
578
- <div className="feaas-wrapper">
579
- <FEAASComponent.FEaaSComponent />
580
- </div>
581
- ));
582
-
583
- const renderedComponent = render(
584
- <SitecoreProvider componentMap={componentMap} page={page}>
585
- <Placeholder name={phKey} rendering={component} />
586
- </SitecoreProvider>
587
- );
588
-
589
- expect(renderedComponent.container.querySelectorAll('.feaas-component').length).to.equal(2);
590
- expect(renderedComponent.container.querySelectorAll('.feaas-wrapper').length).to.equal(1);
591
-
592
- feaasComponentStub.restore();
593
- feaasWrapperStub.restore();
594
- });
595
- });
596
-
597
- it('should render Suspense when disableSuspense is false', async () => {
598
- const page = getPage();
599
- page.layout = normalModeDevData;
600
- const component = normalModeDevData.sitecore.route as RouteData;
601
- const phKey = 'main';
602
-
603
- const renderedComponent = render(
604
- <SitecoreProvider componentMap={componentMap} page={page}>
605
- <Placeholder name={phKey} disableSuspense={false} rendering={component} />
606
- </SitecoreProvider>
607
- );
608
-
609
- expect(renderedComponent.container.innerHTML).to.contain('Loading component...');
610
-
611
- await findByText(renderedComponent.container, 'No error');
612
- });
613
-
614
- it('should not render Suspense when disableSuspense is true', async () => {
615
- const page = getPage();
616
- page.layout = normalModeDevData;
617
- const component = normalModeDevData.sitecore.route as RouteData;
618
- const phKey = 'main';
619
-
620
- const renderedComponent = render(
621
- <SitecoreProvider componentMap={componentMap} page={page}>
622
- <Placeholder name={phKey} disableSuspense={true} rendering={component} />
623
- </SitecoreProvider>
624
- );
625
-
626
- expect(renderedComponent.container.innerHTML).to.not.contain('Loading component...');
627
-
628
- await findByText(renderedComponent.container, 'No error');
629
- });
630
- */
631
- test('should render null for unknown placeholder', async () => {
632
- const page = getPage();
633
- const route = {
634
- placeholders: {
635
- main: [
636
- {
637
- componentName: 'Home',
638
- },
639
- ],
640
- },
641
- } as unknown as RouteData;
642
- page.layout = {
643
- sitecore: {
644
- context: {},
645
- route,
646
- },
647
- };
648
- mockSitecoreContext(page, componentMap);
649
-
650
- const phKey = 'unknown';
651
-
652
- const renderedComponent = await renderAstroComponent(Placeholder, {
653
- props: {
654
- name: phKey,
655
- rendering: route,
656
- },
657
- });
658
-
659
- expect(renderedComponent?.innerHTML).to.be.empty;
660
- });
661
-
662
- test('should render error message on error', async () => {
663
- const components = new Map<string, AstroContentSdkComponent>();
664
- components.set('Home', Home);
665
- components.set('ThrowError', TestComponentWithError);
666
-
667
- const route = {
668
- placeholders: {
669
- main: [
670
- {
671
- componentName: 'ThrowError',
672
- },
673
- ],
674
- },
675
- } as unknown as RouteData;
676
- const page = getPage();
677
- page.layout = {
678
- sitecore: {
679
- context: {},
680
- route,
681
- },
682
- };
683
- mockSitecoreContext(page, components);
684
-
685
- const phKey = 'main';
686
-
687
- const renderedComponent = await renderAstroComponent(Placeholder, {
688
- props: {
689
- name: phKey,
690
- rendering: route,
691
- },
692
- });
693
-
694
- expect(renderedComponent.querySelectorAll('.sc-content-sdk-placeholder-error').length).to.equal(
695
- 1
696
- );
697
- });
698
-
699
- test('should render error message on error, only for the errored component', async () => {
700
- const components = new Map<string, AstroContentSdkComponent>();
701
- components.set('Home', Home);
702
- components.set('ThrowError', TestComponentWithError);
703
-
704
- components.set('Foo', TestWrapperComponent);
705
-
706
- const route = {
707
- placeholders: {
708
- main: [
709
- {
710
- componentName: 'ThrowError',
711
- },
712
- {
713
- componentName: 'Foo',
714
- },
715
- ],
716
- },
717
- } as unknown as RouteData;
718
- const page = getPage();
719
- page.layout = {
720
- sitecore: {
721
- context: {},
722
- route,
723
- },
724
- };
725
- mockSitecoreContext(page, components);
726
-
727
- const phKey = 'main';
728
-
729
- const renderedComponent = await renderAstroComponent(Placeholder, {
730
- props: {
731
- name: phKey,
732
- rendering: route,
733
- },
734
- });
735
-
736
- expect(renderedComponent.querySelectorAll('.sc-content-sdk-placeholder-error').length).to.equal(
737
- 1
738
- );
739
- expect(renderedComponent.querySelectorAll('div.wrapper').length).to.equal(1);
740
- });
741
-
742
- test('should render custom errorComponent on error, if provided', async () => {
743
- const page = getPage();
744
- const components = new Map<string, AstroContentSdkComponent>();
745
-
746
- components.set('Home', Home);
747
- components.set('ThrowError', TestComponentWithError);
748
-
749
- const route = {
750
- placeholders: {
751
- main: [
752
- {
753
- componentName: 'ThrowError',
754
- },
755
- ],
756
- },
757
- } as unknown as RouteData;
758
- page.layout = {
759
- sitecore: {
760
- context: {},
761
- route,
762
- },
763
- };
764
- mockSitecoreContext(page, components);
765
-
766
- const phKey = 'main';
767
-
768
- const renderedComponent = await renderAstroComponent(Placeholder, {
769
- props: {
770
- name: phKey,
771
- rendering: route,
772
- errorComponent: CustomErrorComponent,
773
- },
774
- });
775
-
776
- expect(renderedComponent.querySelectorAll('.custom-error').length).to.equal(1);
777
- });
778
-
779
- test('should render MissingComponent for unknown rendering', async () => {
780
- const page = getPage();
781
- const route: any = {
782
- placeholders: {
783
- main: [
784
- {
785
- componentName: 'Unknown',
786
- },
787
- ],
788
- },
789
- };
790
- page.layout = {
791
- sitecore: {
792
- context: {},
793
- route,
794
- },
795
- };
796
- mockSitecoreContext(page, componentMap);
797
-
798
- const phKey = 'main';
799
-
800
- const renderedComponent = await renderAstroComponent(Placeholder, {
801
- props: {
802
- name: phKey,
803
- rendering: route,
804
- missingComponentComponent: CustomMissingComponent,
805
- },
806
- });
807
-
808
- expect(renderedComponent.querySelectorAll('.missing-component').length).to.equal(1);
809
- });
810
-
811
- test('should render nothing for rendering without a name', async () => {
812
- const page = getPage();
813
- const componentMap = new Map<string, AstroContentSdkComponent>();
814
-
815
- componentMap.set('Test', TestWrapperComponent);
816
-
817
- const route: any = {
818
- placeholders: {
819
- main: [
820
- {
821
- componentName: 'Test',
822
- },
823
- {
824
- componentName: null,
825
- },
826
- ],
827
- },
828
- };
829
- page.layout = {
830
- sitecore: {
831
- context: {},
832
- route,
833
- },
834
- };
835
- mockSitecoreContext(page, componentMap);
836
-
837
- const phKey = 'main';
838
-
839
- const renderedComponent = await renderAstroComponent(Placeholder, {
840
- props: {
841
- name: phKey,
842
- rendering: route,
843
- },
844
- });
845
-
846
- expect(renderedComponent.children.length).to.equal(1);
847
- });
848
-
849
- test('should render HiddenRendering when rendering is hidden', async () => {
850
- const page = getPage();
851
- const route: any = {
852
- placeholders: {
853
- main: [
854
- {
855
- componentName: 'Hidden Rendering',
856
- },
857
- ],
858
- },
859
- };
860
- page.layout = {
861
- sitecore: {
862
- context: {},
863
- route,
864
- },
865
- };
866
- mockSitecoreContext(page, componentMap);
867
-
868
- const phKey = 'main';
869
-
870
- const renderedComponent = await renderAstroComponent(Placeholder, {
871
- props: {
872
- name: phKey,
873
- rendering: route,
874
- },
875
- });
876
-
877
- expect(renderedComponent.textContent).to.equal('The component is hidden');
878
- });
879
-
880
- test('should render custom HiddenRendering when rendering is hidden', async () => {
881
- const page = getPage();
882
-
883
- const route: any = {
884
- placeholders: {
885
- main: [
886
- {
887
- componentName: 'Hidden Rendering',
888
- },
889
- ],
890
- },
891
- };
892
- page.layout = {
893
- sitecore: {
894
- context: {},
895
- route,
896
- },
897
- };
898
- mockSitecoreContext(page, componentMap);
899
-
900
- const phKey = 'main';
901
-
902
- const renderedComponent = await renderAstroComponent(Placeholder, {
903
- props: {
904
- name: phKey,
905
- rendering: route,
906
- hiddenRenderingComponent: CustomHiddenRendering,
907
- },
908
- });
909
-
910
- expect(renderedComponent.querySelectorAll('.hidden-rendering').length).to.equal(1);
911
- expect(
912
- expect(renderedComponent.querySelector('.hidden-rendering p')?.textContent).to.equal(
913
- 'Hidden Rendering'
914
- )
915
- );
916
- });
917
-
918
- describe('PlaceholderMetadata', () => {
919
- const {
920
- layoutData,
921
- layoutDataForNestedDynamicPlaceholder,
922
- layoutDataWithEmptyPlaceholder,
923
- layoutDataWithUnknownComponent,
924
- } = metadataData;
925
-
926
- const mode: PageMode = {
927
- name: LayoutServicePageState.Edit,
928
- isEditing: true,
929
- isNormal: false,
930
- isPreview: false,
931
- isDesignLibrary: false,
932
- designLibrary: {
933
- isVariantGeneration: false,
934
- },
935
- };
936
-
937
- let page: Page;
938
-
939
- beforeEach(() => {
940
- page = getPage();
941
- page.layout = layoutData;
942
- page.mode = mode;
943
- mockSitecoreContext(page, componentMap);
944
- });
945
-
946
- const componentMap = new Map<string, AstroContentSdkComponent>();
947
-
948
- componentMap.set('Header', TestHeader);
949
- componentMap.set('Logo', TestLogo);
950
-
951
- test('should render <PlaceholderMetadata> with nested placeholder components', async () => {
952
- const wrapper = await renderAstroComponent(Placeholder, {
953
- props: {
954
- name: 'main',
955
- rendering: layoutData.sitecore.route,
956
- },
957
- });
958
-
959
- expect(wrapper?.innerHTML).to.equal(
960
- [
961
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="main_00000000-0000-0000-0000-000000000000"></code>',
962
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="nested123"></code>',
963
- '<div class="header-wrapper">',
964
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="logo_nested123"></code>',
965
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="deep123"></code>',
966
- '<div class="Logo-mock"></div>',
967
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>',
968
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
969
- '</div>',
970
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>',
971
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
972
- ].join('')
973
- );
974
-
975
- expect(wrapper?.querySelectorAll('.scpm').length).to.equal(8);
976
- });
977
-
978
- test('should render code blocks even if placeholder is empty', async () => {
979
- page.layout = layoutDataWithEmptyPlaceholder;
980
- mockSitecoreContext(page, componentMap);
981
-
982
- const wrapper = await renderAstroComponent(Placeholder, {
983
- props: {
984
- name: 'main',
985
- rendering: layoutDataWithEmptyPlaceholder.sitecore.route,
986
- },
987
- });
988
-
989
- expect(wrapper.innerHTML).to.equal(
990
- [
991
- '<div class="sc-jss-empty-placeholder">',
992
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="main_00000000-0000-0000-0000-000000000000"></code>',
993
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
994
- '</div>',
995
- ].join('')
996
- );
997
- });
998
-
999
- test('should render missing component with code blocks if component is not registered', async () => {
1000
- page.layout = layoutDataWithUnknownComponent;
1001
- mockSitecoreContext(page, componentMap);
1002
-
1003
- const wrapper = await renderAstroComponent(Placeholder, {
1004
- props: {
1005
- name: 'main',
1006
- rendering: layoutDataWithUnknownComponent.sitecore.route,
1007
- },
1008
- });
1009
-
1010
- expect(wrapper?.innerHTML).to.equal(
1011
- [
1012
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="main_00000000-0000-0000-0000-000000000000"></code>',
1013
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="123"></code>',
1014
- '<div style="background:darkorange;outline:5px solid orange;padding:10px;color:white;max-width:500px"><h2>Unknown</h2><p>Content SDK component is missing Astro implementation. See the developer console for more information.</p></div>',
1015
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>',
1016
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
1017
- ].join('')
1018
- );
1019
- });
1020
-
1021
- test('should render dynamic placeholder', async () => {
1022
- const phKey = 'container-1';
1023
- const layoutData = layoutDataForNestedDynamicPlaceholder('container-{*}');
1024
- page.layout = layoutData;
1025
- mockSitecoreContext(page, componentMap);
1026
-
1027
- const wrapper = await renderAstroComponent(Placeholder, {
1028
- props: {
1029
- name: phKey,
1030
- rendering: layoutData.sitecore.route,
1031
- },
1032
- });
1033
-
1034
- expect(wrapper?.innerHTML).to.equal(
1035
- [
1036
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="container-{*}_00000000-0000-0000-0000-000000000000"></code>',
1037
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="nested123"></code>',
1038
- '<div class="header-wrapper">',
1039
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="logo_nested123"></code>',
1040
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="deep123"></code>',
1041
- '<div class="Logo-mock"></div><code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>',
1042
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
1043
- '</div>',
1044
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>',
1045
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
1046
- ].join('')
1047
- );
1048
-
1049
- expect(wrapper?.querySelectorAll('.scpm')?.length).to.equal(8);
1050
- });
1051
-
1052
- test('should render double digit dynamic placeholder', async () => {
1053
- const phKey = 'container-1-2';
1054
- const layoutData = layoutDataForNestedDynamicPlaceholder('container-1-{*}');
1055
- page.layout = layoutData;
1056
- mockSitecoreContext(page, componentMap);
1057
-
1058
- const wrapper = await renderAstroComponent(Placeholder, {
1059
- props: {
1060
- name: phKey,
1061
- rendering: layoutData.sitecore.route,
1062
- },
1063
- });
1064
-
1065
- expect(wrapper?.innerHTML).to.equal(
1066
- [
1067
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="container-1-{*}_00000000-0000-0000-0000-000000000000"></code>',
1068
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="nested123"></code>',
1069
- '<div class="header-wrapper">',
1070
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="logo_nested123"></code>',
1071
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="deep123"></code>',
1072
- '<div class="Logo-mock"></div><code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>',
1073
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
1074
- '</div>',
1075
- '<code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>',
1076
- '<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>',
1077
- ].join('')
1078
- );
1079
-
1080
- // 4 placeholders in total, 8 code blocks
1081
- expect(wrapper?.querySelectorAll('.scpm').length).to.equal(8);
1082
- });
1083
- });
1084
- });
1085
-
1086
- afterAll(() => {
1087
- (global as any).window.close();
1088
- });