From 55af83a78a9ce8c0591728c2fec13dbdd2d39e9a Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Thu, 29 Oct 2020 14:33:09 +0530 Subject: [PATCH] chore: move entityClient to createPlugin, mock entityClient in tests --- packages/backend/src/plugins/scaffolder.ts | 6 ++ plugins/scaffolder-backend/src/index.ts | 1 + .../src/service/router.test.ts | 91 ++++++++++--------- .../scaffolder-backend/src/service/router.ts | 5 +- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index 6eacd143c1..5d36d508a5 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -21,7 +21,9 @@ import { Publishers, CreateReactAppTemplater, Templaters, + CatalogEntityClient, } from '@backstage/plugin-scaffolder-backend'; +import { SingleHostDiscovery } from '@backstage/backend-common'; import type { PluginEnvironment } from '../types'; import Docker from 'dockerode'; @@ -40,6 +42,9 @@ export default async function createPlugin({ const dockerClient = new Docker(); + const discovery = SingleHostDiscovery.fromConfig(config); + const entityClient = new CatalogEntityClient({ discovery }); + return await createRouter({ preparers, templaters, @@ -47,5 +52,6 @@ export default async function createPlugin({ logger, config, dockerClient, + entityClient, }); } diff --git a/plugins/scaffolder-backend/src/index.ts b/plugins/scaffolder-backend/src/index.ts index c461bfede6..28e6a2b24c 100644 --- a/plugins/scaffolder-backend/src/index.ts +++ b/plugins/scaffolder-backend/src/index.ts @@ -16,3 +16,4 @@ export * from './scaffolder'; export * from './service/router'; +export * from './lib/catalog'; diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index fae7ee8beb..c2b60a2040 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -35,6 +35,10 @@ import Docker from 'dockerode'; jest.mock('dockerode'); +const generateEntityClient: any = (template: any) => ({ + findTemplate: () => Promise.resolve(template), +}); + describe('createRouter - working directory', () => { const mockPrepare = jest.fn(); const mockPreparers = new Preparers(); @@ -74,6 +78,8 @@ describe('createRouter - working directory', () => { }, }; + const mockedEntityClient = generateEntityClient(template); + it('should throw an error when working directory does not exist or is not writable', async () => { mockAccess.mockImplementation(() => { throw new Error('access error'); @@ -87,6 +93,7 @@ describe('createRouter - working directory', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([workDirConfig('/path')]), dockerClient: new Docker(), + entityClient: mockedEntityClient, }), ).rejects.toThrow('access error'); }); @@ -99,11 +106,12 @@ describe('createRouter - working directory', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([workDirConfig('/path')]), dockerClient: new Docker(), + entityClient: mockedEntityClient, }); const app = express().use(router); await request(app).post('/v1/jobs').send({ - template, + templateName: '', values: {}, }); @@ -121,11 +129,12 @@ describe('createRouter - working directory', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([]), dockerClient: new Docker(), + entityClient: mockedEntityClient, }); const app = express().use(router); await request(app).post('/v1/jobs').send({ - template, + templateName: '', values: {}, }); @@ -137,6 +146,43 @@ describe('createRouter - working directory', () => { describe('createRouter', () => { let app: express.Express; + const template = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Template', + metadata: { + description: 'Create a new CRA website project', + name: 'create-react-app-template', + tags: ['experimental', 'react', 'cra'], + title: 'Create React App Template', + }, + spec: { + owner: 'web@example.com', + path: '.', + schema: { + properties: { + component_id: { + description: 'Unique name of the component', + title: 'Name', + type: 'string', + }, + description: { + description: 'Description of the component', + title: 'Description', + type: 'string', + }, + use_typescript: { + default: true, + description: 'Include typescript', + title: 'Use Typescript', + type: 'boolean', + }, + }, + required: ['component_id', 'use_typescript'], + }, + templater: 'cra', + type: 'website', + }, + }; beforeAll(async () => { const router = await createRouter({ @@ -146,6 +192,7 @@ describe('createRouter', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([]), dockerClient: new Docker(), + entityClient: generateEntityClient(template), }); app = express().use(router); }); @@ -155,47 +202,9 @@ describe('createRouter', () => { }); describe('POST /v1/jobs', () => { - const template = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Template', - metadata: { - description: 'Create a new CRA website project', - name: 'create-react-app-template', - tags: ['experimental', 'react', 'cra'], - title: 'Create React App Template', - }, - spec: { - owner: 'web@example.com', - path: '.', - schema: { - properties: { - component_id: { - description: 'Unique name of the component', - title: 'Name', - type: 'string', - }, - description: { - description: 'Description of the component', - title: 'Description', - type: 'string', - }, - use_typescript: { - default: true, - description: 'Include typescript', - title: 'Use Typescript', - type: 'boolean', - }, - }, - required: ['component_id', 'use_typescript'], - }, - templater: 'cra', - type: 'website', - }, - }; - it('rejects template values which do not match the template schema definition', async () => { const response = await request(app).post('/v1/jobs').send({ - template, + templateName: '', values: {}, }); diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index efe8ee46f6..e4d3d5c45a 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { SingleHostDiscovery } from '@backstage/backend-common'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import { Config, JsonValue } from '@backstage/config'; import fs from 'fs-extra'; @@ -41,6 +40,7 @@ export interface RouterOptions { logger: Logger; config: Config; dockerClient: Docker; + entityClient: CatalogEntityClient; } export async function createRouter( @@ -56,13 +56,12 @@ export async function createRouter( logger: parentLogger, config, dockerClient, + entityClient, } = options; const logger = parentLogger.child({ plugin: 'scaffolder' }); const jobProcessor = new JobProcessor(); - const discovery = SingleHostDiscovery.fromConfig(config); - const entityClient = new CatalogEntityClient({ discovery }); let workingDirectory: string; if (config.has('backend.workingDirectory')) { workingDirectory = config.getString('backend.workingDirectory');