import '@testing-library/jest-dom'; import { render } from '@testing-library/react'; import { JSONSchema4, JSONSchema7 } from 'json-schema'; import * as React from 'react'; import { beforeEach, describe, expect, it } from 'vitest'; import { JsonSchemaViewer } from '../components'; import { ViewMode } from '../types'; describe('HTML Output', () => { describe.each(['anyOf', 'oneOf'])('given %s combiner placed next to allOf', combiner => { let schema: JSONSchema4; beforeEach(() => { schema = { type: 'object', title: 'Account', allOf: [ { type: 'object', properties: { type: { type: 'string', enum: ['admin', 'editor'], }, enabled: { type: 'boolean', description: 'Is this account enabled', }, }, required: ['type'], }, ], [combiner]: [ { type: 'object', title: 'Admin', properties: { root: { type: 'boolean', }, group: { type: 'string', }, expirationDate: { type: 'string', }, }, }, { type: 'object', title: 'Editor', properties: { supervisor: { type: 'string', }, key: { type: 'string', }, }, }, ], }; }); it('given allOf merging enabled, should merge contents of allOf combiners', () => { expect( render().container.firstChild, ).toMatchSnapshot(); }); }); it('given array with oneOf containing items, should merge it correctly', () => { const schema: JSONSchema4 = { oneOf: [ { items: { type: 'string', }, }, { items: { type: 'number', }, }, ], type: 'array', }; expect( render().container.firstChild, ).toMatchSnapshot(); }); it.each(['standalone', 'read', 'write'])('given %s mode, should populate proper nodes', mode => { const schema: JSONSchema4 = { type: ['string', 'object'], properties: { id: { type: 'string', readOnly: true, }, description: { type: 'string', writeOnly: true, }, }, }; expect( render().container.firstChild, ).toMatchSnapshot(); }); it('given multiple object and string type, should process properties', () => { const schema: JSONSchema4 = { type: ['string', 'object'], properties: { ids: { type: 'array', items: { type: 'integer', }, }, }, }; expect( render().container.firstChild, ).toMatchSnapshot(); }); it('given complex type that includes array and complex array subtype, should not ignore subtype', () => { const schema: JSONSchema4 = { type: 'object', properties: { items: { type: ['null', 'array'], items: { type: ['string', 'number'], }, description: "This description can be long and should truncate once it reaches the end of the row. If it's not truncating then theres and issue that needs to be fixed. Help!", }, }, }; expect( render().container.firstChild, ).toMatchSnapshot(); }); it('given visible $ref node, should try to inject the title immediately', () => { const schema: JSONSchema4 = { type: 'object', properties: { foo: { $ref: '#/properties/user', }, user: { title: 'User', type: 'object', properties: { name: { type: 'string', }, }, }, }, }; expect(render().container.firstChild).toMatchSnapshot(); }); it('given dictionary with defined properties, should not render them', () => { const schema: JSONSchema7 = { type: ['object', 'null'], properties: { id: { type: 'string', readOnly: true, }, description: { type: 'string', writeOnly: true, }, }, additionalProperties: { type: 'string', }, }; expect(render().container.firstChild) .toMatchInlineSnapshot(` dictionary[string, string] or null `); }); it('should render top-level dictionary', () => { const schema: JSONSchema7 = { type: 'object', additionalProperties: { type: 'string', }, }; expect(render()).toMatchInlineSnapshot(` { "asFragment": [Function], "baseElement": dictionary[string, string] , "container": dictionary[string, string] , "debug": [Function], "findAllByAltText": [Function], "findAllByDisplayValue": [Function], "findAllByLabelText": [Function], "findAllByPlaceholderText": [Function], "findAllByRole": [Function], "findAllByTestId": [Function], "findAllByText": [Function], "findAllByTitle": [Function], "findByAltText": [Function], "findByDisplayValue": [Function], "findByLabelText": [Function], "findByPlaceholderText": [Function], "findByRole": [Function], "findByTestId": [Function], "findByText": [Function], "findByTitle": [Function], "getAllByAltText": [Function], "getAllByDisplayValue": [Function], "getAllByLabelText": [Function], "getAllByPlaceholderText": [Function], "getAllByRole": [Function], "getAllByTestId": [Function], "getAllByText": [Function], "getAllByTitle": [Function], "getByAltText": [Function], "getByDisplayValue": [Function], "getByLabelText": [Function], "getByPlaceholderText": [Function], "getByRole": [Function], "getByTestId": [Function], "getByText": [Function], "getByTitle": [Function], "queryAllByAltText": [Function], "queryAllByDisplayValue": [Function], "queryAllByLabelText": [Function], "queryAllByPlaceholderText": [Function], "queryAllByRole": [Function], "queryAllByTestId": [Function], "queryAllByText": [Function], "queryAllByTitle": [Function], "queryByAltText": [Function], "queryByDisplayValue": [Function], "queryByLabelText": [Function], "queryByPlaceholderText": [Function], "queryByRole": [Function], "queryByTestId": [Function], "queryByText": [Function], "queryByTitle": [Function], "rerender": [Function], "unmount": [Function], } `); }); it('should not merge array of dictionaries', () => { const schema: JSONSchema7 = { type: 'array', items: { type: 'object', additionalProperties: { type: 'string', }, }, }; expect(render()).toMatchInlineSnapshot(` { "asFragment": [Function], "baseElement": array dictionary[string, string] , "container": array dictionary[string, string] , "debug": [Function], "findAllByAltText": [Function], "findAllByDisplayValue": [Function], "findAllByLabelText": [Function], "findAllByPlaceholderText": [Function], "findAllByRole": [Function], "findAllByTestId": [Function], "findAllByText": [Function], "findAllByTitle": [Function], "findByAltText": [Function], "findByDisplayValue": [Function], "findByLabelText": [Function], "findByPlaceholderText": [Function], "findByRole": [Function], "findByTestId": [Function], "findByText": [Function], "findByTitle": [Function], "getAllByAltText": [Function], "getAllByDisplayValue": [Function], "getAllByLabelText": [Function], "getAllByPlaceholderText": [Function], "getAllByRole": [Function], "getAllByTestId": [Function], "getAllByText": [Function], "getAllByTitle": [Function], "getByAltText": [Function], "getByDisplayValue": [Function], "getByLabelText": [Function], "getByPlaceholderText": [Function], "getByRole": [Function], "getByTestId": [Function], "getByText": [Function], "getByTitle": [Function], "queryAllByAltText": [Function], "queryAllByDisplayValue": [Function], "queryAllByLabelText": [Function], "queryAllByPlaceholderText": [Function], "queryAllByRole": [Function], "queryAllByTestId": [Function], "queryAllByText": [Function], "queryAllByTitle": [Function], "queryByAltText": [Function], "queryByDisplayValue": [Function], "queryByLabelText": [Function], "queryByPlaceholderText": [Function], "queryByRole": [Function], "queryByTestId": [Function], "queryByText": [Function], "queryByTitle": [Function], "rerender": [Function], "unmount": [Function], } `); }); it('should merge dictionaries with array values', () => { const schema: JSONSchema7 = { type: 'object', additionalProperties: { type: 'array', items: { type: 'string', }, }, }; expect(render()).toMatchInlineSnapshot(` { "asFragment": [Function], "baseElement": dictionary[string, array] string , "container": dictionary[string, array] string , "debug": [Function], "findAllByAltText": [Function], "findAllByDisplayValue": [Function], "findAllByLabelText": [Function], "findAllByPlaceholderText": [Function], "findAllByRole": [Function], "findAllByTestId": [Function], "findAllByText": [Function], "findAllByTitle": [Function], "findByAltText": [Function], "findByDisplayValue": [Function], "findByLabelText": [Function], "findByPlaceholderText": [Function], "findByRole": [Function], "findByTestId": [Function], "findByText": [Function], "findByTitle": [Function], "getAllByAltText": [Function], "getAllByDisplayValue": [Function], "getAllByLabelText": [Function], "getAllByPlaceholderText": [Function], "getAllByRole": [Function], "getAllByTestId": [Function], "getAllByText": [Function], "getAllByTitle": [Function], "getByAltText": [Function], "getByDisplayValue": [Function], "getByLabelText": [Function], "getByPlaceholderText": [Function], "getByRole": [Function], "getByTestId": [Function], "getByText": [Function], "getByTitle": [Function], "queryAllByAltText": [Function], "queryAllByDisplayValue": [Function], "queryAllByLabelText": [Function], "queryAllByPlaceholderText": [Function], "queryAllByRole": [Function], "queryAllByTestId": [Function], "queryAllByText": [Function], "queryAllByTitle": [Function], "queryByAltText": [Function], "queryByDisplayValue": [Function], "queryByLabelText": [Function], "queryByPlaceholderText": [Function], "queryByRole": [Function], "queryByTestId": [Function], "queryByText": [Function], "queryByTitle": [Function], "rerender": [Function], "unmount": [Function], } `); }); it('should not render true/false additionalProperties', () => { const schema: JSONSchema7 = { type: 'object', properties: { id: { type: 'string', }, }, additionalProperties: true, }; const additionalTrue = render(); const additionalFalse = render( , ); expect(additionalTrue.container.firstChild).toEqual(additionalFalse.container.firstChild); expect(additionalTrue.container.firstChild).toMatchInlineSnapshot(` id string `); }); it('should not render additionalItems', () => { const schema: JSONSchema7 = { type: 'array', additionalItems: { type: 'object', properties: { id: { type: 'string', }, }, }, }; expect(render()).toMatchInlineSnapshot(` { "asFragment": [Function], "baseElement": array , "container": array , "debug": [Function], "findAllByAltText": [Function], "findAllByDisplayValue": [Function], "findAllByLabelText": [Function], "findAllByPlaceholderText": [Function], "findAllByRole": [Function], "findAllByTestId": [Function], "findAllByText": [Function], "findAllByTitle": [Function], "findByAltText": [Function], "findByDisplayValue": [Function], "findByLabelText": [Function], "findByPlaceholderText": [Function], "findByRole": [Function], "findByTestId": [Function], "findByText": [Function], "findByTitle": [Function], "getAllByAltText": [Function], "getAllByDisplayValue": [Function], "getAllByLabelText": [Function], "getAllByPlaceholderText": [Function], "getAllByRole": [Function], "getAllByTestId": [Function], "getAllByText": [Function], "getAllByTitle": [Function], "getByAltText": [Function], "getByDisplayValue": [Function], "getByLabelText": [Function], "getByPlaceholderText": [Function], "getByRole": [Function], "getByTestId": [Function], "getByText": [Function], "getByTitle": [Function], "queryAllByAltText": [Function], "queryAllByDisplayValue": [Function], "queryAllByLabelText": [Function], "queryAllByPlaceholderText": [Function], "queryAllByRole": [Function], "queryAllByTestId": [Function], "queryAllByText": [Function], "queryAllByTitle": [Function], "queryByAltText": [Function], "queryByDisplayValue": [Function], "queryByLabelText": [Function], "queryByPlaceholderText": [Function], "queryByRole": [Function], "queryByTestId": [Function], "queryByText": [Function], "queryByTitle": [Function], "rerender": [Function], "unmount": [Function], } `); }); describe('top level descriptions', () => { const schema: JSONSchema4 = { description: 'This is a description that should be rendered', allOf: [ { type: 'object', properties: { foo: { type: 'string', }, }, }, { type: 'object', properties: { baz: { type: 'string', }, }, }, ], }; it('should render top-level description on allOf', () => { expect( render().container.firstChild, ).toMatchSnapshot(); }); it('should not render top-level description when skipTopLevelDescription=true', () => { expect( render().container .firstChild, ).toMatchSnapshot(); }); }); }); describe.each([{}, { unknown: '' }, { $ref: null }])('given empty schema: %o', schema => { it('should render empty text', () => { const wrapper = render(); const emptyText = wrapper.queryAllByTestId('empty-text'); expect(emptyText[0]).toBeInTheDocument(); }); }); describe('Expanded depth', () => { describe('merged array with object', () => { let schema: JSONSchema4; beforeEach(() => { schema = { type: 'array', items: { type: 'object', properties: { foo: { type: 'array', items: { type: 'object', properties: { bar: { type: 'object', properties: { baz: { type: 'integer', }, }, }, }, }, }, }, }, }; }); describe('static', () => { it('given initial level set to -1, should render only top-level property', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchInlineSnapshot(` array of: foo array[object] `); }); it('given initial level set to 0, should render top 2 levels', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchInlineSnapshot(` array of: foo array[object] `); }); it('given initial level set to 1, should render top 3 levels', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchInlineSnapshot(` array of: foo array[object] bar object `); }); }); }); describe('merged array with object #2', () => { let schema: JSONSchema4; beforeEach(() => { schema = { type: 'array', items: { type: 'object', properties: { bar: { type: 'integer', }, foo: { type: 'array', items: { type: 'object', properties: { bar: { type: 'string', }, foo: { type: 'number', }, }, }, }, }, }, }; }); describe('static', () => { it('given initial level set to -1, should render only top-level property', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchInlineSnapshot(` array of: bar integer foo array[object] `); }); it('given initial level set to 0, should render top 2 levels', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchInlineSnapshot(` array of: bar integer foo array[object] `); }); it('given initial level set to 1, should render top 3 levels', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchInlineSnapshot(` array of: bar integer foo array[object] bar string foo number `); }); }); }); describe('nested object', () => { let schema: JSONSchema4; beforeEach(() => { schema = { type: 'object', properties: { bar: { type: 'object', properties: { barFoo: { type: 'object', properties: { barFooBar: { type: 'object', }, }, }, barBar: { type: 'string', }, barBaz: { type: 'boolean', }, }, }, foo: { type: 'array', items: { type: 'object', properties: { fooBar: { type: 'string', }, fooFoo: { type: 'number', }, }, }, }, }, }; }); describe('static', () => { it('given initial level set to -1, should render only top-level property', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchInlineSnapshot(` bar object foo array[object] `); }); it('given initial level set to 0, should render top 2 levels', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchSnapshot(); }); it('given initial level set to 1, should render top 3 levels', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchSnapshot(); }); it('given initial level set to 2, should render top 4 levels', () => { const wrapper = render(); expect(wrapper.container.firstChild).toMatchSnapshot(); }); }); }); }); describe('$ref resolving', () => { it('should render caret for schema with top-level $ref pointing at complex type', () => { const schema: JSONSchema4 = { $ref: '#/definitions/foo', definitions: { foo: { type: 'string', }, }, }; expect(render()).toMatchInlineSnapshot(` { "asFragment": [Function], "baseElement": string , "container": string , "debug": [Function], "findAllByAltText": [Function], "findAllByDisplayValue": [Function], "findAllByLabelText": [Function], "findAllByPlaceholderText": [Function], "findAllByRole": [Function], "findAllByTestId": [Function], "findAllByText": [Function], "findAllByTitle": [Function], "findByAltText": [Function], "findByDisplayValue": [Function], "findByLabelText": [Function], "findByPlaceholderText": [Function], "findByRole": [Function], "findByTestId": [Function], "findByText": [Function], "findByTitle": [Function], "getAllByAltText": [Function], "getAllByDisplayValue": [Function], "getAllByLabelText": [Function], "getAllByPlaceholderText": [Function], "getAllByRole": [Function], "getAllByTestId": [Function], "getAllByText": [Function], "getAllByTitle": [Function], "getByAltText": [Function], "getByDisplayValue": [Function], "getByLabelText": [Function], "getByPlaceholderText": [Function], "getByRole": [Function], "getByTestId": [Function], "getByText": [Function], "getByTitle": [Function], "queryAllByAltText": [Function], "queryAllByDisplayValue": [Function], "queryAllByLabelText": [Function], "queryAllByPlaceholderText": [Function], "queryAllByRole": [Function], "queryAllByTestId": [Function], "queryAllByText": [Function], "queryAllByTitle": [Function], "queryByAltText": [Function], "queryByDisplayValue": [Function], "queryByLabelText": [Function], "queryByPlaceholderText": [Function], "queryByRole": [Function], "queryByTestId": [Function], "queryByText": [Function], "queryByTitle": [Function], "rerender": [Function], "unmount": [Function], } `); }); it('should render caret for top-level array with $ref items', () => { const schema: JSONSchema4 = { type: 'array', items: { $ref: '#/foo', }, }; expect(render()).toMatchInlineSnapshot(` { "asFragment": [Function], "baseElement": $ref(#/foo)[] #/foo , "container": $ref(#/foo)[] #/foo , "debug": [Function], "findAllByAltText": [Function], "findAllByDisplayValue": [Function], "findAllByLabelText": [Function], "findAllByPlaceholderText": [Function], "findAllByRole": [Function], "findAllByTestId": [Function], "findAllByText": [Function], "findAllByTitle": [Function], "findByAltText": [Function], "findByDisplayValue": [Function], "findByLabelText": [Function], "findByPlaceholderText": [Function], "findByRole": [Function], "findByTestId": [Function], "findByText": [Function], "findByTitle": [Function], "getAllByAltText": [Function], "getAllByDisplayValue": [Function], "getAllByLabelText": [Function], "getAllByPlaceholderText": [Function], "getAllByRole": [Function], "getAllByTestId": [Function], "getAllByText": [Function], "getAllByTitle": [Function], "getByAltText": [Function], "getByDisplayValue": [Function], "getByLabelText": [Function], "getByPlaceholderText": [Function], "getByRole": [Function], "getByTestId": [Function], "getByText": [Function], "getByTitle": [Function], "queryAllByAltText": [Function], "queryAllByDisplayValue": [Function], "queryAllByLabelText": [Function], "queryAllByPlaceholderText": [Function], "queryAllByRole": [Function], "queryAllByTestId": [Function], "queryAllByText": [Function], "queryAllByTitle": [Function], "queryByAltText": [Function], "queryByDisplayValue": [Function], "queryByLabelText": [Function], "queryByPlaceholderText": [Function], "queryByRole": [Function], "queryByTestId": [Function], "queryByText": [Function], "queryByTitle": [Function], "rerender": [Function], "unmount": [Function], } `); }); });