From 5b7f8fb4423f107ed69024b7517dbfa9c2c2feb5 Mon Sep 17 00:00:00 2001 From: blam Date: Thu, 23 Jun 2022 14:02:53 +0200 Subject: [PATCH] chore: saving state in the form Signed-off-by: blam --- .../Stepper/Stepper.test.tsx | 136 ++++++++++++++++++ .../TemplateWizardPage/Stepper/Stepper.tsx | 7 +- 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx new file mode 100644 index 0000000000..2b091883ae --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx @@ -0,0 +1,136 @@ +/* + * 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 React from 'react'; +import { TemplateParameterSchema } from '../../../types'; +import { Stepper } from './Stepper'; +import { renderInTestApp } from '@backstage/test-utils'; +import { fireEvent } from '@testing-library/react'; + +describe('Stepper', () => { + it('should render the step titles for each step of the manifest', async () => { + const manifest: TemplateParameterSchema = { + steps: [ + { title: 'Step 1', schema: { properties: {} } }, + { title: 'Step 2', schema: { properties: {} } }, + ], + title: 'React JSON Schema Form Test', + }; + + const { getByText } = await renderInTestApp( + , + ); + + for (const step of manifest.steps) { + expect(getByText(step.title)).toBeInTheDocument(); + } + }); + + it('should render next / review button', async () => { + const manifest: TemplateParameterSchema = { + steps: [ + { title: 'Step 1', schema: { properties: {} } }, + { title: 'Step 2', schema: { properties: {} } }, + ], + title: 'React JSON Schema Form Test', + }; + + const { getByText } = await renderInTestApp( + , + ); + + expect(getByText('Next')).toBeInTheDocument(); + + await fireEvent.click(getByText('Next')); + + expect(getByText('Review')).toBeInTheDocument(); + }); + + it('should remember the state of the form when cycling through the pages', async () => { + const manifest: TemplateParameterSchema = { + steps: [ + { + title: 'Step 1', + schema: { + properties: { + name: { + type: 'string', + }, + }, + }, + }, + { + title: 'Step 2', + schema: { + properties: { + description: { + type: 'string', + }, + }, + }, + }, + ], + title: 'React JSON Schema Form Test', + }; + + const { getByRole, getByText } = await renderInTestApp( + , + ); + + await fireEvent.change(getByRole('textbox', { name: 'name' }), { + target: { value: 'im a test value' }, + }); + + await fireEvent.click(getByText('Next')); + + await fireEvent.click(getByText('Back')); + + expect(getByRole('textbox', { name: 'name' })).toHaveValue( + 'im a test value', + ); + }); + + it('should render custom field extensions properly', async () => { + const MockComponent = () => { + return

im a custom field extension

; + }; + + const manifest: TemplateParameterSchema = { + title: 'Custom Fields', + steps: [ + { + title: 'Test', + schema: { + properties: { + name: { + type: 'string', + 'ui:field': 'Mock', + }, + }, + }, + }, + ], + }; + + const { getByText } = await renderInTestApp( + , + ); + + expect(getByText('im a custom field extension')).toBeInTheDocument(); + }); +}); diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx index f864e9ee09..19335d4993 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { JsonObject } from '@backstage/types'; import { Stepper as MuiStepper, Step as MuiStep, @@ -51,6 +52,7 @@ const Form = withTheme(MuiTheme); export const Stepper = (props: StepperProps) => { const { steps } = useTemplateSchema(props.manifest); const [activeStep, setActiveStep] = useState(0); + const [formState, setFormState] = useState({}); const styles = useStyles(); const extensions = useMemo(() => { @@ -62,8 +64,10 @@ export const Stepper = (props: StepperProps) => { const handleBack = () => { setActiveStep(prevActiveStep => prevActiveStep - 1); }; - const handleNext = () => { + + const handleNext = ({ formData }: { formData: JsonObject }) => { setActiveStep(prevActiveStep => prevActiveStep + 1); + setFormState(current => ({ ...current, ...formData })); }; return ( @@ -77,6 +81,7 @@ export const Stepper = (props: StepperProps) => {