From 082f1703f4e7d3ccf9095ff2b4dd89db5c38ff5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20A=CC=8Ahsberg?= Date: Mon, 4 Jan 2021 14:57:07 +0000 Subject: [PATCH] Use msw for mocking external Bitbucket apis --- .changeset/bitbucket-scaffolder.md | 2 +- plugins/scaffolder-backend/package.json | 4 +- .../stages/prepare/bitbucket.test.ts | 2 +- .../scaffolder/stages/prepare/bitbucket.ts | 2 +- .../scaffolder/stages/prepare/preparers.ts | 2 +- .../stages/publish/bitbucket.test.ts | 96 +++++++++++-------- .../scaffolder/stages/publish/publishers.ts | 2 +- .../src/scaffolder/stages/types.ts | 2 +- 8 files changed, 66 insertions(+), 46 deletions(-) diff --git a/.changeset/bitbucket-scaffolder.md b/.changeset/bitbucket-scaffolder.md index 908bcd7e2b..e1e6f17b29 100644 --- a/.changeset/bitbucket-scaffolder.md +++ b/.changeset/bitbucket-scaffolder.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-scaffolder-backend': minor +'@backstage/plugin-scaffolder-backend': patch --- Add scaffolding support for Bitbucket Cloud and Server. diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 1a443ceb7c..c290a94b19 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -59,12 +59,14 @@ }, "devDependencies": { "@backstage/cli": "^0.4.3", + "@backstage/test-utils": "^0.1.5", "@octokit/types": "^5.4.1", "@types/fs-extra": "^9.0.1", "@types/git-url-parse": "^9.0.0", "@types/supertest": "^2.0.8", "supertest": "^4.0.2", - "yaml": "^1.10.0" + "yaml": "^1.10.0", + "msw": "^0.21.2" }, "files": [ "dist", diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.test.ts b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.test.ts index 143e1e0990..809d18c808 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.test.ts @@ -44,7 +44,7 @@ describe('BitbucketPreparer', () => { metadata: { annotations: { [LOCATION_ANNOTATION]: - 'bitbucket/api:https://bitbucket.org/backstage-project/backstage-repo', + 'bitbucket:https://bitbucket.org/backstage-project/backstage-repo', }, name: 'graphql-starter', title: 'GraphQL Service', diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.ts b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.ts index a39b8d6fff..5b244d24ce 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/bitbucket.ts @@ -42,7 +42,7 @@ export class BitbucketPreparer implements PreparerBase { const workingDirectory = opts?.workingDirectory ?? os.tmpdir(); const { logger } = opts; - if (!['bitbucket/api', 'url'].includes(protocol)) { + if (!['bitbucket', 'url'].includes(protocol)) { throw new InputError( `Wrong location protocol: ${protocol}, should be 'url'`, ); diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/preparers.ts b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/preparers.ts index 25e771ae12..906fc0f9fd 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/preparers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/preparers.ts @@ -86,7 +86,7 @@ export class Preparers implements PreparerBuilder { preparers.register('gitlab', gitlabPreparer); preparers.register('gitlab/api', gitlabPreparer); preparers.register('azure/api', azurePreparer); - preparers.register('bitbucket/api', bitbucketPreparer); + preparers.register('bitbucket', bitbucketPreparer); const githubConfig = config.getOptionalConfig('scaffolder.github'); if (githubConfig) { diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/publish/bitbucket.test.ts b/plugins/scaffolder-backend/src/scaffolder/stages/publish/bitbucket.test.ts index 82f54ec746..3b084f1bf9 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/publish/bitbucket.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/publish/bitbucket.test.ts @@ -14,44 +14,55 @@ * limitations under the License. */ -const mockResponse = jest.fn(); jest.mock('./helpers'); -jest.mock('cross-fetch', () => mockResponse); import { BitbucketPublisher } from './bitbucket'; import { initRepoAndPush } from './helpers'; import { getVoidLogger } from '@backstage/backend-common'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { msw } from '@backstage/test-utils'; describe('Bitbucket Publisher', () => { const logger = getVoidLogger(); + const server = setupServer(); + msw.setupDefaultHandlers(server); + beforeEach(() => { jest.clearAllMocks(); }); describe('publish: createRemoteInBitbucketCloud', () => { it('should create repo in bitbucket cloud', async () => { + server.use( + rest.post( + 'https://api.bitbucket.org/2.0/repositories/project/repo', + (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + html: { + href: 'https://bitbucket.org/project/repo', + }, + clone: [ + { + name: 'https', + href: 'https://bitbucket.org/project/repo', + }, + ], + }, + }), + ), + ), + ); + const publisher = new BitbucketPublisher( 'https://bitbucket.org', 'fake-user', 'fake-token', ); - mockResponse.mockResolvedValue({ - status: 200, - json: () => - Promise.resolve({ - links: { - html: { - href: 'https://bitbucket.org/project/repo', - }, - clone: [ - { - name: 'https', - href: 'https://bitbucket.org/project/repo', - }, - ], - }, - }), - }); const result = await publisher.publish({ values: { @@ -78,31 +89,38 @@ describe('Bitbucket Publisher', () => { }); describe('publish: createRemoteInBitbucketServer', () => { it('should create repo in bitbucket server', async () => { + server.use( + rest.post( + 'https://bitbucket.mycompany.com/rest/api/1.0/projects/project/repos', + (_, res, ctx) => + res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: + 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ), + ), + ); + const publisher = new BitbucketPublisher( 'https://bitbucket.mycompany.com', 'fake-user', 'fake-token', ); - mockResponse.mockResolvedValue({ - status: 201, - json: () => - Promise.resolve({ - links: { - self: [ - { - href: - 'https://bitbucket.mycompany.com/projects/project/repos/repo', - }, - ], - clone: [ - { - name: 'http', - href: 'https://bitbucket.mycompany.com/scm/project/repo', - }, - ], - }, - }), - }); const result = await publisher.publish({ values: { diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/publish/publishers.ts b/plugins/scaffolder-backend/src/scaffolder/stages/publish/publishers.ts index 7496600356..75243aa610 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/publish/publishers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/publish/publishers.ts @@ -178,7 +178,7 @@ export class Publishers implements PublisherBuilder { bitbucketUsername, bitbucketToken, ); - publishers.register('bitbucket/api', bitbucketPublisher); + publishers.register('bitbucket', bitbucketPublisher); } catch (e) { const providerName = 'bitbucket'; if (process.env.NODE_ENV !== 'development') { diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/types.ts b/plugins/scaffolder-backend/src/scaffolder/stages/types.ts index c1dc9fbcdb..56111337fe 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/types.ts @@ -19,4 +19,4 @@ export type RemoteProtocol = | 'gitlab' | 'gitlab/api' | 'azure/api' - | 'bitbucket/api'; + | 'bitbucket';