From b965a83a1f0134250a1d3e585f83664992ea194b Mon Sep 17 00:00:00 2001 From: Paul Cowan Date: Thu, 12 Jan 2023 17:02:21 +0000 Subject: [PATCH] add tests to scaffoler-react Signed-off-by: Paul Cowan --- plugins/scaffolder-react/package.json | 2 +- .../components/ReviewState/ReviewState.tsx | 2 +- .../next/components/Stepper/Stepper.test.tsx | 38 ++++++ .../src/next/components/Stepper/Stepper.tsx | 9 +- .../components/Workflow/Workflow.test.tsx | 116 ++++++++++++++++++ .../src/next/components/Workflow/Workflow.tsx | 2 +- yarn.lock | 1 + 7 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index d08edb75fb..e44a1d94ee 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -57,8 +57,8 @@ "json-schema": "^0.4.0", "json-schema-library": "^7.3.9", "lodash": "^4.17.21", - "react-use": "^17.2.4", "qs": "^6.9.4", + "react-use": "^17.2.4", "zen-observable": "^0.10.0", "zod": "~3.18.0", "zod-to-json-schema": "~3.18.0" diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index 11fb28b29c..56abc52469 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -26,7 +26,7 @@ import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; export interface ReviewStateProps { schemas: ParsedTemplateSchema[]; formState: JsonObject; -}; +} /** * The component used by the {@link Stepper} to render the review step. diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx index 786f45b05d..e460afbdfc 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx @@ -352,4 +352,42 @@ describe('Stepper', () => { // flush promises return new Promise(process.nextTick); }); + + it('should override the Create and Review button text', async () => { + const manifest: TemplateParameterSchema = { + title: 'Custom Fields', + steps: [ + { + title: 'Test', + schema: { + properties: { + name: { + type: 'string', + }, + }, + }, + }, + ], + }; + + const { getByRole } = await renderInTestApp( + , + ); + + await act(async () => { + await fireEvent.click(getByRole('button', { name: 'Inspect' })); + }); + + expect(getByRole('button', { name: 'Make' })).toBeInTheDocument(); + + await act(async () => { + await fireEvent.click(getByRole('button', { name: 'Make' })); + }); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 6bd3ec8c71..5d0ad29513 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -61,8 +61,9 @@ export type StepperProps = { initialState?: Record; onComplete: (values: Record) => Promise; - initialFormState?: Record; ReviewStateWrapper?: (props: ReviewStateProps) => JSX.Element; + createButtonText?: string; + reviewButtonText?: string; }; // TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly @@ -77,6 +78,8 @@ const Form = withTheme(require('@rjsf/material-ui-v5').Theme); export const Stepper = ({ ReviewStateWrapper = ReviewState, + createButtonText = 'Create', + reviewButtonText = 'Review', ...props }: StepperProps) => { const analytics = useAnalytics(); @@ -182,7 +185,7 @@ export const Stepper = ({ Back @@ -211,7 +214,7 @@ export const Stepper = ({ ); }} > - Create + {createButtonText} diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx new file mode 100644 index 0000000000..8be6d58407 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx @@ -0,0 +1,116 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiProvider } from '@backstage/core-app-api'; +import { + MockAnalyticsApi, + renderInTestApp, + TestApiRegistry, +} from '@backstage/test-utils'; +import { act, fireEvent } from '@testing-library/react'; +import React from 'react'; +import { Workflow } from './Workflow'; +import { analyticsApiRef } from '@backstage/core-plugin-api'; +import { ScaffolderApi } from '../../../api/types'; +import { scaffolderApiRef } from '../../../api/ref'; + +const scaffolderApiMock: jest.Mocked = { + scaffold: jest.fn(), + getTemplateParameterSchema: jest.fn(), + getIntegrationsList: jest.fn(), + getTask: jest.fn(), + streamLogs: jest.fn(), + listActions: jest.fn(), + listTasks: jest.fn(), +}; + +const analyticsMock = new MockAnalyticsApi(); +const apis = TestApiRegistry.from( + [scaffolderApiRef, scaffolderApiMock], + [analyticsApiRef, analyticsMock], +); + +describe('', () => { + it('should complete a workflow', async () => { + const onComplete = jest.fn(); + const onError = jest.fn(); + scaffolderApiMock.scaffold.mockResolvedValue({ taskId: 'xyz' }); + + scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ + steps: [ + { + title: 'Step 1', + schema: { + properties: { + name: { + type: 'string', + }, + }, + }, + }, + ], + title: 'React JSON Schema Form Test', + }); + + const { getByRole, getAllByRole, getByText } = await renderInTestApp( + + ( +

This is a different wrapper for the review page

+ )} + customFieldExtensions={[]} + /> +
, + ); + + // Test template title is overriden + expect(getByRole('heading', { level: 2 }).innerHTML).toBe( + 'Different title than template', + ); + + const input = getByRole('textbox') as HTMLInputElement; + + expect(input).toBeInTheDocument(); + + expect(input.value).toBe('prefilled-name'); + + await act(async () => { + fireEvent.click(getByRole('button', { name: 'Review' })); + }); + + expect( + getByText('This is a different wrapper for the review page'), + ).toBeDefined(); + + await act(async () => { + fireEvent.click(getAllByRole('button')[1] as HTMLButtonElement); + }); + + expect(onComplete).toHaveBeenCalledWith({ name: 'prefilled-name' }); + }); +}); diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx index 783c504cc8..095ff49fe8 100644 --- a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx @@ -113,7 +113,7 @@ export const Workflow = ({ extensions={props.customFieldExtensions} onComplete={props.onComplete} FormProps={FormProps} - initialFormState={props.initialFormState} + initialState={props.initialFormState} ReviewStateWrapper={ReviewStateWrapper} /> diff --git a/yarn.lock b/yarn.lock index f8df88cb37..6a6a81f40b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7459,6 +7459,7 @@ __metadata: json-schema-library: ^7.3.9 lodash: ^4.17.21 qs: ^6.9.4 + react-use: ^17.2.4 zen-observable: ^0.10.0 zod: ~3.18.0 zod-to-json-schema: ~3.18.0