@@ -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(
|
||||
<Stepper manifest={manifest} extensions={[]} />,
|
||||
);
|
||||
|
||||
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(
|
||||
<Stepper manifest={manifest} extensions={[]} />,
|
||||
);
|
||||
|
||||
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(
|
||||
<Stepper manifest={manifest} extensions={[]} />,
|
||||
);
|
||||
|
||||
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 <h1>im a custom field extension</h1>;
|
||||
};
|
||||
|
||||
const manifest: TemplateParameterSchema = {
|
||||
title: 'Custom Fields',
|
||||
steps: [
|
||||
{
|
||||
title: 'Test',
|
||||
schema: {
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
'ui:field': 'Mock',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Stepper
|
||||
manifest={manifest}
|
||||
extensions={[{ name: 'Mock', component: MockComponent }]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(getByText('im a custom field extension')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -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) => {
|
||||
</MuiStepper>
|
||||
<div className={styles.formWrapper}>
|
||||
<Form
|
||||
formData={formState}
|
||||
schema={steps[activeStep].schema}
|
||||
uiSchema={steps[activeStep].uiSchema}
|
||||
onSubmit={handleNext}
|
||||
|
||||
Reference in New Issue
Block a user