docusaurus-plugin-generate-schema-docs 1.1.1 → 1.3.0

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 (81) hide show
  1. package/README.md +60 -2
  2. package/__tests__/ExampleDataLayer.test.js +92 -0
  3. package/__tests__/__fixtures__/static/schemas/add-to-cart-event.json +44 -0
  4. package/__tests__/__fixtures__/static/schemas/choice-event.json +72 -0
  5. package/__tests__/__fixtures__/static/schemas/components/dataLayer.json +56 -0
  6. package/__tests__/__fixtures__/static/schemas/components/product.json +125 -0
  7. package/__tests__/__fixtures__/static/schemas/nested/child-event.json +10 -0
  8. package/__tests__/__fixtures__/static/schemas/nested/grandchild-a.json +9 -0
  9. package/__tests__/__fixtures__/static/schemas/nested/grandchild-b.json +9 -0
  10. package/__tests__/__fixtures__/static/schemas/nested/parent-event.json +7 -0
  11. package/__tests__/__fixtures__/static/schemas/root-any-of-event.json +34 -0
  12. package/__tests__/__fixtures__/static/schemas/root-choice-event.json +36 -0
  13. package/__tests__/__fixtures__/validateSchemas/circular-schema.json +8 -0
  14. package/__tests__/__fixtures__/validateSchemas/components/referenced.json +10 -0
  15. package/__tests__/__fixtures__/validateSchemas/invalid-example-schema.json +8 -0
  16. package/__tests__/__fixtures__/validateSchemas/main-schema-with-missing-ref.json +8 -0
  17. package/__tests__/__fixtures__/validateSchemas/main-schema-with-ref.json +8 -0
  18. package/__tests__/__fixtures__/validateSchemas/no-example-schema.json +12 -0
  19. package/__tests__/__fixtures__/validateSchemas/schema-A.json +7 -0
  20. package/__tests__/__fixtures__/validateSchemas/schema-B.json +7 -0
  21. package/__tests__/__fixtures__/validateSchemas/valid-schema.json +8 -0
  22. package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/add-to-cart-event.json +44 -0
  23. package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/components/dataLayer.json +56 -0
  24. package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/components/product.json +125 -0
  25. package/__tests__/__fixtures_versioned__/static/schemas/next/add-to-cart-event.json +44 -0
  26. package/__tests__/__fixtures_versioned__/static/schemas/next/components/dataLayer.json +56 -0
  27. package/__tests__/__fixtures_versioned__/static/schemas/next/components/product.json +125 -0
  28. package/__tests__/__fixtures_versioned__/versions.json +1 -0
  29. package/__tests__/__snapshots__/ExampleDataLayer.test.js.snap +117 -0
  30. package/__tests__/__snapshots__/generateEventDocs.nested.test.js.snap +92 -0
  31. package/__tests__/__snapshots__/generateEventDocs.test.js.snap +151 -0
  32. package/__tests__/__snapshots__/generateEventDocs.versioned.test.js.snap +53 -0
  33. package/__tests__/components/FoldableRows.test.js +330 -0
  34. package/__tests__/components/PropertiesTable.test.js +41 -0
  35. package/__tests__/components/PropertyRow.test.js +487 -0
  36. package/__tests__/components/SchemaJsonViewer.test.js +36 -0
  37. package/__tests__/components/SchemaRows.test.js +110 -0
  38. package/__tests__/components/SchemaViewer.test.js +44 -0
  39. package/__tests__/components/TableHeader.test.js +20 -0
  40. package/__tests__/generateEventDocs.nested.test.js +80 -0
  41. package/__tests__/generateEventDocs.test.js +90 -0
  42. package/__tests__/generateEventDocs.versioned.test.js +69 -0
  43. package/__tests__/helpers/buildExampleFromSchema.test.js +188 -0
  44. package/__tests__/helpers/file-system.test.js +44 -0
  45. package/__tests__/helpers/getConstraints.test.js +58 -0
  46. package/__tests__/helpers/loadSchema.test.js +20 -0
  47. package/__tests__/helpers/path-helpers.test.js +34 -0
  48. package/__tests__/helpers/processSchema.test.js +56 -0
  49. package/__tests__/helpers/schema-processing.test.js +82 -0
  50. package/__tests__/helpers/schemaToExamples.test.js +56 -0
  51. package/__tests__/helpers/schemaToTableData.filtering.test.js +65 -0
  52. package/__tests__/helpers/schemaToTableData.hierarchicalLines.test.js +539 -0
  53. package/__tests__/helpers/schemaToTableData.test.js +222 -0
  54. package/__tests__/helpers/update-schema-ids.test.js +107 -0
  55. package/__tests__/update-schema-ids.test.js +39 -0
  56. package/__tests__/validateSchemas.test.js +137 -0
  57. package/components/ExampleDataLayer.js +60 -27
  58. package/components/FoldableRows.js +164 -0
  59. package/components/PropertiesTable.js +12 -14
  60. package/components/PropertyRow.js +183 -0
  61. package/components/SchemaJsonViewer.js +8 -7
  62. package/components/SchemaRows.css +250 -0
  63. package/components/SchemaRows.js +24 -69
  64. package/components/SchemaViewer.js +21 -13
  65. package/components/TableHeader.js +15 -0
  66. package/generateEventDocs.js +141 -60
  67. package/helpers/buildExampleFromSchema.js +59 -73
  68. package/helpers/choice-index-template.js +22 -0
  69. package/helpers/file-system.js +32 -0
  70. package/helpers/getConstraints.js +52 -0
  71. package/helpers/loadSchema.js +11 -0
  72. package/helpers/path-helpers.js +22 -0
  73. package/helpers/processSchema.js +32 -0
  74. package/helpers/schema-doc-template.js +36 -0
  75. package/helpers/schema-processing.js +75 -0
  76. package/helpers/schemaToExamples.js +99 -0
  77. package/helpers/schemaToTableData.js +311 -0
  78. package/helpers/update-schema-ids.js +47 -0
  79. package/index.js +146 -47
  80. package/package.json +6 -3
  81. package/validateSchemas.js +56 -70
