diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx index cc789d8ea9..462c162970 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx @@ -90,12 +90,9 @@ describe('ActionsPage', () => { await screen.findByRole('row', { name: /test/ }), ).toBeInTheDocument(); - expect(screen.queryByText('Test title')).not.toBeInTheDocument(); - await selectAction('test'); - expect(await screen.findByText('Test title')).toBeInTheDocument(); - expect(screen.getByText('foobar *')).toBeInTheDocument(); + expect(await screen.findByText('foobar *')).toBeInTheDocument(); }); it('renders action with input and output on row click', async () => { @@ -139,9 +136,8 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('Test title')).toBeInTheDocument(); - expect(screen.getByText('foobar *')).toBeInTheDocument(); - expect(screen.getByText('Test output')).toBeInTheDocument(); + expect(await screen.findByText('foobar *')).toBeInTheDocument(); + expect(screen.getByText('buzz')).toBeInTheDocument(); }); it('renders action with oneOf output on row click', async () => { @@ -198,10 +194,10 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('oneOf')).toBeInTheDocument(); - expect(screen.getByText('Test title')).toBeInTheDocument(); - expect(screen.getByText('Test output1')).toBeInTheDocument(); - expect(screen.getByText('Test output2')).toBeInTheDocument(); + expect( + await screen.findByRole('button', { name: /oneOf/ }), + ).toBeInTheDocument(); + expect(screen.getByText('foobar *')).toBeInTheDocument(); }); it('renders action with multiple input types on row click', async () => { @@ -297,10 +293,16 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('oneOf')).toBeInTheDocument(); - expect(screen.getByText('Foo title')).toBeInTheDocument(); + const oneOfButton = await screen.findByRole('button', { name: /oneOf/ }); + expect(oneOfButton).toBeInTheDocument(); + + expect(screen.queryByText('foo *')).not.toBeInTheDocument(); + + await userEvent.click(oneOfButton); + + expect(await screen.findByText('foo *')).toBeInTheDocument(); expect(screen.getByText('Foo description')).toBeInTheDocument(); - expect(screen.getByText('Bar title')).toBeInTheDocument(); + expect(screen.getByText('bar *')).toBeInTheDocument(); expect(screen.getByText('Bar description')).toBeInTheDocument(); }); @@ -346,20 +348,17 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('Test object')).toBeInTheDocument(); - const objectButton = screen.getByRole('button', { name: /object/ }); + const objectButton = await screen.findByRole('button', { name: /object/ }); expect(objectButton).toBeInTheDocument(); - expect(screen.queryByText('nested prop a')).not.toBeInTheDocument(); expect(screen.queryByText(/^string$/)).not.toBeInTheDocument(); - expect(screen.queryByText('nested prop b')).not.toBeInTheDocument(); expect(screen.queryByText(/^number$/)).not.toBeInTheDocument(); await userEvent.click(objectButton); - expect(screen.queryByText('nested prop a')).toBeInTheDocument(); + expect(screen.queryByText('a')).toBeInTheDocument(); expect(screen.queryByText(/^string$/)).toBeInTheDocument(); - expect(screen.queryByText('nested prop b')).toBeInTheDocument(); + expect(screen.queryByText('b')).toBeInTheDocument(); expect(screen.queryByText(/^number$/)).toBeInTheDocument(); }); @@ -411,27 +410,20 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('Test object')).toBeInTheDocument(); - const objectButton = screen.getByRole('button', { name: /object/ }); + const objectButton = await screen.findByRole('button', { name: /object/ }); expect(objectButton).toBeInTheDocument(); - expect(screen.queryByText('nested object a')).not.toBeInTheDocument(); - expect(screen.queryByText('nested prop b')).not.toBeInTheDocument(); - expect(screen.queryByText('nested object c')).not.toBeInTheDocument(); - await userEvent.click(objectButton); - expect(screen.queryByText('nested object a')).toBeInTheDocument(); - expect(screen.queryByText('nested prop b')).toBeInTheDocument(); - expect(screen.queryByText('nested object c')).not.toBeInTheDocument(); + expect(screen.queryByText('a')).toBeInTheDocument(); + expect(screen.queryByText('b')).toBeInTheDocument(); + expect(screen.queryByText('c')).not.toBeInTheDocument(); const allObjectButtons = screen.getAllByRole('button', { name: /object/ }); expect(allObjectButtons.length).toBe(2); await userEvent.click(allObjectButtons[1]); - expect(screen.queryByText('nested object a')).toBeInTheDocument(); - expect(screen.queryByText('nested prop b')).toBeInTheDocument(); - expect(screen.queryByText('nested object c')).toBeInTheDocument(); + expect(screen.queryByText('c')).toBeInTheDocument(); }); it('renders action with object input type and no properties', async () => { @@ -466,8 +458,7 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('Test object')).toBeInTheDocument(); - const objectButton = screen.getByRole('button', { name: /object/ }); + const objectButton = await screen.findByRole('button', { name: /object/ }); expect(objectButton).toBeInTheDocument(); expect(screen.queryByText('No schema defined')).not.toBeInTheDocument(); @@ -511,8 +502,7 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('Test array')).toBeInTheDocument(); - expect(screen.getByText('array(string)')).toBeInTheDocument(); + expect(await screen.findByText('array(string)')).toBeInTheDocument(); }); it('renders action with array(object) input type', async () => { @@ -566,19 +556,17 @@ describe('ActionsPage', () => { await selectAction('test'); - expect(await screen.findByText('Test array')).toBeInTheDocument(); - const arrayButton = screen.getByRole('button', { + const arrayButton = await screen.findByRole('button', { name: /array\(object\)/, }); expect(arrayButton).toBeInTheDocument(); - expect(screen.queryByText('nested object a')).not.toBeInTheDocument(); - expect(screen.queryByText('nested prop b')).not.toBeInTheDocument(); + expect(screen.queryByText('b')).not.toBeInTheDocument(); await userEvent.click(arrayButton); - expect(screen.queryByText('nested object a')).toBeInTheDocument(); - expect(screen.queryByText('nested prop b')).toBeInTheDocument(); + expect(screen.queryByText('a')).toBeInTheDocument(); + expect(screen.queryByText('b')).toBeInTheDocument(); }); it('renders action with array input type and no items', async () => { diff --git a/plugins/scaffolder/src/components/RenderSchema/RenderSchema.test.tsx b/plugins/scaffolder/src/components/RenderSchema/RenderSchema.test.tsx index a5d7915482..0e13858d8c 100644 --- a/plugins/scaffolder/src/components/RenderSchema/RenderSchema.test.tsx +++ b/plugins/scaffolder/src/components/RenderSchema/RenderSchema.test.tsx @@ -26,7 +26,6 @@ import { JSONSchema7Definition, JSONSchema7Type, } from 'json-schema'; -import { capitalize } from 'lodash'; import { useState } from 'react'; import { Expanded, SchemaRenderStrategy } from '.'; import { RenderEnum, RenderSchema } from './RenderSchema'; @@ -136,8 +135,6 @@ describe('JSON schema UI rendering', () => { id: string, ) => { const { getByTestId, queryByTestId } = q; - const t = getByTestId(`properties_${id}`); - expect(t).toBeInTheDocument(); for (const p of Object.keys(basic.properties!)) { const tr = getByTestId(`properties-row_${id}.${p}`); @@ -152,7 +149,6 @@ describe('JSON schema UI rendering', () => { expect(cellTexts).toEqual( expect.arrayContaining([ expect.stringContaining(p), - expect.stringContaining(capitalize(p)), expect.stringContaining(`the ${pt}`), expect.stringContaining(String(pt)), ]), @@ -208,8 +204,6 @@ describe('JSON schema UI rendering', () => { id: string, ) => { const { findByTestId, getByTestId, queryByTestId } = q; - const t = getByTestId(`properties_${id}`); - expect(t).toBeInTheDocument(); const xp: (k: string) => Promise<{ expander: HTMLElement; @@ -396,13 +390,22 @@ describe('JSON schema UI rendering', () => { const rendered = await renderInTestApp( , ); - const { getByTestId } = rendered; + const { findByTestId, getByTestId, queryByTestId } = rendered; - for (const [i, k] of Object.keys(schema.properties!).entries()) { + for (const k of Object.keys(schema.properties!)) { const tr = getByTestId(`properties-row_test.${k}`); expect(tr).toBeInTheDocument(); + } - const sub = getByTestId(`properties-row_test_oneOf${i}.${k}`); + expect( + queryByTestId('properties-row_test_oneOf0.foo'), + ).not.toBeInTheDocument(); + + const expandOneOf = getByTestId('expand_test_oneOf'); + await userEvent.click(expandOneOf); + + for (const [i, k] of Object.keys(schema.properties!).entries()) { + const sub = await findByTestId(`properties-row_test_oneOf${i}.${k}`); expect(sub).toBeInTheDocument(); const nameCell = @@ -414,6 +417,14 @@ describe('JSON schema UI rendering', () => { getByTestId(`properties-row_test_oneOf${i}.${k}Flag`), ).toBeInTheDocument(); } + + await userEvent.click(expandOneOf); + + await waitFor(() => { + expect( + queryByTestId('properties-row_test_oneOf0.foo'), + ).not.toBeInTheDocument(); + }); }); it('full oneOf', async () => { const schema: JSONSchema7 = { @@ -450,11 +461,15 @@ describe('JSON schema UI rendering', () => { const rendered = await renderInTestApp( , ); + + const expandOneOf = rendered.getByTestId('expand_test_oneOf'); + await userEvent.click(expandOneOf); + const subs = schema.oneOf as JSONSchema7[]; for (const i of subs.keys()) { for (const k of Object.keys(subs[i].properties!)) { expect( - rendered.getByTestId(`properties-row_test_oneOf${i}.${k}`), + await rendered.findByTestId(`properties-row_test_oneOf${i}.${k}`), ).toBeInTheDocument(); } } @@ -477,11 +492,19 @@ describe('JSON schema UI rendering', () => { const rendered = await renderInTestApp( , ); + expect( - rendered.getByTestId(`root-row_test.bs_anyOf0`), + rendered.queryByTestId('root-row_test.bs_anyOf0'), + ).not.toBeInTheDocument(); + + const expandAnyOf = rendered.getByTestId('expand_test.bs_anyOf'); + await userEvent.click(expandAnyOf); + + expect( + await rendered.findByTestId('root-row_test.bs_anyOf0'), ).toBeInTheDocument(); expect( - rendered.getByTestId(`root-row_test.bs_anyOf1`), + rendered.getByTestId('root-row_test.bs_anyOf1'), ).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/components/RenderSchema/RenderSchema.tsx b/plugins/scaffolder/src/components/RenderSchema/RenderSchema.tsx index 4d5511876a..86da40d5e6 100644 --- a/plugins/scaffolder/src/components/RenderSchema/RenderSchema.tsx +++ b/plugins/scaffolder/src/components/RenderSchema/RenderSchema.tsx @@ -270,13 +270,6 @@ export const RenderSchema = ({ width: '1fr', }); } - if (schema.title) { - columns.unshift({ - key: 'title', - title: t('renderSchema.tableCell.title'), - render: renderTitleCell, - }); - } } } else if (schema.properties) { columns = [ @@ -285,11 +278,6 @@ export const RenderSchema = ({ title: t('renderSchema.tableCell.name'), render: renderNameCell, }, - { - key: 'title', - title: t('renderSchema.tableCell.title'), - render: renderTitleCell, - }, { key: 'description', title: t('renderSchema.tableCell.description'), @@ -310,117 +298,129 @@ export const RenderSchema = ({ } else if (!Object.keys(subschemas).length) { return undefined; } - const [isExpanded] = context.expanded; + const [isExpanded, setIsExpanded] = context.expanded; return ( - {columns && elements && ( - <> - - - {columns.map((col, index) => ( - - {col.title} - - ))} - - - {elements.map(el => { - const id = generateId(el, context); - return ( + {columns && + elements && + elements.map(el => { + const id = generateId(el, context); + const info = inspectSchema(el.schema); + const hasDetails = + typeof el.schema !== 'boolean' && + (info.canSubschema || info.hasEnum); + const s = + typeof el.schema !== 'boolean' + ? (el.schema as JSONSchema7) + : undefined; + const isOpen = + hasDetails && s && (!getTypes(s) || isExpanded[id]); + + return ( + + + + {columns.map((col, index) => ( + + {col.title} + + ))} + + {col => col.render(el, context)} - ); - })} - - - {elements.map(el => { - const id = generateId(el, context); - const info = inspectSchema(el.schema); - const hasDetails = - typeof el.schema !== 'boolean' && - (info.canSubschema || info.hasEnum); - if (!hasDetails || typeof el.schema === 'boolean') { - return null; - } - const s = el.schema as JSONSchema7; - const isOpen = !getTypes(s) || isExpanded[id]; - if (!isOpen) { - return null; - } - return ( -
- {info.canSubschema && ( - - )} - {info.hasEnum && ( - <> - - Valid values: - - + + {isOpen && ( +
+ {info.canSubschema && ( + - - )} -
- ); - })} - - )} - {(Object.keys(subschemas) as Array).map(sk => ( - - - {sk} - - {subschemas[sk]!.map((sub, index) => ( - + + Valid values: + + + + )} +
+ )} +
+ ); + })} + {(Object.keys(subschemas) as Array).map(sk => { + const subId = `${context.parentId}_${sk}`; + const isSubOpen = isExpanded[subId]; + return ( + + + {isSubOpen && + subschemas[sk]!.map((sub, index) => ( + + ))} + + ); + })}
); } @@ -437,14 +437,6 @@ function renderNameCell( return ; } -function renderTitleCell(element: SchemaRenderElement) { - return ( - - - - ); -} - function renderDescriptionCell(element: SchemaRenderElement) { return (