chore: added some test for checking that the workflow passes through the user

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2022-05-04 14:42:33 +02:00
parent d06a045a68
commit 277634feb0
3 changed files with 47 additions and 104 deletions
@@ -24,6 +24,7 @@ import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { TaskContext, TaskSecrets } from './types';
import { TaskSpec } from '@backstage/plugin-scaffolder-common';
import { UserEntity } from '@backstage/catalog-model';
// The Stream module is lazy loaded, so make sure it's in the module cache before mocking fs
void winston.transports.Stream;
@@ -558,8 +559,8 @@ describe('DefaultWorkflowRunner', () => {
});
});
describe('filters', () => {
it('provides the parseRepoUrl filter', async () => {
describe('user', () => {
it('allows access to the user entity at the templating level', async () => {
const task = createMockTaskWithSpec({
apiVersion: 'scaffolder.backstage.io/v1beta3',
steps: [
@@ -587,4 +588,34 @@ describe('DefaultWorkflowRunner', () => {
});
});
});
describe('filters', () => {
it('provides the parseRepoUrl filter', async () => {
const task = createMockTaskWithSpec({
apiVersion: 'scaffolder.backstage.io/v1beta3',
steps: [
{
id: 'test',
name: 'name',
action: 'output-action',
input: {},
},
],
user: {
entity: { metadata: { name: 'bob' } } as UserEntity,
ref: 'user:default/guest',
},
output: {
foo: '${{ user.entity.metadata.name }} ${{ user.ref }}',
},
parameters: {
repoUrl: 'github.com?repo=repo&owner=owner',
},
});
const { output } = await runner.execute(task);
expect(output.foo).toEqual('bob user:default/guest');
});
});
});
+14
View File
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { UserEntity } from '@backstage/catalog-model';
import { JsonValue, JsonObject } from '@backstage/types';
/**
@@ -91,6 +92,19 @@ export interface TaskSpecV1beta3 {
* Some information about the template that is stored on the task spec.
*/
templateInfo?: TemplateInfo;
/**
* Some decoration of the author of the task that should be available in the context
*/
user?: {
/**
* The decorated entity from the Catalog
*/
entity?: UserEntity;
/**
* An entity ref for the author of the task
*/
ref?: string;
};
}
/**
@@ -1,102 +0,0 @@
/*
* 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 {
Stepper as MuiStepper,
Step as MuiStep,
StepLabel as MuiStepLabel,
Button,
makeStyles,
} from '@material-ui/core';
import { withTheme } from '@rjsf/core';
import { Theme as MuiTheme } from '@rjsf/material-ui';
import React, { useMemo, useState } from 'react';
import { FieldExtensionOptions } from '../../../extensions';
import { TemplateParameterSchema } from '../../../types';
import { useTemplateSchema } from './useTemplateSchema';
const useStyles = makeStyles(theme => ({
backButton: {
marginRight: theme.spacing(1),
},
footer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'right',
},
formWrapper: {
padding: theme.spacing(2),
},
}));
export interface StepperProps {
manifest: TemplateParameterSchema;
extensions: FieldExtensionOptions<any, any>[];
}
const Form = withTheme(MuiTheme);
export const Stepper = (props: StepperProps) => {
const { steps } = useTemplateSchema(props.manifest);
const [activeStep, setActiveStep] = useState(0);
const styles = useStyles();
const extensions = useMemo(() => {
return Object.fromEntries(
props.extensions.map(({ name, component }) => [name, component]),
);
}, [props.extensions]);
const handleBack = () => {
setActiveStep(prevActiveStep => prevActiveStep - 1);
};
const handleNext = () => {
setActiveStep(prevActiveStep => prevActiveStep + 1);
};
return (
<>
<MuiStepper activeStep={activeStep} alternativeLabel variant="elevation">
{steps.map((step, index) => (
<MuiStep key={index}>
<MuiStepLabel>{step.title}</MuiStepLabel>
</MuiStep>
))}
</MuiStepper>
<div className={styles.formWrapper}>
<Form
schema={steps[activeStep].schema}
uiSchema={steps[activeStep].uiSchema}
onSubmit={handleNext}
fields={extensions}
showErrorList={false}
>
<div className={styles.footer}>
<Button
onClick={handleBack}
className={styles.backButton}
disabled={activeStep < 1}
>
Back
</Button>
<Button variant="contained" color="primary" type="submit">
{activeStep === steps.length - 1 ? 'Review' : 'Next'}
</Button>
</div>
</Form>
</div>
</>
);
};