@@ -0,0 +1,487 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { render } from '@testing-library/react';
4
+ import PropertyRow from '../../components/PropertyRow';
5
+
6
+ describe('PropertyRow', () => {
7
+ it('renders a basic property', () => {
8
+ const row = {
9
+ name: 'name',
10
+ level: 0,
11
+ required: false,
12
+ propertyType: 'string',
13
+ description: 'The name of the user.',
14
+ example: 'John Doe',
15
+ constraints: [],
16
+ path: ['name'],
17
+ };
18
+
19
+ const { getByText } = render(
20
+ <table>
21
+ <tbody>
22
+ <PropertyRow row={row} />
23
+ </tbody>
24
+ </table>,
25
+ );
26
+
27
+ expect(getByText('name')).toBeInTheDocument();
28
+ expect(getByText('string')).toBeInTheDocument();
29
+ expect(getByText('The name of the user.')).toBeInTheDocument();
30
+ expect(getByText('John Doe')).toBeInTheDocument();
31
+ });
32
+
33
+ it('marks required properties', () => {
34
+ const row = {
35
+ name: 'name',
36
+ level: 0,
37
+ required: true,
38
+ propertyType: 'string',
39
+ description: '',
40
+ example: '',
41
+ constraints: ['required'],
42
+ path: ['name'],
43
+ };
44
+
45
+ const { container, getByText } = render(
46
+ <table>
47
+ <tbody>
48
+ <PropertyRow row={row} />
49
+ </tbody>
50
+ </table>,
51
+ );
52
+
53
+ expect(container.querySelector('.required-row')).toBeInTheDocument();
54
+ expect(container.querySelector('.required')).toBeInTheDocument();
55
+ expect(getByText('required')).toBeInTheDocument();
56
+ });
57
+
58
+ it('renders multiple constraints', () => {
59
+ const row = {
60
+ name: 'name',
61
+ level: 0,
62
+ required: true,
63
+ propertyType: 'string',
64
+ description: '',
65
+ example: '',
66
+ constraints: ['required', 'minLength: 1', 'maxLength: 10'],
67
+ path: ['name'],
68
+ };
69
+
70
+ const { getByText } = render(
71
+ <table>
72
+ <tbody>
73
+ <PropertyRow row={row} />
74
+ </tbody>
75
+ </table>,
76
+ );
77
+ expect(getByText('required')).toBeInTheDocument();
78
+ expect(getByText('minLength: 1')).toBeInTheDocument();
79
+ expect(getByText('maxLength: 10')).toBeInTheDocument();
80
+ });
81
+
82
+ it('renders an example', () => {
83
+ const row = {
84
+ name: 'name',
85
+ level: 0,
86
+ required: false,
87
+ propertyType: 'string',
88
+ description: '',
89
+ example: 'foo',
90
+ constraints: [],
91
+ path: ['name'],
92
+ };
93
+
94
+ const { getByText } = render(
95
+ <table>
96
+ <tbody>
97
+ <PropertyRow row={row} />
98
+ </tbody>
99
+ </table>,
100
+ );
101
+ expect(getByText('foo')).toBeInTheDocument();
102
+ });
103
+
104
+ it('does not render anything for empty constraints', () => {
105
+ const row = {
106
+ name: 'name',
107
+ level: 0,
108
+ required: false,
109
+ propertyType: 'string',
110
+ description: '',
111
+ example: '',
112
+ constraints: [],
113
+ path: ['name'],
114
+ };
115
+
116
+ const { container } = render(
117
+ <table>
118
+ <tbody>
119
+ <PropertyRow row={row} />
120
+ </tbody>
121
+ </table>,
122
+ );
123
+
124
+ // The cell for constraints is the 3rd cell (index 2)
125
+ const cells = container.querySelectorAll('td');
126
+ expect(cells[2].innerHTML).toBe('');
127
+ });
128
+
129
+ describe('hierarchical lines feature', () => {
130
+ it('renders {} symbol for object containers', () => {
131
+ const row = {
132
+ name: 'user_data',
133
+ level: 0,
134
+ required: false,
135
+ propertyType: 'object',
136
+ description: '',
137
+ example: '',
138
+ constraints: [],
139
+ path: ['user_data'],
140
+ hasChildren: true,
141
+ containerType: 'object',
142
+ continuingLevels: [],
143
+ };
144
+
145
+ const { container, getByText } = render(
146
+ <table>
147
+ <tbody>
148
+ <PropertyRow row={row} />
149
+ </tbody>
150
+ </table>,
151
+ );
152
+
153
+ expect(getByText('{}')).toBeInTheDocument();
154
+ expect(container.querySelector('.container-symbol')).toBeInTheDocument();
155
+ });
156
+
157
+ it('renders [] symbol for array containers', () => {
158
+ const row = {
159
+ name: 'addresses',
160
+ level: 0,
161
+ required: false,
162
+ propertyType: 'array',
163
+ description: '',
164
+ example: '',
165
+ constraints: [],
166
+ path: ['addresses'],
167
+ hasChildren: true,
168
+ containerType: 'array',
169
+ continuingLevels: [],
170
+ };
171
+
172
+ const { container, getByText } = render(
173
+ <table>
174
+ <tbody>
175
+ <PropertyRow row={row} />
176
+ </tbody>
177
+ </table>,
178
+ );
179
+
180
+ expect(getByText('[]')).toBeInTheDocument();
181
+ expect(container.querySelector('.container-symbol')).toBeInTheDocument();
182
+ });
183
+
184
+ it('does not render container symbol for simple properties', () => {
185
+ const row = {
186
+ name: 'name',
187
+ level: 0,
188
+ required: false,
189
+ propertyType: 'string',
190
+ description: '',
191
+ example: '',
192
+ constraints: [],
193
+ path: ['name'],
194
+ hasChildren: false,
195
+ containerType: null,
196
+ continuingLevels: [],
197
+ };
198
+
199
+ const { container } = render(
200
+ <table>
201
+ <tbody>
202
+ <PropertyRow row={row} />
203
+ </tbody>
204
+ </table>,
205
+ );
206
+
207
+ expect(
208
+ container.querySelector('.container-symbol'),
209
+ ).not.toBeInTheDocument();
210
+ });
211
+
212
+ it('applies has-children class when property has children', () => {
213
+ const row = {
214
+ name: 'user_data',
215
+ level: 1,
216
+ required: false,
217
+ propertyType: 'object',
218
+ description: '',
219
+ example: '',
220
+ constraints: [],
221
+ path: ['user_data'],
222
+ hasChildren: true,
223
+ containerType: 'object',
224
+ continuingLevels: [],
225
+ };
226
+
227
+ const { container } = render(
228
+ <table>
229
+ <tbody>
230
+ <PropertyRow row={row} />
231
+ </tbody>
232
+ </table>,
233
+ );
234
+
235
+ expect(container.querySelector('.has-children')).toBeInTheDocument();
236
+ });
237
+
238
+ it('applies container-object class for object containers', () => {
239
+ const row = {
240
+ name: 'user_data',
241
+ level: 1,
242
+ required: false,
243
+ propertyType: 'object',
244
+ description: '',
245
+ example: '',
246
+ constraints: [],
247
+ path: ['user_data'],
248
+ hasChildren: true,
249
+ containerType: 'object',
250
+ continuingLevels: [],
251
+ };
252
+
253
+ const { container } = render(
254
+ <table>
255
+ <tbody>
256
+ <PropertyRow row={row} />
257
+ </tbody>
258
+ </table>,
259
+ );
260
+
261
+ expect(container.querySelector('.container-object')).toBeInTheDocument();
262
+ });
263
+
264
+ it('applies container-array class for array containers', () => {
265
+ const row = {
266
+ name: 'addresses',
267
+ level: 1,
268
+ required: false,
269
+ propertyType: 'array',
270
+ description: '',
271
+ example: '',
272
+ constraints: [],
273
+ path: ['addresses'],
274
+ hasChildren: true,
275
+ containerType: 'array',
276
+ continuingLevels: [],
277
+ };
278
+
279
+ const { container } = render(
280
+ <table>
281
+ <tbody>
282
+ <PropertyRow row={row} />
283
+ </tbody>
284
+ </table>,
285
+ );
286
+
287
+ expect(container.querySelector('.container-array')).toBeInTheDocument();
288
+ });
289
+
290
+ it('applies is-last class when isLastInGroup is true', () => {
291
+ const row = {
292
+ name: 'last_item',
293
+ level: 1,
294
+ required: false,
295
+ propertyType: 'string',
296
+ description: '',
297
+ example: '',
298
+ constraints: [],
299
+ path: ['last_item'],
300
+ hasChildren: false,
301
+ containerType: null,
302
+ continuingLevels: [],
303
+ isLastInGroup: true,
304
+ };
305
+
306
+ const { container } = render(
307
+ <table>
308
+ <tbody>
309
+ <PropertyRow row={row} isLastInGroup={true} />
310
+ </tbody>
311
+ </table>,
312
+ );
313
+
314
+ expect(container.querySelector('.is-last')).toBeInTheDocument();
315
+ });
316
+
317
+ it('applies level class based on nesting level', () => {
318
+ const row = {
319
+ name: 'nested_item',
320
+ level: 2,
321
+ required: false,
322
+ propertyType: 'string',
323
+ description: '',
324
+ example: '',
325
+ constraints: [],
326
+ path: ['parent', 'nested_item'],
327
+ hasChildren: false,
328
+ containerType: null,
329
+ continuingLevels: [],
330
+ };
331
+
332
+ const { container } = render(
333
+ <table>
334
+ <tbody>
335
+ <PropertyRow row={row} />
336
+ </tbody>
337
+ </table>,
338
+ );
339
+
340
+ expect(container.querySelector('.level-2')).toBeInTheDocument();
341
+ });
342
+
343
+ it('applies padding-left based on level using rem units', () => {
344
+ const row = {
345
+ name: 'nested_item',
346
+ level: 2,
347
+ required: false,
348
+ propertyType: 'string',
349
+ description: '',
350
+ example: '',
351
+ constraints: [],
352
+ path: ['parent', 'nested_item'],
353
+ hasChildren: false,
354
+ containerType: null,
355
+ continuingLevels: [],
356
+ };
357
+
358
+ const { container } = render(
359
+ <table>
360
+ <tbody>
361
+ <PropertyRow row={row} />
362
+ </tbody>
363
+ </table>,
364
+ );
365
+
366
+ const td = container.querySelector('td');
367
+ // level 2: 2 * 1.25 + 0.5 = 3rem
368
+ expect(td.style.paddingLeft).toBe('3rem');
369
+ });
370
+
371
+ it('applies background-image for parent-to-child line when hasChildren is true', () => {
372
+ const row = {
373
+ name: 'user_data',
374
+ level: 1,
375
+ required: false,
376
+ propertyType: 'object',
377
+ description: '',
378
+ example: '',
379
+ constraints: [],
380
+ path: ['user_data'],
381
+ hasChildren: true,
382
+ containerType: 'object',
383
+ continuingLevels: [],
384
+ };
385
+
386
+ const { container } = render(
387
+ <table>
388
+ <tbody>
389
+ <PropertyRow row={row} />
390
+ </tbody>
391
+ </table>,
392
+ );
393
+
394
+ const td = container.querySelector('td');
395
+ expect(td.style.backgroundImage).toContain('linear-gradient');
396
+ });
397
+
398
+ it('applies background-image for continuing ancestor lines', () => {
399
+ const row = {
400
+ name: 'deep_item',
401
+ level: 3,
402
+ required: false,
403
+ propertyType: 'string',
404
+ description: '',
405
+ example: '',
406
+ constraints: [],
407
+ path: ['a', 'b', 'deep_item'],
408
+ hasChildren: false,
409
+ containerType: null,
410
+ continuingLevels: [0, 1], // Ancestors at levels 0 and 1 have more siblings
411
+ };
412
+
413
+ const { container } = render(
414
+ <table>
415
+ <tbody>
416
+ <PropertyRow row={row} />
417
+ </tbody>
418
+ </table>,
419
+ );
420
+
421
+ const td = container.querySelector('td');
422
+ // Should have background gradients for continuing lines
423
+ // Level 0 passes filter (0 < 3-1 = 2), level 1 passes (1 < 2)
424
+ expect(td.style.backgroundImage).toContain('linear-gradient');
425
+ });
426
+
427
+ it('filters out immediate parent level from continuing lines', () => {
428
+ const row = {
429
+ name: 'nested_item',
430
+ level: 2,
431
+ required: false,
432
+ propertyType: 'string',
433
+ description: '',
434
+ example: '',
435
+ constraints: [],
436
+ path: ['parent', 'nested_item'],
437
+ hasChildren: false,
438
+ containerType: null,
439
+ continuingLevels: [0, 1], // Level 1 is immediate parent
440
+ };
441
+
442
+ const { container } = render(
443
+ <table>
444
+ <tbody>
445
+ <PropertyRow row={row} />
446
+ </tbody>
447
+ </table>,
448
+ );
449
+
450
+ const td = container.querySelector('td');
451
+ // Filter is lvl < level - 1, so for level 2: lvl < 1
452
+ // Only level 0 should pass, level 1 should be filtered out
453
+ // So we should have exactly one gradient (for level 0)
454
+ const bgImage = td.style.backgroundImage;
455
+ // Count occurrences of linear-gradient
456
+ const gradientCount = (bgImage.match(/linear-gradient/g) || []).length;
457
+ expect(gradientCount).toBe(1);
458
+ });
459
+
460
+ it('has no background-image when continuingLevels is empty and no children', () => {
461
+ const row = {
462
+ name: 'simple',
463
+ level: 1,
464
+ required: false,
465
+ propertyType: 'string',
466
+ description: '',
467
+ example: '',
468
+ constraints: [],
469
+ path: ['simple'],
470
+ hasChildren: false,
471
+ containerType: null,
472
+ continuingLevels: [],
473
+ };
474
+
475
+ const { container } = render(
476
+ <table>
477
+ <tbody>
478
+ <PropertyRow row={row} />
479
+ </tbody>
480
+ </table>,
481
+ );
482
+
483
+ const td = container.querySelector('td');
484
+ expect(td.style.backgroundImage).toBe('');
485
+ });
486
+ });
487
+ });
@@ -0,0 +1,36 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { render } from '@testing-library/react';
4
+ import SchemaJsonViewer from '../../components/SchemaJsonViewer';
5
+
6
+ // Mock CodeBlock as it's an external theme component
7
+ jest.mock('@theme/CodeBlock', () => {
8
+ return function DummyCodeBlock({ children, language }) {
9
+ return <pre data-language={language}>{children}</pre>;
10
+ };
11
+ });
12
+
13
+ describe('SchemaJsonViewer', () => {
14
+ it('renders the schema in a CodeBlock', () => {
15
+ const schema = {
16
+ type: 'object',
17
+ properties: {
18
+ name: { type: 'string' },
19
+ },
20
+ };
21
+
22
+ const { getByText, container } = render(
23
+ <SchemaJsonViewer schema={schema} />,
24
+ );
25
+
26
+ expect(getByText('View Raw JSON Schema')).toBeInTheDocument();
27
+ const detailsElement = container.querySelector('details');
28
+ expect(detailsElement).toHaveClass('schema-json-viewer');
29
+ const codeBlockElement = container.querySelector('pre');
30
+ expect(codeBlockElement).toBeInTheDocument();
31
+ expect(codeBlockElement).toHaveAttribute('data-language', 'json');
32
+ expect(codeBlockElement.textContent).toEqual(
33
+ JSON.stringify(schema, null, 2),
34
+ );
35
+ });
36
+ });
@@ -0,0 +1,110 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { render } from '@testing-library/react';
4
+ import SchemaRows from '../../components/SchemaRows';
5
+
6
+ // Mock child components
7
+ jest.mock('../../components/PropertyRow', () => {
8
+ const MockPropertyRow = (props) => (
9
+ <tr>
10
+ <td>Mocked PropertyRow: {props.row.name}</td>
11
+ </tr>
12
+ );
13
+ MockPropertyRow.displayName = 'MockPropertyRow';
14
+ return MockPropertyRow;
15
+ });
16
+
17
+ jest.mock('../../components/FoldableRows', () => {
18
+ const MockFoldableRows = (props) => (
19
+ <tr>
20
+ <td>Mocked FoldableRows: {props.row.choiceType}</td>
21
+ </tr>
22
+ );
23
+ MockFoldableRows.displayName = 'MockFoldableRows';
24
+ return MockFoldableRows;
25
+ });
26
+
27
+ describe('SchemaRows', () => {
28
+ it('renders a PropertyRow for each property type item in tableData', () => {
29
+ const tableData = [
30
+ { type: 'property', name: 'name', path: ['name'] },
31
+ { type: 'property', name: 'age', path: ['age'] },
32
+ ];
33
+
34
+ const { getByText } = render(
35
+ <table>
36
+ <tbody>
37
+ <SchemaRows tableData={tableData} />
38
+ </tbody>
39
+ </table>,
40
+ );
41
+
42
+ expect(getByText('Mocked PropertyRow: name')).toBeInTheDocument();
43
+ expect(getByText('Mocked PropertyRow: age')).toBeInTheDocument();
44
+ });
45
+
46
+ it('renders nested properties from a flat list', () => {
47
+ const tableData = [
48
+ { type: 'property', name: 'user', path: ['user'], level: 0 },
49
+ { type: 'property', name: 'id', path: ['user', 'id'], level: 1 },
50
+ ];
51
+
52
+ const { getByText } = render(
53
+ <table>
54
+ <tbody>
55
+ <SchemaRows tableData={tableData} />
56
+ </tbody>
57
+ </table>,
58
+ );
59
+
60
+ // It should render both the parent and child property from the flat list
61
+ expect(getByText('Mocked PropertyRow: user')).toBeInTheDocument();
62
+ expect(getByText('Mocked PropertyRow: id')).toBeInTheDocument();
63
+ });
64
+
65
+ it('renders a FoldableRows for choice type items in tableData', () => {
66
+ const tableData = [
67
+ {
68
+ type: 'choice',
69
+ choiceType: 'oneOf',
70
+ path: ['choice'],
71
+ options: [],
72
+ },
73
+ ];
74
+
75
+ const { getByText } = render(
76
+ <table>
77
+ <tbody>
78
+ <SchemaRows tableData={tableData} />
79
+ </tbody>
80
+ </table>,
81
+ );
82
+
83
+ expect(getByText('Mocked FoldableRows: oneOf')).toBeInTheDocument();
84
+ });
85
+
86
+ it('renders a mix of properties and choices', () => {
87
+ const tableData = [
88
+ { type: 'property', name: 'prop1', path: ['prop1'] },
89
+ {
90
+ type: 'choice',
91
+ choiceType: 'anyOf',
92
+ path: ['choice'],
93
+ options: [],
94
+ },
95
+ { type: 'property', name: 'prop2', path: ['prop2'] },
96
+ ];
97
+
98
+ const { getByText } = render(
99
+ <table>
100
+ <tbody>
101
+ <SchemaRows tableData={tableData} />
102
+ </tbody>
103
+ </table>,
104
+ );
105
+
106
+ expect(getByText('Mocked PropertyRow: prop1')).toBeInTheDocument();
107
+ expect(getByText('Mocked FoldableRows: anyOf')).toBeInTheDocument();
108
+ expect(getByText('Mocked PropertyRow: prop2')).toBeInTheDocument();
109
+ });
110
+ });
@@ -0,0 +1,44 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { render, screen, within } from '@testing-library/react';
4
+ import SchemaViewer from '../../components/SchemaViewer';
5
+ import choiceEventSchema from '../__fixtures__/static/schemas/choice-event.json';
6
+
7
+ // Mock the CodeBlock component as it's not relevant to this test
8
+ jest.mock('@theme/CodeBlock', () => {
9
+ const MockCodeBlock = ({ children }) => <pre>{children}</pre>;
10
+ MockCodeBlock.displayName = 'MockCodeBlock';
11
+ return MockCodeBlock;
12
+ });
13
+
14
+ // Mock the Heading component
15
+ jest.mock('@theme/Heading', () => {
16
+ const MockHeading = ({ as: Component, ...props }) => <Component {...props} />;
17
+ MockHeading.displayName = 'MockHeading';
18
+ return MockHeading;
19
+ });
20
+
21
+ describe('SchemaViewer', () => {
22
+ it('renders complex schema with payment_method and required indicators', () => {
23
+ render(<SchemaViewer schema={choiceEventSchema} />);
24
+
25
+ // Check that payment_method property name is rendered within the table
26
+ const table = screen.getByRole('table');
27
+ expect(within(table).getByText('payment_method')).toBeInTheDocument();
28
+
29
+ // Check that the "required" text is rendered for the user_id choice
30
+ const userIdChoiceHeader = screen.getByText(
31
+ (content, element) =>
32
+ element.tagName.toLowerCase() === 'h4' &&
33
+ content.includes('Select one of the following options:'),
34
+ );
35
+ expect(userIdChoiceHeader).toBeInTheDocument();
36
+
37
+ // The required text is rendered as a 'required' constraint code block.
38
+ // We expect it for 'event', 'user_id', and 'payment_method' at the top level.
39
+ const requiredConstraints = within(table).getAllByText('required');
40
+
41
+ // There should be at least 3 required constraints visible at the top level.
42
+ expect(requiredConstraints.length).toBeGreaterThanOrEqual(3);
43
+ });
44
+ });
@@ -0,0 +1,20 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { render } from '@testing-library/react';
4
+ import TableHeader from '../../components/TableHeader';
5
+
6
+ describe('TableHeader', () => {
7
+ it('renders the table header with correct columns', () => {
8
+ const { getByText } = render(
9
+ <table>
10
+ <TableHeader />
11
+ </table>,
12
+ );
13
+
14
+ expect(getByText('Property')).toBeInTheDocument();
15
+ expect(getByText('Type')).toBeInTheDocument();
16
+ expect(getByText('Constraints')).toBeInTheDocument();
17
+ expect(getByText('Examples')).toBeInTheDocument();
18
+ expect(getByText('Description')).toBeInTheDocument();
19
+ });
20
+ });