From 1fb79af2f16fc59d7f856b384cf21555cd9d5c09 Mon Sep 17 00:00:00 2001 From: Michael Kriese <michael.kriese@visualon.de> Date: Mon, 22 Jul 2019 07:16:16 +0200 Subject: [PATCH] feat: check for disabled renovate.json (#4114) Extends option `optimizeForDisabled` to azure and bitbucket too --- lib/platform/azure/azure-helper.ts | 33 +++------- lib/platform/azure/index.ts | 40 ++++++++---- lib/platform/bitbucket-server/README.md | 5 ++ lib/platform/bitbucket-server/index.ts | 52 +++++++++++++--- lib/platform/bitbucket/index.ts | 59 +++++++++++------- lib/platform/common.ts | 12 ++++ test/platform/azure/azure-helper.spec.ts | 18 ++---- test/platform/azure/index.spec.ts | 61 +++++++++++-------- .../__snapshots__/index.spec.ts.snap | 16 +++++ test/platform/bitbucket-server/index.spec.ts | 30 ++++++++- .../platform/bitbucket/_fixtures/responses.js | 1 + test/platform/bitbucket/index.spec.ts | 12 +++- 12 files changed, 229 insertions(+), 110 deletions(-) diff --git a/lib/platform/azure/azure-helper.ts b/lib/platform/azure/azure-helper.ts index 4e019b845b..6fc995dd23 100644 --- a/lib/platform/azure/azure-helper.ts +++ b/lib/platform/azure/azure-helper.ts @@ -66,8 +66,9 @@ export async function getRefs(repoId: string, branchName?: string) { /** * - * @param {string} branchName - * @param {string} from + * @param repoId + * @param branchName + * @param from */ export async function getAzureBranchObj( repoId: string, @@ -88,31 +89,17 @@ export async function getAzureBranchObj( oldObjectId: refs[0].objectId, }; } -/** - * - * @param {string} msg - * @param {string} filePath - * @param {string} fileContent - * @param {string} repoId - * @param {string} repository - * @param {string} branchName - */ + export async function getChanges( - files: any, - repoId: any, - repository: any, - branchName: any + files: { name: string; contents: any }[], + repoId: string, + branchName: string ) { const changes = []; for (const file of files) { // Add or update let changeType = 1; - const fileAlreadyThere = await getFile( - repoId, - repository, - file.name, - branchName - ); + const fileAlreadyThere = await getFile(repoId, file.name, branchName); if (fileAlreadyThere) { changeType = 2; } @@ -135,15 +122,13 @@ export async function getChanges( /** * if no branchName, look globaly * @param {string} repoId - * @param {string} repository * @param {string} filePath * @param {string} branchName */ export async function getFile( repoId: string, - repository: any, filePath: string, - branchName: any + branchName: string ) { logger.trace(`getFile(filePath=${filePath}, branchName=${branchName})`); const azureApiGit = await azureApi.gitApi(); diff --git a/lib/platform/azure/index.ts b/lib/platform/azure/index.ts index 2ec2d577b3..55fefb7d54 100644 --- a/lib/platform/azure/index.ts +++ b/lib/platform/azure/index.ts @@ -4,8 +4,9 @@ import * as hostRules from '../../util/host-rules'; import { appSlug } from '../../config/app-strings'; import GitStorage from '../git/storage'; import { logger } from '../../logger'; +import { RepoConfig, PlatformConfig } from '../common'; -interface RepoConfig { +interface Config { storage: GitStorage; repoForceRebase: boolean; mergeMethod: string; @@ -20,7 +21,7 @@ interface RepoConfig { repository: string; } -let config: RepoConfig = {} as any; +let config: Config = {} as any; const defaults: any = { hostType: 'azure', @@ -59,16 +60,10 @@ export async function initRepo({ repository, localDir, azureWorkItemId, -}: { - repository: string; - localDir: string; - azureWorkItemId: any; -}) { + optimizeForDisabled, +}: RepoConfig) { logger.debug(`initRepo("${repository}")`); - config.repository = repository; - config.fileList = null; - config.prList = null; - config.azureWorkItemId = azureWorkItemId; + config = { repository, azureWorkItemId } as any; const azureApiGit = await azureApi.gitApi(); const repos = await azureApiGit.getRepositories(); const names = azureHelper.getProjectAndRepo(repository); @@ -88,6 +83,27 @@ export async function initRepo({ config.baseCommitSHA = await getBranchCommit(config.baseBranch); config.mergeMethod = 'merge'; config.repoForceRebase = false; + + if (optimizeForDisabled) { + interface RenovateConfig { + enabled: boolean; + } + let renovateConfig: RenovateConfig; + try { + const json = await azureHelper.getFile( + repo.id, + 'renovate.json', + config.defaultBranch + ); + renovateConfig = JSON.parse(json); + } catch { + // Do nothing + } + if (renovateConfig && renovateConfig.enabled === false) { + throw new Error('disabled'); + } + } + config.storage = new GitStorage(); const [projectName, repoName] = repository.split('/'); const opts = hostRules.find({ @@ -102,7 +118,7 @@ export async function initRepo({ localDir, url, }); - const platformConfig = { + const platformConfig: PlatformConfig = { privateRepo: true, isFork: false, }; diff --git a/lib/platform/bitbucket-server/README.md b/lib/platform/bitbucket-server/README.md index 0bbb0d2c1b..d5ef66a96a 100644 --- a/lib/platform/bitbucket-server/README.md +++ b/lib/platform/bitbucket-server/README.md @@ -47,3 +47,8 @@ yarn start --autodiscover=true ``` You should then receive a "Configure Renovate" onboarding PR in any projects that `@renovate-bot` has been invited to. + +## Supported versions + +We support all Bitbucket Server versions which are not EOL. +See [Atlassian Support End of Life Policy](https://confluence.atlassian.com/support/atlassian-support-end-of-life-policy-201851003.html#AtlassianSupportEndofLifePolicy-BitbucketServer) for uptodate versions. diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts index 85bf5a975e..00147a1475 100644 --- a/lib/platform/bitbucket-server/index.ts +++ b/lib/platform/bitbucket-server/index.ts @@ -6,6 +6,17 @@ import * as utils from './utils'; import * as hostRules from '../../util/host-rules'; import GitStorage from '../git/storage'; import { logger } from '../../logger'; +import { RepoConfig, PlatformConfig } from '../common'; + +/* + * Version: 5.3 (EOL Date: 15 Aug 2019) + * See following docs for api information: + * https://docs.atlassian.com/bitbucket-server/rest/5.3.0/bitbucket-rest.html + * https://docs.atlassian.com/bitbucket-server/rest/5.3.0/bitbucket-build-rest.html + * + * See following page for uptodate supported versions + * https://confluence.atlassian.com/support/atlassian-support-end-of-life-policy-201851003.html#AtlassianSupportEndofLifePolicy-BitbucketServer + */ interface BbsConfig { baseBranch: string; @@ -96,13 +107,9 @@ export async function initRepo({ repository, gitPrivateKey, localDir, + optimizeForDisabled, bbUseDefaultReviewers, -}: { - repository: string; - gitPrivateKey?: string; - localDir: string; - bbUseDefaultReviewers?: boolean; -}) { +}: RepoConfig) { logger.debug( `initRepo("${JSON.stringify({ repository, localDir }, null, 2)}")` ); @@ -112,6 +119,35 @@ export async function initRepo({ }); const [projectKey, repositorySlug] = repository.split('/'); + + if (optimizeForDisabled) { + interface RenovateConfig { + enabled: boolean; + } + + interface FileData { + isLastPage: boolean; + + lines: string[]; + + size: number; + } + + let renovateConfig: RenovateConfig; + try { + const { body } = await api.get<FileData>( + `./rest/api/1.0/projects/${projectKey}/repos/${repositorySlug}/browse/renovate.json?limit=20000` + ); + if (!body.isLastPage) logger.warn('Renovate config to big: ' + body.size); + else renovateConfig = JSON.parse(body.lines.join()); + } catch { + // Do nothing + } + if (renovateConfig && renovateConfig.enabled === false) { + throw new Error('disabled'); + } + } + config = { projectKey, repositorySlug, @@ -144,7 +180,7 @@ export async function initRepo({ url: gitUrl, }); - const platformConfig: any = {}; + const platformConfig: PlatformConfig = {} as any; try { const info = (await api.get( @@ -168,8 +204,6 @@ export async function initRepo({ logger.info({ err }, 'Unknown Bitbucket initRepo error'); throw err; } - delete config.prList; - delete config.fileList; logger.debug( { platformConfig }, `platformConfig for ${config.projectKey}/${config.repositorySlug}` diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts index 92efc51c74..d3c68bb4b1 100644 --- a/lib/platform/bitbucket/index.ts +++ b/lib/platform/bitbucket/index.ts @@ -8,6 +8,7 @@ import GitStorage from '../git/storage'; import { readOnlyIssueBody } from '../utils/read-only-issue-body'; import { appSlug } from '../../config/app-strings'; import * as comments from './comments'; +import { RepoConfig, PlatformConfig } from '../common'; let config: utils.Config = {} as any; @@ -56,10 +57,8 @@ export async function getRepos() { export async function initRepo({ repository, localDir, -}: { - repository: string; - localDir: string; -}) { + optimizeForDisabled, +}: RepoConfig) { logger.debug(`initRepo("${repository}")`); const opts = hostRules.find({ hostType: 'bitbucket', @@ -71,26 +70,31 @@ export async function initRepo({ } as any; // TODO: get in touch with @rarkins about lifting up the caching into the app layer - const platformConfig: any = {}; - - const url = GitStorage.getUrl({ - protocol: 'https', - auth: `${opts!.username}:${opts!.password}`, - hostname: 'bitbucket.org', - repository, - }); - - config.storage = new GitStorage(); - await config.storage.initRepo({ - ...config, - localDir, - url, - }); + const platformConfig: PlatformConfig = {} as any; try { const info = utils.repoInfoTransformer( (await api.get(`/2.0/repositories/${repository}`)).body ); + + if (optimizeForDisabled) { + interface RenovateConfig { + enabled: boolean; + } + + let renovateConfig: RenovateConfig; + try { + renovateConfig = (await api.get<RenovateConfig>( + `/2.0/repositories/${repository}/src/${info.mainbranch}/renovate.json` + )).body; + } catch { + // Do nothing + } + if (renovateConfig && renovateConfig.enabled === false) { + throw new Error('disabled'); + } + } + platformConfig.privateRepo = info.privateRepo; platformConfig.isFork = info.isFork; platformConfig.repoFullName = info.repoFullName; @@ -111,8 +115,21 @@ export async function initRepo({ logger.info({ err }, 'Unknown Bitbucket initRepo error'); throw err; } - delete config.prList; - delete config.fileList; + + const url = GitStorage.getUrl({ + protocol: 'https', + auth: `${opts!.username}:${opts!.password}`, + hostname: 'bitbucket.org', + repository, + }); + + config.storage = new GitStorage(); + await config.storage.initRepo({ + ...config, + localDir, + url, + }); + await Promise.all([getPrList(), getFileList()]); return platformConfig; } diff --git a/lib/platform/common.ts b/lib/platform/common.ts index 8458aabf2c..0d44da6593 100644 --- a/lib/platform/common.ts +++ b/lib/platform/common.ts @@ -41,4 +41,16 @@ export interface GotApi<TOptions extends object = any> { export interface PlatformConfig { isFork: boolean; + privateRepo: boolean; + // do we need this? + repoFullName?: string; +} + +export interface RepoConfig { + azureWorkItemId?: number; + bbUseDefaultReviewers?: boolean; + gitPrivateKey?: string; + localDir: string; + optimizeForDisabled?: boolean; + repository: string; } diff --git a/test/platform/azure/azure-helper.spec.ts b/test/platform/azure/azure-helper.spec.ts index 812f0b58a6..e3bb4ea18b 100644 --- a/test/platform/azure/azure-helper.spec.ts +++ b/test/platform/azure/azure-helper.spec.ts @@ -135,8 +135,7 @@ describe('platform/azure/helpers', () => { }, ], '123', - 'repository', - 'branchName' + 'repository' ); expect(res).toMatchSnapshot(); }); @@ -156,8 +155,7 @@ describe('platform/azure/helpers', () => { }, ], '123', - 'repository', - 'branchName' + 'repository' ); expect(res).toMatchSnapshot(); }); @@ -189,8 +187,7 @@ describe('platform/azure/helpers', () => { const res = await azureHelper.getFile( '123', 'repository', - './myFilePath/test', - 'branchName' + './myFilePath/test' ); expect(res).toBeNull(); }); @@ -220,8 +217,7 @@ describe('platform/azure/helpers', () => { const res = await azureHelper.getFile( '123', 'repository', - './myFilePath/test', - 'branchName' + './myFilePath/test' ); expect(res).toBeNull(); }); @@ -251,8 +247,7 @@ describe('platform/azure/helpers', () => { const res = await azureHelper.getFile( '123', 'repository', - './myFilePath/test', - 'branchName' + './myFilePath/test' ); expect(res).toMatchSnapshot(); }); @@ -270,8 +265,7 @@ describe('platform/azure/helpers', () => { const res = await azureHelper.getFile( '123', 'repository', - './myFilePath/test', - 'branchName' + './myFilePath/test' ); expect(res).toBeNull(); }); diff --git a/test/platform/azure/index.spec.ts b/test/platform/azure/index.spec.ts index acf58c72a8..a94da7f3b3 100644 --- a/test/platform/azure/index.spec.ts +++ b/test/platform/azure/index.spec.ts @@ -1,4 +1,6 @@ +import is from '@sindresorhus/is'; import * as _hostRules from '../../../lib/util/host-rules'; +import { RepoConfig } from '../../../lib/platform/common'; describe('platform/azure', () => { let hostRules: jest.Mocked<typeof _hostRules>; @@ -122,7 +124,7 @@ describe('platform/azure', () => { azure.cleanRepo(); }); }); - function initRepo(...args: any[]) { + function initRepo(args?: Partial<RepoConfig> | string) { azureApi.gitApi.mockImplementationOnce( () => ({ @@ -157,29 +159,34 @@ describe('platform/azure', () => { repo: 'some-repo', })); - if (typeof args[0] === 'string') { + if (is.string(args)) { return azure.initRepo({ - repository: args[0] as string, + repository: args, } as any); } return azure.initRepo({ - endpoint: 'https://dev.azure.com/renovate12345', repository: 'some/repo', - ...args[0], - }); + ...args, + } as any); } describe('initRepo', () => { it(`should initialise the config for a repo`, async () => { const config = await initRepo({ repository: 'some-repo', - token: 'token', - endpoint: 'https://dev.azure.com/renovate12345', }); expect(azureApi.gitApi.mock.calls).toMatchSnapshot(); expect(config).toMatchSnapshot(); }); + + it('throws disabled', async () => { + expect.assertions(1); + azureHelper.getFile.mockResolvedValueOnce('{ "enabled": false }'); + await expect( + initRepo({ repository: 'some-repo', optimizeForDisabled: true }) + ).rejects.toThrow('disabled'); + }); }); describe('getRepoForceRebase', () => { @@ -302,7 +309,7 @@ describe('platform/azure', () => { describe('getBranchPr(branchName)', () => { it('should return null if no PR exists', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -316,7 +323,7 @@ describe('platform/azure', () => { expect(pr).toBeNull(); }); it('should return the pr', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementation( () => ({ @@ -347,17 +354,17 @@ describe('platform/azure', () => { describe('getBranchStatus(branchName, requiredStatusChecks)', () => { it('return success if requiredStatusChecks null', async () => { - await initRepo('some-repo', 'token'); + await initRepo('some-repo'); const res = await azure.getBranchStatus('somebranch', null); expect(res).toEqual('success'); }); it('return failed if unsupported requiredStatusChecks', async () => { - await initRepo('some-repo', 'token'); + await initRepo('some-repo'); const res = await azure.getBranchStatus('somebranch', ['foo']); expect(res).toEqual('failed'); }); it('should pass through success', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -368,7 +375,7 @@ describe('platform/azure', () => { expect(res).toEqual('success'); }); it('should pass through failed', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -386,7 +393,7 @@ describe('platform/azure', () => { expect(pr).toBeNull(); }); it('should return null if no PR is returned from azure', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -397,7 +404,7 @@ describe('platform/azure', () => { expect(pr).toBeNull(); }); it('should return a pr in the right format', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -418,7 +425,7 @@ describe('platform/azure', () => { describe('createPr()', () => { it('should create and return a PR object', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -443,7 +450,7 @@ describe('platform/azure', () => { expect(pr).toMatchSnapshot(); }); it('should create and return a PR object from base branch', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -469,7 +476,7 @@ describe('platform/azure', () => { expect(pr).toMatchSnapshot(); }); it('should create and return a PR object with auto-complete set', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); const prResult = { pullRequestId: 456, displayNumber: `Pull Request #456`, @@ -514,7 +521,7 @@ describe('platform/azure', () => { describe('updatePr(prNo, title, body)', () => { it('should update the PR', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -526,7 +533,7 @@ describe('platform/azure', () => { }); it('should update the PR without description', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ @@ -540,7 +547,7 @@ describe('platform/azure', () => { describe('ensureComment', () => { it('add comment', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementation( () => ({ @@ -554,7 +561,7 @@ describe('platform/azure', () => { describe('ensureCommentRemoval', () => { it('deletes comment if found', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementation( () => ({ @@ -575,7 +582,7 @@ describe('platform/azure', () => { expect(azureApi.gitApi).toHaveBeenCalledTimes(0); }); it('comment not found', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementation( () => ({ @@ -592,7 +599,7 @@ describe('platform/azure', () => { describe('Assignees', () => { it('addAssignees', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementation( () => ({ @@ -606,7 +613,7 @@ describe('platform/azure', () => { describe('Reviewers', () => { it('addReviewers', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementation( () => ({ @@ -666,7 +673,7 @@ describe('platform/azure', () => { describe('deleteLabel()', () => { it('Should delete a label', async () => { - await initRepo({ repository: 'some/repo', token: 'token' }); + await initRepo({ repository: 'some/repo' }); azureApi.gitApi.mockImplementationOnce( () => ({ diff --git a/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap b/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap index e6a5f8bf2a..06a44efa2d 100644 --- a/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap +++ b/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap @@ -982,6 +982,14 @@ Object { } `; +exports[`platform/bitbucket-server endpoint with no path initRepo() does not throw 1`] = ` +Object { + "isFork": false, + "privateRepo": undefined, + "repoFullName": "repo", +} +`; + exports[`platform/bitbucket-server endpoint with no path initRepo() works 1`] = ` Object { "isFork": false, @@ -2436,6 +2444,14 @@ Object { } `; +exports[`platform/bitbucket-server endpoint with path initRepo() does not throw 1`] = ` +Object { + "isFork": false, + "privateRepo": undefined, + "repoFullName": "repo", +} +`; + exports[`platform/bitbucket-server endpoint with path initRepo() works 1`] = ` Object { "isFork": false, diff --git a/test/platform/bitbucket-server/index.spec.ts b/test/platform/bitbucket-server/index.spec.ts index 3deca6128c..9af2044371 100644 --- a/test/platform/bitbucket-server/index.spec.ts +++ b/test/platform/bitbucket-server/index.spec.ts @@ -1,5 +1,5 @@ import responses from './_fixtures/responses'; -import { GotApi } from '../../../lib/platform/common'; +import { GotApi, RepoConfig } from '../../../lib/platform/common'; import { Storage } from '../../../lib/platform/git/storage'; type BbsApi = typeof import('../../../lib/platform/bitbucket-server'); @@ -7,7 +7,7 @@ type BbsApi = typeof import('../../../lib/platform/bitbucket-server'); describe('platform/bitbucket-server', () => { Object.entries(responses).forEach(([scenarioName, mockResponses]) => { describe(scenarioName, () => { - let bitbucket: typeof import('../../../lib/platform/bitbucket-server'); + let bitbucket: BbsApi; let api: jest.Mocked<GotApi>; let hostRules: jest.Mocked<typeof import('../../../lib/util/host-rules')>; let GitStorage: jest.Mock<Storage> & { @@ -83,10 +83,11 @@ describe('platform/bitbucket-server', () => { bitbucket.cleanRepo(); }); - function initRepo() { + function initRepo(config?: Partial<RepoConfig>) { return bitbucket.initRepo({ endpoint: 'https://stash.renovatebot.com/vcs/', repository: 'SOME/repo', + ...config, } as any); } @@ -126,6 +127,29 @@ describe('platform/bitbucket-server', () => { const res = await initRepo(); expect(res).toMatchSnapshot(); }); + it('does not throw', async () => { + expect.assertions(1); + api.get.mockResolvedValueOnce({ + body: { + isLastPage: false, + lines: ['{'], + size: 50000, + }, + } as any); + + const res = await initRepo({ optimizeForDisabled: true }); + expect(res).toMatchSnapshot(); + }); + + it('throws disabled', async () => { + expect.assertions(1); + api.get.mockResolvedValueOnce({ + body: { isLastPage: true, lines: ['{ "enabled": false }'] }, + } as any); + await expect(initRepo({ optimizeForDisabled: true })).rejects.toThrow( + 'disabled' + ); + }); }); describe('repoForceRebase()', () => { diff --git a/test/platform/bitbucket/_fixtures/responses.js b/test/platform/bitbucket/_fixtures/responses.js index d4698f276b..ff871a2f56 100644 --- a/test/platform/bitbucket/_fixtures/responses.js +++ b/test/platform/bitbucket/_fixtures/responses.js @@ -40,6 +40,7 @@ module.exports = { '/2.0/repositories/some/empty/issues': { values: [], }, + '/2.0/repositories/some/empty/src/master/renovate.json': { enabled: false }, '/2.0/repositories/some/repo/issues': { values: [issue, { ...issue, id: 26 }], }, diff --git a/test/platform/bitbucket/index.spec.ts b/test/platform/bitbucket/index.spec.ts index b69e17bf33..6ba40c91f6 100644 --- a/test/platform/bitbucket/index.spec.ts +++ b/test/platform/bitbucket/index.spec.ts @@ -1,6 +1,6 @@ import URL from 'url'; import responses from './_fixtures/responses'; -import { GotApi } from '../../../lib/platform/common'; +import { GotApi, RepoConfig } from '../../../lib/platform/common'; describe('platform/bitbucket', () => { let bitbucket: typeof import('../../../lib/platform/bitbucket'); @@ -71,11 +71,12 @@ describe('platform/bitbucket', () => { return (...args: any) => mocked(() => (bitbucket as any)[prop](...args)); } - function initRepo() { + function initRepo(config?: Partial<RepoConfig>) { return mocked(() => bitbucket.initRepo({ repository: 'some/repo', localDir: '', + ...config, }) ); } @@ -120,6 +121,13 @@ describe('platform/bitbucket', () => { it('works', async () => { expect(await initRepo()).toMatchSnapshot(); }); + + it('throws disabled', async () => { + expect.assertions(1); + await expect( + initRepo({ repository: 'some/empty', optimizeForDisabled: true }) + ).rejects.toThrow('disabled'); + }); }); describe('getRepoForceRebase()', () => { -- GitLab