diff --git a/lib/platform/common.ts b/lib/platform/common.ts index 544b9b4904323918b99fd04620f39620d62f5783..45b14c88c132fab267918ddd01481ad615bfaf5e 100644 --- a/lib/platform/common.ts +++ b/lib/platform/common.ts @@ -78,10 +78,13 @@ export interface RepoParams { /** * TODO: Proper typing */ -export type Pr = { branchName: string; title: string; state: string } & Record< - string, - any ->; +export type Pr = { + branchName: string; + title: string; + state: string; + isConflicted?: boolean; + isModified?: boolean; +} & Record<string, any>; /** * TODO: Proper typing @@ -93,7 +96,12 @@ export interface Issue { title?: string; } -export type BranchStatus = 'pending' | 'success' | 'failed'; +export type BranchStatus = + | 'pending' + | 'success' + | 'failed' + | 'running' + | 'failure'; export type PlatformPrOptions = { azureAutoComplete: boolean; diff --git a/lib/workers/branch/get-updated.ts b/lib/workers/branch/get-updated.ts index 72f6784990bd51a196afe88c161865b896fcd56d..3176cb84fd25b793b71eb91632df168eb6713ebd 100644 --- a/lib/workers/branch/get-updated.ts +++ b/lib/workers/branch/get-updated.ts @@ -7,7 +7,7 @@ import { UpdateArtifactsConfig, ArtifactError } from '../../manager/common'; export interface PackageFilesResult { artifactErrors: ArtifactError[]; - parentBranch: string; + parentBranch?: string; updatedPackageFiles: FileData[]; updatedArtifacts: FileData[]; } diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts index 57a46727f72d428b72a32e8019e8668dfb90fe88..d11f92ba71724980ce95015f6ad284984a84a86e 100644 --- a/lib/workers/branch/index.ts +++ b/lib/workers/branch/index.ts @@ -7,25 +7,16 @@ import { getAdditionalFiles, AdditionalPackageFiles, } from '../../manager/npm/post-update'; -import { commitFilesToBranch, CommitConfig } from './commit'; +import { commitFilesToBranch } from './commit'; import { getParentBranch } from './parent'; import { tryBranchAutomerge } from './automerge'; -import { - setStability, - setUnpublishable, - StabilityConfig, - UnpublishableConfig, -} from './status-checks'; +import { setStability, setUnpublishable } from './status-checks'; import { prAlreadyExisted } from './check-existing'; import { ensurePr, checkAutoMerge } from '../pr'; import { RenovateConfig } from '../../config'; import { platform } from '../../platform'; import { emojify } from '../../util/emoji'; - -export type BranchConfig = RenovateConfig & - StabilityConfig & - UnpublishableConfig & - CommitConfig; +import { BranchConfig } from '../common'; export type ProcessBranchResult = | 'already-existed' @@ -57,7 +48,7 @@ export async function processBranch( prHourlyLimitReached?: boolean, packageFiles?: AdditionalPackageFiles ): Promise<ProcessBranchResult> { - const config = { ...branchConfig }; + const config: BranchConfig = { ...branchConfig }; const dependencies = config.upgrades .map(upgrade => upgrade.depName) .filter(v => v) // remove nulls (happens for lock file maintenance) diff --git a/lib/workers/branch/status-checks.ts b/lib/workers/branch/status-checks.ts index c0d780b292eab9438dd5af84925d6eface2ffcb8..bfd0b3bc8775aa3e9900b4a617d74a2d277311ca 100644 --- a/lib/workers/branch/status-checks.ts +++ b/lib/workers/branch/status-checks.ts @@ -29,7 +29,7 @@ async function setStatusCheck( } export type StabilityConfig = RenovateConfig & { - stabilityStatus: string; + stabilityStatus?: string; branchName: string; }; diff --git a/lib/workers/common.ts b/lib/workers/common.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ee5527627139e370e53cbd1dc8b65d27dc1b738 --- /dev/null +++ b/lib/workers/common.ts @@ -0,0 +1,21 @@ +import { PrBodyUpgrade, PrBodyConfig } from './pr/body/common'; +import { PackageDependency } from '../manager/common'; +import { ChangeLogConfig } from './pr/changelog'; +import { RenovateConfig } from '../config'; +import { StabilityConfig, UnpublishableConfig } from './branch/status-checks'; +import { CommitConfig } from './branch/commit'; + +export type PrUpgrade = PrBodyUpgrade & + PackageDependency & + ChangeLogConfig & + PrBodyConfig & { + manager?: string; + hasUrls?: boolean; + githubName?: string | undefined; + }; + +export type BranchConfig = RenovateConfig & + StabilityConfig & + UnpublishableConfig & + CommitConfig & + PrBodyConfig<PrUpgrade>; diff --git a/lib/workers/pr/body/common.ts b/lib/workers/pr/body/common.ts index 3a73c44ef0febb1b58050c917bba2f96b57821f5..c3de2c62f5b0590178714efcba58aa746d76941c 100644 --- a/lib/workers/pr/body/common.ts +++ b/lib/workers/pr/body/common.ts @@ -2,17 +2,20 @@ import { LookupUpdate } from '../../repository/process/lookup/common'; import { RenovateSharedConfig } from '../../../config'; import { Release, ReleaseResult } from '../../../datasource'; +export type PrBodyUpgrade = LookupUpdate & + Release & + ReleaseResult & { + prBodyNotes?: string[]; + depName?: string; + depNameLinked?: string; + references?: string; + versionScheme: string; + stabilityDays?: number; + }; + // TODO: Unify and optimize types and interfaces -export type PrBodyConfig = { - upgrades: (LookupUpdate & - Release & - ReleaseResult & { - prBodyNotes?: string[]; - depName?: string; - depNameLinked?: string; - references?: string; - versionScheme: string; - })[]; +export type PrBodyConfig<T extends PrBodyUpgrade = PrBodyUpgrade> = { + upgrades: T[]; prBanner?: string; prBodyTemplate: string; prBodyColumns: string[]; diff --git a/lib/workers/pr/index.js b/lib/workers/pr/index.ts similarity index 94% rename from lib/workers/pr/index.js rename to lib/workers/pr/index.ts index 31386627d22e655a473106e668de93b1ad5e23fc..915810d19c04d0aa55ad15774b1562826d6b6757 100644 --- a/lib/workers/pr/index.js +++ b/lib/workers/pr/index.ts @@ -1,17 +1,66 @@ -const sampleSize = require('lodash/sampleSize'); +import sampleSize from 'lodash/sampleSize'; +import { logger } from '../../logger'; +import { getChangeLogJSON } from './changelog'; +import { getPrBody } from './body'; +import { platform, BranchStatus, Pr } from '../../platform'; +import { BranchConfig } from '../common'; -const { logger } = require('../../logger'); -const changelogHelper = require('./changelog'); -const { getPrBody } = require('./body'); -const { platform } = require('../../platform'); +function noWhitespace(input: string): string { + return input.replace(/\r?\n|\r|\s/g, ''); +} + +async function addAssigneesReviewers(config, pr: Pr): Promise<void> { + if (config.assignees.length > 0) { + try { + let assignees = config.assignees.map(assignee => + assignee.length && assignee[0] === '@' ? assignee.slice(1) : assignee + ); + if (config.assigneesSampleSize !== null) { + assignees = sampleSize(assignees, config.assigneesSampleSize); + } + // istanbul ignore if + if (config.dryRun) { + logger.info('DRY-RUN: Would add assignees to PR #' + pr.number); + } else { + await platform.addAssignees(pr.number, assignees); + logger.info({ assignees }, 'Added assignees'); + } + } catch (err) { + logger.info( + { assignees: config.assignees, err }, + 'Failed to add assignees' + ); + } + } + if (config.reviewers.length > 0) { + try { + let reviewers = config.reviewers.map(reviewer => + reviewer.length && reviewer[0] === '@' ? reviewer.slice(1) : reviewer + ); + if (config.reviewersSampleSize !== null) { + reviewers = sampleSize(reviewers, config.reviewersSampleSize); + } + // istanbul ignore if + if (config.dryRun) { + logger.info('DRY-RUN: Would add reviewers to PR #' + pr.number); + } else { + await platform.addReviewers(pr.number, reviewers); + logger.info({ reviewers }, 'Added reviewers'); + } + } catch (err) { + logger.info( + { reviewers: config.reviewers, err }, + 'Failed to add reviewers' + ); + } + } +} -module.exports = { - ensurePr, - checkAutoMerge, -}; // Ensures that PR exists with matching title/body -async function ensurePr(prConfig) { - const config = { ...prConfig }; +export async function ensurePr( + prConfig: BranchConfig +): Promise<Pr | 'needs-pr-approval'> { + const config: BranchConfig = { ...prConfig }; logger.trace({ config }, 'ensurePr'); // If there is a group, it will use the config of the first upgrade in the array @@ -29,8 +78,8 @@ async function ensurePr(prConfig) { config.forcePr = true; } - let branchStatus; - async function getBranchStatus() { + let branchStatus: BranchStatus; + async function getBranchStatus(): Promise<BranchStatus> { if (!branchStatus) { branchStatus = await platform.getBranchStatus( branchName, @@ -133,7 +182,7 @@ async function ensurePr(prConfig) { processedUpgrades.push(upgradeKey); upgrade.hasUrls = !!(upgrade.sourceUrl || upgrade.homepage); - const logJSON = await changelogHelper.getChangeLogJSON(upgrade); + const logJSON = await getChangeLogJSON(upgrade); if (logJSON) { upgrade.githubName = logJSON.project ? logJSON.project.github : undefined; @@ -240,12 +289,12 @@ async function ensurePr(prConfig) { if (config.updateType === 'rollback') { logger.info('Creating Rollback PR'); } - let pr; + let pr: Pr; try { // istanbul ignore if if (config.dryRun) { logger.info('DRY-RUN: Would create PR: ' + prTitle); - pr = { number: 0, displayNumber: 'Dry run PR' }; + pr = { number: 0, displayNumber: 'Dry run PR' } as never; } else { const platformOptions = { azureAutoComplete: config.azureAutoComplete, @@ -342,54 +391,7 @@ async function ensurePr(prConfig) { return null; } -async function addAssigneesReviewers(config, pr) { - if (config.assignees.length > 0) { - try { - let assignees = config.assignees.map(assignee => - assignee.length && assignee[0] === '@' ? assignee.slice(1) : assignee - ); - if (config.assigneesSampleSize !== null) { - assignees = sampleSize(assignees, config.assigneesSampleSize); - } - // istanbul ignore if - if (config.dryRun) { - logger.info('DRY-RUN: Would add assignees to PR #' + pr.number); - } else { - await platform.addAssignees(pr.number, assignees); - logger.info({ assignees }, 'Added assignees'); - } - } catch (err) { - logger.info( - { assignees: config.assignees, err }, - 'Failed to add assignees' - ); - } - } - if (config.reviewers.length > 0) { - try { - let reviewers = config.reviewers.map(reviewer => - reviewer.length && reviewer[0] === '@' ? reviewer.slice(1) : reviewer - ); - if (config.reviewersSampleSize !== null) { - reviewers = sampleSize(reviewers, config.reviewersSampleSize); - } - // istanbul ignore if - if (config.dryRun) { - logger.info('DRY-RUN: Would add reviewers to PR #' + pr.number); - } else { - await platform.addReviewers(pr.number, reviewers); - logger.info({ reviewers }, 'Added reviewers'); - } - } catch (err) { - logger.info( - { reviewers: config.reviewers, err }, - 'Failed to add reviewers' - ); - } - } -} - -async function checkAutoMerge(pr, config) { +export async function checkAutoMerge(pr: Pr, config): Promise<boolean> { logger.trace({ config }, 'checkAutoMerge'); const { branchName, @@ -456,7 +458,3 @@ async function checkAutoMerge(pr, config) { logger.debug('No automerge'); return false; } - -function noWhitespace(input) { - return input.replace(/\r?\n|\r|\s/g, ''); -} diff --git a/test/util.ts b/test/util.ts index 1c6d9624e8d1e771f45d9599bbb243d2d68d7546..69d8ec1e606753ff7b7f15bcc2443e18ea819c25 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,3 +1,6 @@ +import { platform as _platform } from '../lib/platform'; +import { getConfig } from '../lib/config/defaults'; + /** * Simple wrapper for getting mocked version of a module * @param module module which is mocked by `jest.mock` @@ -5,3 +8,7 @@ export function mocked<T>(module: T): jest.Mocked<T> { return module as never; } + +export const platform = mocked(_platform); + +export const defaultConfig = getConfig(); diff --git a/test/workers/branch/__snapshots__/commit.spec.js.snap b/test/workers/branch/__snapshots__/commit.spec.ts.snap similarity index 100% rename from test/workers/branch/__snapshots__/commit.spec.js.snap rename to test/workers/branch/__snapshots__/commit.spec.ts.snap diff --git a/test/workers/branch/__snapshots__/get-updated.spec.js.snap b/test/workers/branch/__snapshots__/get-updated.spec.ts.snap similarity index 97% rename from test/workers/branch/__snapshots__/get-updated.spec.js.snap rename to test/workers/branch/__snapshots__/get-updated.spec.ts.snap index c61fc9a70a7f55ea73ab7fe3624755231028efd2..c04eeae264409c18159115ff214bf7b783ed440e 100644 --- a/test/workers/branch/__snapshots__/get-updated.spec.js.snap +++ b/test/workers/branch/__snapshots__/get-updated.spec.ts.snap @@ -41,7 +41,7 @@ exports[`workers/branch/get-updated getUpdatedPackageFiles() handles lock file e Object { "artifactErrors": Array [ Object { - "name": "composer.lock", + "lockFile": "composer.lock", "stderr": "some error", }, ], @@ -93,7 +93,7 @@ exports[`workers/branch/get-updated getUpdatedPackageFiles() handles lockFileMai Object { "artifactErrors": Array [ Object { - "name": "composer.lock", + "lockFile": "composer.lock", "stderr": "some error", }, ], diff --git a/test/workers/branch/automerge.spec.js b/test/workers/branch/automerge.spec.ts similarity index 74% rename from test/workers/branch/automerge.spec.js rename to test/workers/branch/automerge.spec.ts index cde1f766fa782ec45497017376c6af861e5ddf10..1be7443631ebfe855f1d001cc6f66b1e9ce9d85c 100644 --- a/test/workers/branch/automerge.spec.js +++ b/test/workers/branch/automerge.spec.ts @@ -1,11 +1,10 @@ -const { tryBranchAutomerge } = require('../../../lib/workers/branch/automerge'); -const defaultConfig = require('../../../lib/config/defaults').getConfig(); -/** @type any */ -const { platform } = require('../../../lib/platform'); +import { tryBranchAutomerge } from '../../../lib/workers/branch/automerge'; +import { defaultConfig, platform } from '../../util'; +import { RenovateConfig } from '../../../lib/config'; describe('workers/branch/automerge', () => { describe('tryBranchAutomerge', () => { - let config; + let config: RenovateConfig; beforeEach(() => { config = { ...defaultConfig, @@ -23,20 +22,20 @@ describe('workers/branch/automerge', () => { it('returns false if branch status is not success', async () => { config.automerge = true; config.automergeType = 'branch'; - platform.getBranchStatus.mockReturnValueOnce('pending'); + platform.getBranchStatus.mockResolvedValueOnce('pending'); expect(await tryBranchAutomerge(config)).toBe('no automerge'); }); it('returns branch status error if branch status is failure', async () => { config.automerge = true; config.automergeType = 'branch'; - platform.getBranchStatus.mockReturnValueOnce('failure'); + platform.getBranchStatus.mockResolvedValueOnce('failure'); expect(await tryBranchAutomerge(config)).toBe('branch status error'); }); it('returns false if PR exists', async () => { - platform.getBranchPr.mockReturnValueOnce({}); + platform.getBranchPr.mockResolvedValueOnce({} as never); config.automerge = true; config.automergeType = 'branch'; - platform.getBranchStatus.mockReturnValueOnce('success'); + platform.getBranchStatus.mockResolvedValueOnce('success'); expect(await tryBranchAutomerge(config)).toBe( 'automerge aborted - PR exists' ); @@ -44,7 +43,7 @@ describe('workers/branch/automerge', () => { it('returns false if automerge fails', async () => { config.automerge = true; config.automergeType = 'branch'; - platform.getBranchStatus.mockReturnValueOnce('success'); + platform.getBranchStatus.mockResolvedValueOnce('success'); platform.mergeBranch.mockImplementationOnce(() => { throw new Error('merge error'); }); @@ -53,14 +52,14 @@ describe('workers/branch/automerge', () => { it('returns true if automerge succeeds', async () => { config.automerge = true; config.automergeType = 'branch'; - platform.getBranchStatus.mockReturnValueOnce('success'); + platform.getBranchStatus.mockResolvedValueOnce('success'); expect(await tryBranchAutomerge(config)).toBe('automerged'); }); it('returns true if automerge succeeds (dry-run)', async () => { config.automerge = true; config.automergeType = 'branch'; config.dryRun = true; - platform.getBranchStatus.mockReturnValueOnce('success'); + platform.getBranchStatus.mockResolvedValueOnce('success'); expect(await tryBranchAutomerge(config)).toBe('automerged'); }); }); diff --git a/test/workers/branch/check-existing.spec.js b/test/workers/branch/check-existing.spec.ts similarity index 69% rename from test/workers/branch/check-existing.spec.js rename to test/workers/branch/check-existing.spec.ts index 07401919929bf928e30b16c65f1b32f445e48714..f857d752329ffde9d6774d17c8253bfb71d2b0e3 100644 --- a/test/workers/branch/check-existing.spec.js +++ b/test/workers/branch/check-existing.spec.ts @@ -1,13 +1,10 @@ -const { - prAlreadyExisted, -} = require('../../../lib/workers/branch/check-existing'); -const defaultConfig = require('../../../lib/config/defaults').getConfig(); -/** @type any */ -const { platform } = require('../../../lib/platform'); +import { prAlreadyExisted } from '../../../lib/workers/branch/check-existing'; +import { defaultConfig, platform } from '../../util'; +import { RenovateConfig } from '../../../lib/config'; describe('workers/branch/check-existing', () => { describe('prAlreadyExisted', () => { - let config; + let config: RenovateConfig; beforeEach(() => { config = { ...defaultConfig, @@ -27,8 +24,11 @@ describe('workers/branch/check-existing', () => { expect(platform.findPr).toHaveBeenCalledTimes(1); }); it('returns true if first check hits', async () => { - platform.findPr.mockReturnValueOnce({ number: 12 }); - platform.getPr.mockReturnValueOnce({ number: 12, state: 'closed' }); + platform.findPr.mockResolvedValueOnce({ number: 12 } as never); + platform.getPr.mockResolvedValueOnce({ + number: 12, + state: 'closed', + } as never); expect(await prAlreadyExisted(config)).toEqual({ number: 12 }); expect(platform.findPr).toHaveBeenCalledTimes(1); }); diff --git a/test/workers/branch/commit.spec.js b/test/workers/branch/commit.spec.ts similarity index 80% rename from test/workers/branch/commit.spec.js rename to test/workers/branch/commit.spec.ts index 6f2634f96dd39bb235a682fc25bd766ab78a7aa6..b1d5bb8d7de880ed2dad7c2f0e1a832371f6807d 100644 --- a/test/workers/branch/commit.spec.js +++ b/test/workers/branch/commit.spec.ts @@ -1,11 +1,13 @@ -const { commitFilesToBranch } = require('../../../lib/workers/branch/commit'); -const defaultConfig = require('../../../lib/config/defaults').getConfig(); -/** @type any */ -const { platform } = require('../../../lib/platform'); +import { + commitFilesToBranch, + CommitConfig, +} from '../../../lib/workers/branch/commit'; +import { defaultConfig, platform } from '../../util'; +import { RenovateConfig } from '../../../lib/config'; describe('workers/branch/automerge', () => { describe('commitFilesToBranch', () => { - let config; + let config: RenovateConfig & CommitConfig; beforeEach(() => { config = { ...defaultConfig, @@ -18,7 +20,7 @@ describe('workers/branch/automerge', () => { updatedArtifacts: [], }; jest.resetAllMocks(); - platform.commitFilesToBranch.mockReturnValueOnce('created'); + platform.commitFilesToBranch.mockResolvedValueOnce(); }); it('handles empty files', async () => { await commitFilesToBranch(config); diff --git a/test/workers/branch/get-updated.spec.js b/test/workers/branch/get-updated.spec.ts similarity index 77% rename from test/workers/branch/get-updated.spec.js rename to test/workers/branch/get-updated.spec.ts index 953c711b0a1b5e292aeb3e3d20514e74f0c6c3e2..de78463f1334287a09d2f53e76722b323c6b532c 100644 --- a/test/workers/branch/get-updated.spec.js +++ b/test/workers/branch/get-updated.spec.ts @@ -1,15 +1,12 @@ -/** @type any */ -const composer = require('../../../lib/manager/composer'); -/** @type any */ -const npm = require('../../../lib/manager/npm'); -/** @type any */ -const gitSubmodules = require('../../../lib/manager/git-submodules'); -const { - getUpdatedPackageFiles, -} = require('../../../lib/workers/branch/get-updated'); -const defaultConfig = require('../../../lib/config/defaults').getConfig(); -/** @type any */ -const { platform } = require('../../../lib/platform'); +import * as _composer from '../../../lib/manager/composer'; +import * as _npm from '../../../lib/manager/npm'; +import * as _gitSubmodules from '../../../lib/manager/git-submodules'; +import { getUpdatedPackageFiles } from '../../../lib/workers/branch/get-updated'; +import { mocked, defaultConfig, platform } from '../../util'; + +const composer = mocked(_composer); +const gitSubmodules = mocked(_gitSubmodules); +const npm = mocked(_npm); jest.mock('../../../lib/manager/composer'); jest.mock('../../../lib/manager/npm'); @@ -24,7 +21,7 @@ describe('workers/branch/get-updated', () => { upgrades: [], }; npm.updateDependency = jest.fn(); - platform.getFile.mockReturnValueOnce('existing content'); + platform.getFile.mockResolvedValueOnce('existing content'); }); it('handles empty', async () => { const res = await getUpdatedPackageFiles(config); @@ -52,7 +49,7 @@ describe('workers/branch/get-updated', () => { manager: 'composer', }); composer.updateDependency.mockReturnValue('some new content'); - composer.updateArtifacts.mockReturnValue([ + composer.updateArtifacts.mockResolvedValueOnce([ { file: { name: 'composer.json', @@ -69,7 +66,7 @@ describe('workers/branch/get-updated', () => { manager: 'composer', updateType: 'lockFileMaintenance', }); - composer.updateArtifacts.mockReturnValue([ + composer.updateArtifacts.mockResolvedValueOnce([ { file: { name: 'composer.json', @@ -86,10 +83,10 @@ describe('workers/branch/get-updated', () => { manager: 'composer', updateType: 'lockFileMaintenance', }); - composer.updateArtifacts.mockReturnValue([ + composer.updateArtifacts.mockResolvedValueOnce([ { artifactError: { - name: 'composer.lock', + lockFile: 'composer.lock', stderr: 'some error', }, }, @@ -103,10 +100,10 @@ describe('workers/branch/get-updated', () => { manager: 'composer', }); composer.updateDependency.mockReturnValue('some new content'); - composer.updateArtifacts.mockReturnValue([ + composer.updateArtifacts.mockResolvedValueOnce([ { artifactError: { - name: 'composer.lock', + lockFile: 'composer.lock', stderr: 'some error', }, }, @@ -119,7 +116,7 @@ describe('workers/branch/get-updated', () => { manager: 'git-submodules', datasource: 'gitSubmodules', }); - gitSubmodules.updateDependency.mockReturnValue('existing content'); + gitSubmodules.updateDependency.mockResolvedValueOnce('existing content'); const res = await getUpdatedPackageFiles(config); expect(res).toMatchSnapshot(); }); diff --git a/test/workers/branch/index.spec.js b/test/workers/branch/index.spec.ts similarity index 61% rename from test/workers/branch/index.spec.js rename to test/workers/branch/index.spec.ts index aeb6123a3e617940faf001b6eb544e0282cb53cb..cb198a68e19811b38202e1c1b504a49a3f85163f 100644 --- a/test/workers/branch/index.spec.js +++ b/test/workers/branch/index.spec.ts @@ -1,25 +1,15 @@ -const branchWorker = require('../../../lib/workers/branch'); -const defaultConfig = require('../../../lib/config/defaults').getConfig(); - -/** @type any */ -const schedule = require('../../../lib/workers/branch/schedule'); -/** @type any */ -const checkExisting = require('../../../lib/workers/branch/check-existing'); -/** @type any */ -const parent = require('../../../lib/workers/branch/parent'); -/** @type any */ -const npmPostExtract = require('../../../lib/manager/npm/post-update'); -/** @type any */ -const commit = require('../../../lib/workers/branch/commit'); -const statusChecks = require('../../../lib/workers/branch/status-checks'); -/** @type any */ -const automerge = require('../../../lib/workers/branch/automerge'); -/** @type any */ -const prWorker = require('../../../lib/workers/pr'); -/** @type any */ -const getUpdated = require('../../../lib/workers/branch/get-updated'); -/** @type any */ -const { platform } = require('../../../lib/platform'); +import * as branchWorker from '../../../lib/workers/branch'; +import * as _schedule from '../../../lib/workers/branch/schedule'; +import * as _checkExisting from '../../../lib/workers/branch/check-existing'; +import * as _parent from '../../../lib/workers/branch/parent'; +import * as _npmPostExtract from '../../../lib/manager/npm/post-update'; +import * as _commit from '../../../lib/workers/branch/commit'; +import * as _statusChecks from '../../../lib/workers/branch/status-checks'; +import * as _automerge from '../../../lib/workers/branch/automerge'; +import * as _prWorker from '../../../lib/workers/pr'; +import * as _getUpdated from '../../../lib/workers/branch/get-updated'; +import { defaultConfig, platform, mocked } from '../../util'; +import { BranchConfig } from '../../../lib/workers/common'; jest.mock('../../../lib/workers/branch/get-updated'); jest.mock('../../../lib/workers/branch/schedule'); @@ -31,20 +21,36 @@ jest.mock('../../../lib/workers/branch/automerge'); jest.mock('../../../lib/workers/branch/commit'); jest.mock('../../../lib/workers/pr'); +const getUpdated = mocked(_getUpdated); +const schedule = mocked(_schedule); +const checkExisting = mocked(_checkExisting); +const parent = mocked(_parent); +const npmPostExtract = mocked(_npmPostExtract); +const statusChecks = mocked(_statusChecks); +const automerge = mocked(_automerge); +const commit = mocked(_commit); +const prWorker = mocked(_prWorker); + describe('workers/branch', () => { describe('processBranch', () => { - let config; + const updatedPackageFiles: _getUpdated.PackageFilesResult = { + updatedPackageFiles: [], + artifactErrors: [], + updatedArtifacts: [], + }; + let config: BranchConfig; beforeEach(() => { prWorker.ensurePr = jest.fn(); prWorker.checkAutoMerge = jest.fn(); config = { ...defaultConfig, + branchName: 'renovate/some-branch', errors: [], warnings: [], - upgrades: [{ depName: 'some-dep-name' }], - }; + upgrades: [{ depName: 'some-dep-name' } as never], + } as never; schedule.isScheduledNow.mockReturnValue(true); - commit.commitFilesToBranch.mockReturnValue(true); + commit.commitFilesToBranch.mockResolvedValue(true); }); afterEach(() => { platform.ensureComment.mockClear(); @@ -60,7 +66,7 @@ describe('workers/branch', () => { it('skips branch if not scheduled and not updating out of schedule', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); config.updateNotScheduled = false; - platform.branchExists.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); const res = await branchWorker.processBranch(config); expect(res).toEqual('not-scheduled'); }); @@ -69,7 +75,7 @@ describe('workers/branch', () => { config.unpublishSafe = true; config.canBeUnpublished = true; config.prCreation = 'not-pending'; - platform.branchExists.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); const res = await branchWorker.processBranch(config); expect(res).toEqual('pending'); }); @@ -80,7 +86,7 @@ describe('workers/branch', () => { { releaseTimestamp: '2099-12-31', stabilityDays: 1, - }, + } as never, ]; const res = await branchWorker.processBranch(config); expect(res).toEqual('pending'); @@ -88,29 +94,29 @@ describe('workers/branch', () => { it('processes branch if not scheduled but updating out of schedule', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); config.updateNotScheduled = true; - platform.branchExists.mockReturnValueOnce(true); - platform.getBranchPr.mockReturnValueOnce({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ state: 'open', isModified: false, - }); + } as never); await branchWorker.processBranch(config); }); it('skips branch if closed major PR found', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); config.updateType = 'major'; - checkExisting.prAlreadyExisted.mockReturnValueOnce({ + checkExisting.prAlreadyExisted.mockResolvedValueOnce({ number: 13, state: 'closed', - }); + } as never); await branchWorker.processBranch(config); expect(parent.getParentBranch).toHaveBeenCalledTimes(0); }); it('skips branch if closed digest PR found', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); config.updateType = 'digest'; - checkExisting.prAlreadyExisted.mockReturnValueOnce({ + checkExisting.prAlreadyExisted.mockResolvedValueOnce({ number: 13, state: 'closed', }); @@ -119,8 +125,8 @@ describe('workers/branch', () => { }); it('skips branch if closed minor PR found', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); - checkExisting.prAlreadyExisted.mockReturnValueOnce({ + platform.branchExists.mockResolvedValueOnce(true); + checkExisting.prAlreadyExisted.mockResolvedValueOnce({ number: 13, state: 'closed', }); @@ -129,8 +135,8 @@ describe('workers/branch', () => { }); it('skips branch if merged PR found', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); - checkExisting.prAlreadyExisted.mockReturnValueOnce({ + platform.branchExists.mockResolvedValueOnce(true); + checkExisting.prAlreadyExisted.mockResolvedValueOnce({ number: 13, state: 'merged', }); @@ -139,147 +145,147 @@ describe('workers/branch', () => { }); it('throws error if closed PR found', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); - platform.getBranchPr.mockReturnValueOnce({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ state: 'merged', isModified: true, - }); + } as never); await expect(branchWorker.processBranch(config)).rejects.toThrow( /repository-changed/ ); }); it('does not skip branch if edited PR found with rebaseLabel', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); - platform.getBranchPr.mockReturnValueOnce({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ state: 'open', isModified: true, labels: ['rebase'], - }); + } as never); const res = await branchWorker.processBranch(config); expect(res).not.toEqual('pr-edited'); }); it('skips branch if edited PR found', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); - platform.getBranchPr.mockReturnValueOnce({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ state: 'open', isModified: true, - }); + } as never); const res = await branchWorker.processBranch(config); expect(res).toEqual('pr-edited'); }); it('skips branch if target branch changed', async () => { schedule.isScheduledNow.mockReturnValueOnce(false); - platform.branchExists.mockReturnValueOnce(true); - platform.getBranchPr.mockReturnValueOnce({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ state: 'open', isModified: false, targetBranch: 'v6', - }); + } as never); config.baseBranch = 'master'; const res = await branchWorker.processBranch(config); expect(res).toEqual('pr-edited'); }); it('returns if pr creation limit exceeded', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ - updatedPackageFiles: [], + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ + ...updatedPackageFiles, }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [], }); - platform.branchExists.mockReturnValue(false); + platform.branchExists.mockResolvedValue(false); expect(await branchWorker.processBranch(config, true)).toEqual( 'pr-hourly-limit-reached' ); }); it('returns if no work', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ - updatedPackageFiles: [], + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ + ...updatedPackageFiles, }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [], }); - platform.branchExists.mockReturnValueOnce(false); - commit.commitFilesToBranch.mockReturnValueOnce(false); + platform.branchExists.mockResolvedValueOnce(false); + commit.commitFilesToBranch.mockResolvedValueOnce(false); expect(await branchWorker.processBranch(config)).toEqual('no-work'); }); it('returns if branch automerged', async () => { getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ updatedPackageFiles: [{}], - }); + } as never); npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('automerged'); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('automerged'); await branchWorker.processBranch(config); expect(statusChecks.setUnpublishable).toHaveBeenCalledTimes(1); expect(automerge.tryBranchAutomerge).toHaveBeenCalledTimes(1); expect(prWorker.ensurePr).toHaveBeenCalledTimes(0); }); it('returns if branch automerged (dry-run)', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('automerged'); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('automerged'); await branchWorker.processBranch({ ...config, dryRun: true }); expect(statusChecks.setUnpublishable).toHaveBeenCalledTimes(1); expect(automerge.tryBranchAutomerge).toHaveBeenCalledTimes(1); expect(prWorker.ensurePr).toHaveBeenCalledTimes(0); }); it('returns if branch exists and prCreation set to approval', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('failed'); - prWorker.ensurePr.mockReturnValueOnce('needs-pr-approval'); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('failed'); + prWorker.ensurePr.mockResolvedValueOnce('needs-pr-approval'); expect(await branchWorker.processBranch(config)).toEqual( 'needs-pr-approval' ); }); it('ensures PR and tries automerge', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); + } as never); npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('failed'); - prWorker.ensurePr.mockReturnValueOnce({}); - prWorker.checkAutoMerge.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('failed'); + prWorker.ensurePr.mockResolvedValueOnce({} as never); + prWorker.checkAutoMerge.mockResolvedValueOnce(true); await branchWorker.processBranch(config); expect(prWorker.ensurePr).toHaveBeenCalledTimes(1); expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(1); expect(prWorker.checkAutoMerge).toHaveBeenCalledTimes(1); }); it('ensures PR and adds lock file error comment if no releaseTimestamp', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [{}], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('failed'); - prWorker.ensurePr.mockReturnValueOnce({}); - prWorker.checkAutoMerge.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('failed'); + prWorker.ensurePr.mockResolvedValueOnce({} as never); + prWorker.checkAutoMerge.mockResolvedValueOnce(true); await branchWorker.processBranch(config); expect(platform.ensureComment).toHaveBeenCalledTimes(1); // expect(platform.ensureCommentRemoval.mock.calls).toHaveLength(0); @@ -287,17 +293,17 @@ describe('workers/branch', () => { expect(prWorker.checkAutoMerge).toHaveBeenCalledTimes(0); }); it('ensures PR and adds lock file error comment if old releaseTimestamp', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [{}], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('failed'); - prWorker.ensurePr.mockReturnValueOnce({}); - prWorker.checkAutoMerge.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('failed'); + prWorker.ensurePr.mockResolvedValueOnce({} as never); + prWorker.checkAutoMerge.mockResolvedValueOnce(true); config.releaseTimestamp = '2018-04-26T05:15:51.877Z'; await branchWorker.processBranch(config); expect(platform.ensureComment).toHaveBeenCalledTimes(1); @@ -306,17 +312,17 @@ describe('workers/branch', () => { expect(prWorker.checkAutoMerge).toHaveBeenCalledTimes(0); }); it('ensures PR and adds lock file error comment if new releaseTimestamp and branch exists', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [{}], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('failed'); - prWorker.ensurePr.mockReturnValueOnce({}); - prWorker.checkAutoMerge.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('failed'); + prWorker.ensurePr.mockResolvedValueOnce({} as never); + prWorker.checkAutoMerge.mockResolvedValueOnce(true); config.releaseTimestamp = new Date().toISOString(); await branchWorker.processBranch(config); expect(platform.ensureComment).toHaveBeenCalledTimes(1); @@ -325,35 +331,35 @@ describe('workers/branch', () => { expect(prWorker.checkAutoMerge).toHaveBeenCalledTimes(0); }); it('throws error if lock file errors and new releaseTimestamp', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [{}], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(false); - automerge.tryBranchAutomerge.mockReturnValueOnce('failed'); - prWorker.ensurePr.mockReturnValueOnce({}); - prWorker.checkAutoMerge.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(false); + automerge.tryBranchAutomerge.mockResolvedValueOnce('failed'); + prWorker.ensurePr.mockResolvedValueOnce({} as never); + prWorker.checkAutoMerge.mockResolvedValueOnce(true); config.releaseTimestamp = new Date().toISOString(); await expect(branchWorker.processBranch(config)).rejects.toThrow( Error('lockfile-error') ); }); it('ensures PR and adds lock file error comment recreate closed', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [{}], updatedArtifacts: [{}], - }); + } as never); config.recreateClosed = true; - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce('failed'); - prWorker.ensurePr.mockReturnValueOnce({}); - prWorker.checkAutoMerge.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce('failed'); + prWorker.ensurePr.mockResolvedValueOnce({} as never); + prWorker.checkAutoMerge.mockResolvedValueOnce(true); await branchWorker.processBranch(config); expect(platform.ensureComment).toHaveBeenCalledTimes(1); // expect(platform.ensureCommentRemoval.mock.calls).toHaveLength(0); @@ -367,25 +373,25 @@ describe('workers/branch', () => { await branchWorker.processBranch(config); }); it('throws and swallows branch errors', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [{}], updatedArtifacts: [{}], - }); + } as never); await branchWorker.processBranch(config); }); it('swallows pr errors', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); - automerge.tryBranchAutomerge.mockReturnValueOnce(false); + } as never); + platform.branchExists.mockResolvedValueOnce(true); + automerge.tryBranchAutomerge.mockResolvedValueOnce(false as never); prWorker.ensurePr.mockImplementationOnce(() => { throw new Error('some error'); }); @@ -393,7 +399,7 @@ describe('workers/branch', () => { }); it('closed pr (dry run)', async () => { - platform.branchExists.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); checkExisting.prAlreadyExisted.mockResolvedValueOnce({ state: 'closed' }); expect( await branchWorker.processBranch({ ...config, dryRun: true }) @@ -401,35 +407,35 @@ describe('workers/branch', () => { }); it('branch pr no rebase (dry run)', async () => { - platform.branchExists.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); platform.getBranchPr.mockResolvedValueOnce({ state: 'open', isModified: true, - }); + } as never); expect( await branchWorker.processBranch({ ...config, dryRun: true }) ).toEqual('pr-edited'); }); it('branch pr no schedule lockfile (dry run)', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], artifactErrors: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(true); platform.getBranchPr.mockResolvedValueOnce({ title: 'rebase!', state: 'open', body: `- [x] <!-- rebase-check -->`, isModified: true, - }); + } as never); schedule.isScheduledNow.mockReturnValueOnce(false); - commit.commitFilesToBranch.mockReturnValueOnce(false); + commit.commitFilesToBranch.mockResolvedValueOnce(false); expect( await branchWorker.processBranch({ @@ -443,24 +449,24 @@ describe('workers/branch', () => { }); it('branch pr no schedule (dry run)', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], artifactErrors: [{}], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(true); platform.getBranchPr.mockResolvedValueOnce({ title: 'rebase!', state: 'open', body: `- [x] <!-- rebase-check -->`, isModified: true, - }); + } as never); schedule.isScheduledNow.mockReturnValueOnce(false); - prWorker.ensurePr.mockResolvedValueOnce({}); + prWorker.ensurePr.mockResolvedValueOnce({} as never); expect( await branchWorker.processBranch({ ...config, @@ -471,24 +477,24 @@ describe('workers/branch', () => { }); it('branch pr no schedule', async () => { - getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({ + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ updatedPackageFiles: [{}], artifactErrors: [], - }); - npmPostExtract.getAdditionalFiles.mockReturnValueOnce({ + } as never); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ artifactErrors: [], updatedArtifacts: [{}], - }); - platform.branchExists.mockReturnValueOnce(true); + } as never); + platform.branchExists.mockResolvedValueOnce(true); platform.getBranchPr.mockResolvedValueOnce({ title: 'rebase!', state: 'open', body: `- [x] <!-- rebase-check -->`, isModified: true, - }); + } as never); schedule.isScheduledNow.mockReturnValueOnce(false); - commit.commitFilesToBranch.mockReturnValueOnce(false); + commit.commitFilesToBranch.mockResolvedValueOnce(false); expect( await branchWorker.processBranch({ ...config, diff --git a/test/workers/branch/lock-files/__snapshots__/index.spec.js.snap b/test/workers/branch/lock-files/__snapshots__/index.spec.ts.snap similarity index 100% rename from test/workers/branch/lock-files/__snapshots__/index.spec.js.snap rename to test/workers/branch/lock-files/__snapshots__/index.spec.ts.snap diff --git a/test/workers/branch/lock-files/index.spec.js b/test/workers/branch/lock-files/index.spec.ts similarity index 91% rename from test/workers/branch/lock-files/index.spec.js rename to test/workers/branch/lock-files/index.spec.ts index 2bde468b776c21979bf1b6f52176eff9bdcca579..8fe3f66e56c365777abb2dd62960e41ef38562b0 100644 --- a/test/workers/branch/lock-files/index.spec.js +++ b/test/workers/branch/lock-files/index.spec.ts @@ -1,23 +1,26 @@ -/** @type any */ -const fs = require('fs-extra'); -const lockFiles = require('../../../../lib/manager/npm/post-update'); -const defaultConfig = require('../../../../lib/config/defaults').getConfig(); -// const upath = require('upath'); +import _fs from 'fs-extra'; +import * as _lockFiles from '../../../../lib/manager/npm/post-update'; +import { getConfig } from '../../../../lib/config/defaults'; +import * as _npm from '../../../../lib/manager/npm/post-update/npm'; +import * as _yarn from '../../../../lib/manager/npm/post-update/yarn'; +import * as _pnpm from '../../../../lib/manager/npm/post-update/pnpm'; +import * as _lerna from '../../../../lib/manager/npm/post-update/lerna'; +import * as _hostRules from '../../../../lib/util/host-rules'; +import { platform as _platform } from '../../../../lib/platform'; +import { mocked } from '../../../util'; -/** @type any */ -const npm = require('../../../../lib/manager/npm/post-update/npm'); -/** @type any */ -const yarn = require('../../../../lib/manager/npm/post-update/yarn'); -/** @type any */ -const pnpm = require('../../../../lib/manager/npm/post-update/pnpm'); -const lerna = require('../../../../lib/manager/npm/post-update/lerna'); +const defaultConfig = getConfig(); -const hostRules = require('../../../../lib/util/host-rules'); +const fs = mocked(_fs); +const lockFiles = mocked(_lockFiles); +const npm = mocked(_npm); +const yarn = mocked(_yarn); +const pnpm = mocked(_pnpm); +const lerna = mocked(_lerna); +const hostRules = mocked(_hostRules); +const platform = mocked(_platform); -/** @type any */ -const { platform } = require('../../../../lib/platform'); - -hostRules.find = jest.fn(() => ({ +hostRules.find = jest.fn(_ => ({ token: 'abc', })); @@ -301,17 +304,17 @@ describe('manager/npm/post-update', () => { ...defaultConfig, localDir: 'some-tmp-dir', }; - platform.getFile.mockReturnValue('some lock file contents'); + platform.getFile.mockResolvedValueOnce('some lock file contents'); npm.generateLockFile = jest.fn(); - npm.generateLockFile.mockReturnValue({ + npm.generateLockFile.mockResolvedValueOnce({ lockFile: 'some lock file contents', }); yarn.generateLockFile = jest.fn(); - yarn.generateLockFile.mockReturnValue({ + yarn.generateLockFile.mockResolvedValueOnce({ lockFile: 'some lock file contents', }); pnpm.generateLockFile = jest.fn(); - pnpm.generateLockFile.mockReturnValue({ + pnpm.generateLockFile.mockResolvedValueOnce({ lockFile: 'some lock file contents', }); lerna.generateLockFiles = jest.fn(); @@ -330,7 +333,7 @@ describe('manager/npm/post-update', () => { it('returns no error and empty lockfiles if lock file maintenance exists', async () => { config.updateType = 'lockFileMaintenance'; config.parentBranch = 'renovate/lock-file-maintenance'; - platform.branchExists.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); const res = await getAdditionalFiles(config, { npm: [{}] }); expect(res).toMatchSnapshot(); expect(res.artifactErrors).toHaveLength(0); diff --git a/test/workers/branch/lock-files/lerna.spec.js b/test/workers/branch/lock-files/lerna.spec.ts similarity index 67% rename from test/workers/branch/lock-files/lerna.spec.js rename to test/workers/branch/lock-files/lerna.spec.ts index d87e679059708da71da42f2165823bb05ad787cd..4efabd08485f5e721cdb6ee145d6360df8540394 100644 --- a/test/workers/branch/lock-files/lerna.spec.js +++ b/test/workers/branch/lock-files/lerna.spec.ts @@ -1,21 +1,24 @@ -/** @type any */ -const { exec } = require('../../../../lib/util/exec'); -const lernaHelper = require('../../../../lib/manager/npm/post-update/lerna'); -/** @type any */ -const { platform } = require('../../../../lib/platform'); +import * as _exec from '../../../../lib/util/exec'; +import * as _lernaHelper from '../../../../lib/manager/npm/post-update/lerna'; +import { platform as _platform } from '../../../../lib/platform'; +import { mocked } from '../../../util'; jest.mock('../../../../lib/util/exec'); +const exec = mocked(_exec).exec; +const lernaHelper = mocked(_lernaHelper); +const platform = mocked(_platform); + describe('generateLockFiles()', () => { it('returns if no lernaClient', async () => { const res = await lernaHelper.generateLockFiles(undefined, 'some-dir', {}); expect(res.error).toBe(false); }); it('generates package-lock.json files', async () => { - platform.getFile.mockReturnValueOnce( + platform.getFile.mockResolvedValueOnce( JSON.stringify({ dependencies: { lerna: '2.0.0' } }) ); - exec.mockReturnValueOnce({}); + exec.mockResolvedValueOnce({} as never); const skipInstalls = true; const res = await lernaHelper.generateLockFiles( 'npm', @@ -26,10 +29,10 @@ describe('generateLockFiles()', () => { expect(res.error).toBe(false); }); it('performs full npm install', async () => { - platform.getFile.mockReturnValueOnce( + platform.getFile.mockResolvedValueOnce( JSON.stringify({ dependencies: { lerna: '2.0.0' } }) ); - exec.mockReturnValueOnce({}); + exec.mockResolvedValueOnce({} as never); const skipInstalls = false; const binarySource = 'global'; const res = await lernaHelper.generateLockFiles( @@ -42,16 +45,16 @@ describe('generateLockFiles()', () => { expect(res.error).toBe(false); }); it('generates yarn.lock files', async () => { - platform.getFile.mockReturnValueOnce( + platform.getFile.mockResolvedValueOnce( JSON.stringify({ devDependencies: { lerna: '2.0.0' } }) ); - exec.mockReturnValueOnce({}); + exec.mockResolvedValueOnce({} as never); const res = await lernaHelper.generateLockFiles('yarn', 'some-dir', {}); expect(res.error).toBe(false); }); it('defaults to latest', async () => { platform.getFile.mockReturnValueOnce(undefined); - exec.mockReturnValueOnce({}); + exec.mockResolvedValueOnce({} as never); const res = await lernaHelper.generateLockFiles('npm', 'some-dir', {}); expect(res.error).toBe(false); }); diff --git a/test/workers/branch/lock-files/npm.spec.js b/test/workers/branch/lock-files/npm.spec.ts similarity index 77% rename from test/workers/branch/lock-files/npm.spec.js rename to test/workers/branch/lock-files/npm.spec.ts index b2d021eb990425e94696c7dd80b5fe1da94c17e9..2cfcc7e81412dfd6464dc20fd6a65f6b76142950 100644 --- a/test/workers/branch/lock-files/npm.spec.js +++ b/test/workers/branch/lock-files/npm.spec.ts @@ -1,30 +1,30 @@ -const { getInstalledPath } = require('get-installed-path'); +import { getInstalledPath } from 'get-installed-path'; +import path from 'path'; +import _fs from 'fs-extra'; +import * as _exec from '../../../../lib/util/exec'; +import * as npmHelper from '../../../../lib/manager/npm/post-update/npm'; +import { mocked } from '../../../util'; jest.mock('fs-extra'); jest.mock('../../../../lib/util/exec'); jest.mock('get-installed-path'); getInstalledPath.mockImplementation(() => null); - -const path = require('path'); -/** @type any */ -const fs = require('fs-extra'); -/** @type any */ -const { exec } = require('../../../../lib/util/exec'); -const npmHelper = require('../../../../lib/manager/npm/post-update/npm'); +const exec = mocked(_exec).exec; +const fs = mocked(_fs); describe('generateLockFile', () => { it('generates lock files', async () => { getInstalledPath.mockReturnValueOnce('node_modules/npm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = true; const postUpdateOptions = ['npmDedupe']; const res = await npmHelper.generateLockFile( @@ -39,15 +39,15 @@ describe('generateLockFile', () => { }); it('performs lock file updates', async () => { getInstalledPath.mockReturnValueOnce('node_modules/npm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = true; const updates = [ { depName: 'some-dep', toVersion: '1.0.1', isLockfileUpdate: true }, @@ -65,17 +65,17 @@ describe('generateLockFile', () => { }); it('performs npm-shrinkwrap.json updates', async () => { getInstalledPath.mockReturnValueOnce('node_modules/npm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.pathExists.mockResolvedValueOnce(true); + fs.pathExists.mockImplementationOnce(() => true); fs.move = jest.fn(); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', @@ -101,17 +101,17 @@ describe('generateLockFile', () => { }); it('performs npm-shrinkwrap.json updates (no package-lock.json)', async () => { getInstalledPath.mockReturnValueOnce('node_modules/npm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.pathExists.mockResolvedValueOnce(false); + fs.pathExists.mockImplementationOnce(() => false); fs.move = jest.fn(); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn((_, _1) => 'package-lock-contents') as never; const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', @@ -133,11 +133,11 @@ describe('generateLockFile', () => { }); it('performs full install', async () => { getInstalledPath.mockReturnValueOnce('node_modules/npm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = false; const binarySource = 'global'; const res = await npmHelper.generateLockFile( @@ -152,13 +152,13 @@ describe('generateLockFile', () => { }); it('catches errors', async () => { getInstalledPath.mockReturnValueOnce('node_modules/npm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: 'some-error', + stderr: 'some-error', }); fs.readFile = jest.fn(() => { throw new Error('not found'); - }); + }) as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, @@ -176,11 +176,11 @@ describe('generateLockFile', () => { getInstalledPath.mockImplementationOnce( () => '/node_modules/renovate/node_modules/npm' ); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, @@ -198,11 +198,11 @@ describe('generateLockFile', () => { throw new Error('not found'); }); getInstalledPath.mockImplementationOnce(() => '/node_modules/npm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, @@ -222,11 +222,11 @@ describe('generateLockFile', () => { getInstalledPath.mockImplementationOnce(() => { throw new Error('not found'); }); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, diff --git a/test/workers/branch/lock-files/pnpm.spec.js b/test/workers/branch/lock-files/pnpm.spec.ts similarity index 75% rename from test/workers/branch/lock-files/pnpm.spec.js rename to test/workers/branch/lock-files/pnpm.spec.ts index 25dec87c6afa918fe3b26753664923c7df7e75a8..755771c749e6ad6ff893e48f14c7e24541f7073f 100644 --- a/test/workers/branch/lock-files/pnpm.spec.js +++ b/test/workers/branch/lock-files/pnpm.spec.ts @@ -1,4 +1,8 @@ -const { getInstalledPath } = require('get-installed-path'); +import { getInstalledPath } from 'get-installed-path'; +import _fs from 'fs-extra'; +import * as _exec from '../../../../lib/util/exec'; +import { mocked } from '../../../util'; +import * as _pnpmHelper from '../../../../lib/manager/npm/post-update/pnpm'; jest.mock('fs-extra'); jest.mock('../../../../lib/util/exec'); @@ -6,11 +10,9 @@ jest.mock('get-installed-path'); getInstalledPath.mockImplementation(() => null); -/** @type any */ -const fs = require('fs-extra'); -/** @type any */ -const { exec } = require('../../../../lib/util/exec'); -const pnpmHelper = require('../../../../lib/manager/npm/post-update/pnpm'); +const exec = mocked(_exec).exec; +const fs = mocked(_fs); +const pnpmHelper = mocked(_pnpmHelper); describe('generateLockFile', () => { let env; @@ -20,22 +22,22 @@ describe('generateLockFile', () => { }); it('generates lock files', async () => { getInstalledPath.mockReturnValueOnce('node_modules/pnpm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', env, config); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toEqual('package-lock-contents'); }); it('uses docker pnpm', async () => { getInstalledPath.mockReturnValueOnce('node_modules/pnpm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; config.binarySource = 'docker'; const res = await pnpmHelper.generateLockFile('some-dir', env, config); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -43,13 +45,13 @@ describe('generateLockFile', () => { }); it('catches errors', async () => { getInstalledPath.mockReturnValueOnce('node_modules/pnpm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: 'some-error', + stderr: 'some-error', }); fs.readFile = jest.fn(() => { throw new Error('not found'); - }); + }) as never; const res = await pnpmHelper.generateLockFile('some-dir', env, config); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBe(true); @@ -63,11 +65,11 @@ describe('generateLockFile', () => { getInstalledPath.mockImplementationOnce( () => '/node_modules/renovate/node_modules/pnpm' ); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', env, config); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toEqual('package-lock-contents'); @@ -81,11 +83,11 @@ describe('generateLockFile', () => { throw new Error('not found'); }); getInstalledPath.mockImplementationOnce(() => '/node_modules/pnpm'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', env, config); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toEqual('package-lock-contents'); @@ -101,11 +103,11 @@ describe('generateLockFile', () => { getInstalledPath.mockImplementationOnce(() => { throw new Error('not found'); }); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', - stderror: '', + stderr: '', }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; config.binarySource = 'global'; const res = await pnpmHelper.generateLockFile('some-dir', env, config); expect(fs.readFile).toHaveBeenCalledTimes(1); diff --git a/test/workers/branch/lock-files/yarn.spec.js b/test/workers/branch/lock-files/yarn.spec.ts similarity index 82% rename from test/workers/branch/lock-files/yarn.spec.js rename to test/workers/branch/lock-files/yarn.spec.ts index 77d0e1a6c7764e75c43865ba445ce75433568edd..8000617f5585c3d5d64568ab2cdfa615a7fb3d90 100644 --- a/test/workers/branch/lock-files/yarn.spec.js +++ b/test/workers/branch/lock-files/yarn.spec.ts @@ -1,4 +1,8 @@ -const { getInstalledPath } = require('get-installed-path'); +import { getInstalledPath } from 'get-installed-path'; +import _fs from 'fs-extra'; +import * as _exec from '../../../../lib/util/exec'; +import * as _yarnHelper from '../../../../lib/manager/npm/post-update/yarn'; +import { mocked } from '../../../util'; jest.mock('fs-extra'); jest.mock('../../../../lib/util/exec'); @@ -6,11 +10,9 @@ jest.mock('get-installed-path'); getInstalledPath.mockImplementation(() => null); -/** @type any */ -const fs = require('fs-extra'); -/** @type any */ -const { exec } = require('../../../../lib/util/exec'); -const yarnHelper = require('../../../../lib/manager/npm/post-update/yarn'); +const exec = mocked(_exec).exec; +const fs = mocked(_fs); +const yarnHelper = mocked(_yarnHelper); describe('generateLockFile', () => { beforeEach(() => { @@ -23,7 +25,7 @@ describe('generateLockFile', () => { }); it('generates lock files', async () => { getInstalledPath.mockReturnValueOnce('node_modules/yarn'); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; /** @type {NodeJS.ProcessEnv} */ const env = {}; const config = { @@ -36,7 +38,7 @@ describe('generateLockFile', () => { it('performs lock file updates', async () => { getInstalledPath.mockReturnValueOnce('node_modules/yarn'); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; process.env.YARN_MUTEX_FILE = '/tmp/yarn.mutext'; const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [ { depName: 'some-dep', isLockfileUpdate: true }, @@ -45,7 +47,7 @@ describe('generateLockFile', () => { }); it('detects yarnIntegrity', async () => { getInstalledPath.mockReturnValueOnce('node_modules/yarn'); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const config = { upgrades: [{ yarnIntegrity: true }], }; @@ -56,13 +58,13 @@ describe('generateLockFile', () => { }); it('catches errors', async () => { getInstalledPath.mockReturnValueOnce('node_modules/yarn'); - exec.mockReturnValueOnce({ + exec.mockResolvedValueOnce({ stdout: '', stderr: 'some-error', }); fs.readFile = jest.fn(() => { throw new Error('not found'); - }); + }) as never; const res = await yarnHelper.generateLockFile('some-dir'); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBe(true); @@ -76,7 +78,7 @@ describe('generateLockFile', () => { getInstalledPath.mockImplementationOnce( () => '/node_modules/renovate/node_modules/yarn' ); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await yarnHelper.generateLockFile('some-dir'); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toEqual('package-lock-contents'); @@ -90,7 +92,7 @@ describe('generateLockFile', () => { throw new Error('not found'); }); getInstalledPath.mockImplementationOnce(() => '/node_modules/yarn'); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await yarnHelper.generateLockFile('some-dir'); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toEqual('package-lock-contents'); @@ -106,7 +108,7 @@ describe('generateLockFile', () => { getInstalledPath.mockImplementationOnce(() => { throw new Error('not found'); }); - fs.readFile = jest.fn(() => 'package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await yarnHelper.generateLockFile('some-dir', undefined, { binarySource: 'global', }); diff --git a/test/workers/branch/parent.spec.js b/test/workers/branch/parent.spec.ts similarity index 66% rename from test/workers/branch/parent.spec.js rename to test/workers/branch/parent.spec.ts index b87d969d3b182dc56b8e2760289eb1a58cd573b5..9845839406b237382e7e03d3bff2b4f04898f827 100644 --- a/test/workers/branch/parent.spec.js +++ b/test/workers/branch/parent.spec.ts @@ -1,10 +1,12 @@ -const { getParentBranch } = require('../../../lib/workers/branch/parent'); -/** @type any */ -const { platform } = require('../../../lib/platform'); +import { getParentBranch } from '../../../lib/workers/branch/parent'; +import { platform } from '../../util'; +import { RenovateConfig } from '../../../lib/config'; +import { Pr } from '../../../lib/platform'; describe('workers/branch/parent', () => { describe('getParentBranch(config)', () => { - let config; + const pr: Pr = { branchName: 'master', state: 'open', title: 'any' }; + let config: RenovateConfig; beforeEach(() => { config = { branchName: 'renovate/some-branch', @@ -16,27 +18,29 @@ describe('workers/branch/parent', () => { jest.resetAllMocks(); }); it('returns undefined if branch does not exist', async () => { - platform.branchExists.mockReturnValue(false); + platform.branchExists.mockResolvedValueOnce(false); const res = await getParentBranch(config); expect(res.parentBranch).toBeUndefined(); }); it('returns branchName if no PR', async () => { - platform.branchExists.mockReturnValue(true); + platform.branchExists.mockResolvedValueOnce(true); platform.getBranchPr.mockReturnValue(null); const res = await getParentBranch(config); expect(res.parentBranch).toBe(config.branchName); }); it('returns branchName if does not need rebaseing', async () => { - platform.branchExists.mockReturnValue(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, isConflicted: false, }); const res = await getParentBranch(config); expect(res.parentBranch).toBe(config.branchName); }); it('returns branchName if unmergeable and cannot rebase', async () => { - platform.branchExists.mockReturnValue(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, isConflicted: true, isModified: true, }); @@ -45,8 +49,9 @@ describe('workers/branch/parent', () => { }); it('returns branchName if unmergeable and can rebase, but rebaseConflictedPrs is disabled', async () => { config.rebaseConflictedPrs = false; - platform.branchExists.mockReturnValue(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, isConflicted: true, isModified: false, }); @@ -54,16 +59,18 @@ describe('workers/branch/parent', () => { expect(res.parentBranch).toBe(config.branchName); }); it('returns undefined if PR title rebase!', async () => { - platform.branchExists.mockReturnValue(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, title: 'rebase!Update foo to v4', }); const res = await getParentBranch(config); expect(res.parentBranch).toBeUndefined(); }); it('returns undefined if PR body check rebase', async () => { - platform.branchExists.mockReturnValue(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, title: 'Update foo to v4', body: 'blah\nblah\n- [x] <!-- rebase-check -->foo\n', }); @@ -71,8 +78,9 @@ describe('workers/branch/parent', () => { expect(res.parentBranch).toBeUndefined(); }); it('returns undefined if manual rebase by label', async () => { - platform.branchExists.mockReturnValue(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, isModified: true, labels: ['rebase'], }); @@ -80,8 +88,9 @@ describe('workers/branch/parent', () => { expect(res.parentBranch).toBeUndefined(); }); it('returns undefined if unmergeable and can rebase', async () => { - platform.branchExists.mockReturnValue(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, isConflicted: true, isModified: false, }); @@ -91,23 +100,24 @@ describe('workers/branch/parent', () => { it('returns branchName if automerge branch and not stale', async () => { config.automerge = true; config.automergeType = 'branch'; - platform.branchExists.mockReturnValue(true); + platform.branchExists.mockResolvedValueOnce(true); const res = await getParentBranch(config); expect(res.parentBranch).toBe(config.branchName); }); it('returns undefined if automerge branch and stale', async () => { config.automerge = true; config.automergeType = 'branch'; - platform.branchExists.mockReturnValue(true); - platform.isBranchStale.mockReturnValueOnce(true); + platform.branchExists.mockResolvedValueOnce(true); + platform.isBranchStale.mockResolvedValueOnce(true); const res = await getParentBranch(config); expect(res.parentBranch).toBeUndefined(); }); it('returns branch if rebaseStalePrs enabled but cannot rebase', async () => { config.rebaseStalePrs = true; - platform.branchExists.mockReturnValue(true); - platform.isBranchStale.mockReturnValueOnce(true); - platform.getBranchPr.mockReturnValue({ + platform.branchExists.mockResolvedValueOnce(true); + platform.isBranchStale.mockResolvedValueOnce(true); + platform.getBranchPr.mockResolvedValueOnce({ + ...pr, isConflicted: true, isModified: true, }); diff --git a/test/workers/branch/schedule.spec.js b/test/workers/branch/schedule.spec.ts similarity index 98% rename from test/workers/branch/schedule.spec.js rename to test/workers/branch/schedule.spec.ts index 013ebc89daf0540116aaaa2fd0d59c4c890e76a8..fb3b60b9a7d168b52553fc19b4fbbc50e01be73f 100644 --- a/test/workers/branch/schedule.spec.js +++ b/test/workers/branch/schedule.spec.ts @@ -1,6 +1,5 @@ -/** @type any */ -const mockDate = require('mockdate'); -const schedule = require('../../../lib/workers/branch/schedule'); +import mockDate from 'mockdate'; +import * as schedule from '../../../lib/workers/branch/schedule'; describe('workers/branch/schedule', () => { describe('hasValidTimezone(schedule)', () => { diff --git a/test/workers/branch/status-checks.spec.js b/test/workers/branch/status-checks.spec.ts similarity index 85% rename from test/workers/branch/status-checks.spec.js rename to test/workers/branch/status-checks.spec.ts index b5e80f0e7e52cb1cdfb7d62e9f8968699d5946d2..0d8916977f2bde043d78495b4d11e5113558a5dd 100644 --- a/test/workers/branch/status-checks.spec.js +++ b/test/workers/branch/status-checks.spec.ts @@ -1,18 +1,18 @@ -const { +import { setStability, setUnpublishable, -} = require('../../../lib/workers/branch/status-checks'); -const defaultConfig = require('../../../lib/config/defaults').getConfig(); - -/** @type any */ -const { platform } = require('../../../lib/platform'); + StabilityConfig, + UnpublishableConfig, +} from '../../../lib/workers/branch/status-checks'; +import { defaultConfig, platform } from '../../util'; describe('workers/branch/status-checks', () => { describe('setStability', () => { - let config; + let config: StabilityConfig; beforeEach(() => { config = { ...defaultConfig, + branchName: 'renovate/some-branch', }; }); afterEach(() => { @@ -36,10 +36,11 @@ describe('workers/branch/status-checks', () => { }); }); describe('setUnpublishable', () => { - let config; + let config: UnpublishableConfig; beforeEach(() => { config = { ...defaultConfig, + branchName: 'renovate/some-branch', }; }); afterEach(() => { @@ -65,7 +66,7 @@ describe('workers/branch/status-checks', () => { it('finds canBeUnpublished false and skips status', async () => { config.unpublishSafe = true; config.canBeUnpublished = false; - platform.getBranchStatusCheck.mockReturnValueOnce('success'); + platform.getBranchStatusCheck.mockResolvedValueOnce('success'); await setUnpublishable(config); expect(platform.getBranchStatusCheck).toHaveBeenCalledTimes(1); expect(platform.setBranchStatus).toHaveBeenCalledTimes(0);