chore: test fixes and simplify the types a little bit
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -27,6 +27,12 @@ import { analyticsApiRef } from '@backstage/core-plugin-api';
|
||||
import { ScaffolderApi, scaffolderApiRef } from '../../../api';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { SecretsContextProvider } from '../../../secrets';
|
||||
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { ScaffolderFormDecoratorsApi } from '../../../../../scaffolder/src/alpha/api/types';
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { formDecoratorsApiRef } from '../../../../../scaffolder/src/alpha/api/ref';
|
||||
|
||||
const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
|
||||
cancelTask: jest.fn(),
|
||||
@@ -39,14 +45,19 @@ const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
|
||||
listTasks: jest.fn(),
|
||||
autocomplete: jest.fn(),
|
||||
};
|
||||
const scaffolderDecoratorsMock: jest.Mocked<ScaffolderFormDecoratorsApi> = {
|
||||
getFormDecorators: jest.fn().mockResolvedValue([]),
|
||||
};
|
||||
|
||||
const catalogApi = catalogApiMock.mock();
|
||||
|
||||
const analyticsMock = mockApis.analytics();
|
||||
const apis = TestApiRegistry.from(
|
||||
[scaffolderApiRef, scaffolderApiMock],
|
||||
[formDecoratorsApiRef, scaffolderDecoratorsMock],
|
||||
[catalogApiRef, catalogApi],
|
||||
[analyticsApiRef, analyticsMock],
|
||||
[catalogApiRef, catalogApi],
|
||||
);
|
||||
|
||||
describe('<Workflow />', () => {
|
||||
@@ -82,31 +93,33 @@ describe('<Workflow />', () => {
|
||||
});
|
||||
|
||||
const { getByRole, getAllByRole, getByText } = await renderInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
<Workflow
|
||||
title="Different title than template"
|
||||
description={`
|
||||
<SecretsContextProvider initialSecrets={{}}>
|
||||
<ApiProvider apis={apis}>
|
||||
<Workflow
|
||||
title="Different title than template"
|
||||
description={`
|
||||
## This is markdown
|
||||
- overriding the template description
|
||||
`}
|
||||
onCreate={onCreate}
|
||||
onError={onError}
|
||||
namespace="default"
|
||||
templateName="docs-template"
|
||||
initialState={{
|
||||
name: 'prefilled-name',
|
||||
age: '53',
|
||||
}}
|
||||
components={{
|
||||
ReviewStateComponent: () => (
|
||||
<h1>This is a different wrapper for the review page</h1>
|
||||
),
|
||||
reviewButtonText: <i>Onwards</i>,
|
||||
createButtonText: <b>Make</b>,
|
||||
}}
|
||||
extensions={[]}
|
||||
/>
|
||||
</ApiProvider>,
|
||||
onCreate={onCreate}
|
||||
onError={onError}
|
||||
namespace="default"
|
||||
templateName="docs-template"
|
||||
initialState={{
|
||||
name: 'prefilled-name',
|
||||
age: '53',
|
||||
}}
|
||||
components={{
|
||||
ReviewStateComponent: () => (
|
||||
<h1>This is a different wrapper for the review page</h1>
|
||||
),
|
||||
reviewButtonText: <i>Onwards</i>,
|
||||
createButtonText: <b>Make</b>,
|
||||
}}
|
||||
extensions={[]}
|
||||
/>
|
||||
</ApiProvider>
|
||||
</SecretsContextProvider>,
|
||||
);
|
||||
|
||||
// Test template title is overriden
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import {
|
||||
Content,
|
||||
InfoCard,
|
||||
@@ -90,11 +90,10 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => {
|
||||
const minutesSaved = useTemplateTimeSavedMinutes(templateRef);
|
||||
const { setSecrets } = useInternalTemplateSecrets();
|
||||
const formDecorators = useFormDecorators();
|
||||
const [formState, setFormState] = useState<Record<string, JsonValue>>({});
|
||||
|
||||
const workflowOnCreate = useCallback(
|
||||
async (originalFormState: Record<string, JsonValue>) => {
|
||||
setFormState(originalFormState);
|
||||
let formState: Record<string, JsonValue> = { ...originalFormState };
|
||||
|
||||
if (manifest?.EXPERIMENTAL_formDecorators && formDecorators?.size) {
|
||||
// for each of the form decorators, go and call the decorator with the context
|
||||
@@ -109,7 +108,13 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => {
|
||||
|
||||
await formDecorator.fn({
|
||||
setSecrets,
|
||||
setFormState,
|
||||
setFormState: (
|
||||
handler: (
|
||||
oldState: Record<string, JsonValue>,
|
||||
) => Record<string, JsonValue>,
|
||||
) => {
|
||||
formState = { ...handler(formState) };
|
||||
},
|
||||
formState,
|
||||
input: decorator.input,
|
||||
});
|
||||
@@ -129,7 +134,6 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => {
|
||||
manifest?.EXPERIMENTAL_formDecorators,
|
||||
formDecorators,
|
||||
onCreate,
|
||||
formState,
|
||||
analytics,
|
||||
templateName,
|
||||
minutesSaved,
|
||||
|
||||
@@ -23,7 +23,14 @@ describe('createScaffolderFormDecorator', () => {
|
||||
fn: async () => {},
|
||||
});
|
||||
|
||||
expect(decorator).toMatchInlineSnapshot();
|
||||
expect(decorator).toMatchInlineSnapshot(`
|
||||
{
|
||||
"deps": {},
|
||||
"fn": [Function],
|
||||
"id": "test",
|
||||
"version": "v1",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should allow passing schema and be typesafe', () => {
|
||||
@@ -46,6 +53,19 @@ describe('createScaffolderFormDecorator', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(decorator).toMatchInlineSnapshot();
|
||||
expect(decorator).toMatchInlineSnapshot(`
|
||||
{
|
||||
"deps": {},
|
||||
"fn": [Function],
|
||||
"id": "test",
|
||||
"schema": {
|
||||
"input": {
|
||||
"age": [Function],
|
||||
"name": [Function],
|
||||
},
|
||||
},
|
||||
"version": "v1",
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,15 +15,18 @@
|
||||
*/
|
||||
import { AnyApiRef } from '@backstage/core-plugin-api';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { z } from 'zod';
|
||||
|
||||
export type ScaffolderFormDecoratorContext<TInput> = {
|
||||
input: TInput;
|
||||
formState: Record<string, JsonValue>;
|
||||
|
||||
setFormState: Dispatch<SetStateAction<Record<string, JsonValue>>>;
|
||||
setSecrets: Dispatch<SetStateAction<Record<string, string>>>;
|
||||
setFormState: (
|
||||
fn: (currentState: Record<string, JsonValue>) => Record<string, JsonValue>,
|
||||
) => void;
|
||||
setSecrets: (
|
||||
fn: (currentState: Record<string, string>) => Record<string, string>,
|
||||
) => void;
|
||||
};
|
||||
|
||||
export type ScaffolderFormDecorator<
|
||||
|
||||
Reference in New Issue
Block a user