import { mock } from 'jest-mock-extended'; import type { SimpleGit } from 'simple-git'; import { simpleGit } from 'simple-git'; import type { DirectoryResult } from 'tmp-promise'; import { dir } from 'tmp-promise'; import { join } from 'upath'; import { fs } from '../../../../test/util'; import { GlobalConfig } from '../../../config/global'; import type { RepoGlobalConfig } from '../../../config/types'; import * as hostRules from '../../../util/host-rules'; import type { Upgrade } from '../types'; import { updateDependency } from '.'; jest.mock('../../../util/fs'); jest.mock('simple-git'); const simpleGitFactoryMock = simpleGit as jest.Mock<Partial<SimpleGit>>; const gitMock = mock<SimpleGit>(); describe('modules/manager/git-submodules/update', () => { beforeEach(() => { GlobalConfig.set({ localDir: `${__dirname}/__fixtures__` }); // clear host rules hostRules.clear(); // clear environment variables process.env = {}; simpleGitFactoryMock.mockReturnValue(gitMock); gitMock.env.mockImplementation(() => gitMock); }); describe('updateDependency', () => { let upgrade: Upgrade; let adminConfig: RepoGlobalConfig; let tmpDir: DirectoryResult; beforeAll(async () => { upgrade = { depName: 'renovate' }; tmpDir = await dir({ unsafeCleanup: true }); adminConfig = { localDir: join(tmpDir.path) }; GlobalConfig.set(adminConfig); }); afterAll(async () => { await tmpDir.cleanup(); GlobalConfig.reset(); }); it('returns null on error', async () => { gitMock.submoduleUpdate.mockRejectedValue(new Error()); const update = await updateDependency({ fileContent: '', upgrade, }); expect(update).toBeNull(); }); it('returns content on update', async () => { gitMock.submoduleUpdate.mockResolvedValue(''); gitMock.checkout.mockResolvedValue(''); const update = await updateDependency({ fileContent: '', upgrade, }); expect(update).toBe(''); }); it('returns content on update and uses git environment variables', async () => { gitMock.submoduleUpdate.mockResolvedValue(''); gitMock.checkout.mockResolvedValue(''); hostRules.add({ hostType: 'github', matchHost: 'github.com', token: 'abc123', }); const update = await updateDependency({ fileContent: '', upgrade, }); expect(update).toBe(''); expect(gitMock.env).toHaveBeenCalledWith({ GIT_CONFIG_COUNT: '3', GIT_CONFIG_KEY_0: 'url.https://ssh:abc123@github.com/.insteadOf', GIT_CONFIG_KEY_1: 'url.https://git:abc123@github.com/.insteadOf', GIT_CONFIG_KEY_2: 'url.https://abc123@github.com/.insteadOf', GIT_CONFIG_VALUE_0: 'ssh://git@github.com/', GIT_CONFIG_VALUE_1: 'git@github.com:', GIT_CONFIG_VALUE_2: 'https://github.com/', }); }); it('update gitmodule branch value if value changed', async () => { gitMock.submoduleUpdate.mockResolvedValue(''); gitMock.checkout.mockResolvedValue(''); const updatedGitModules = `[submodule "renovate"] path = deps/renovate url = https://github.com/renovatebot/renovate.git branch = v0.0.2`; fs.readLocalFile.mockResolvedValueOnce(updatedGitModules); upgrade = { depName: 'renovate', currentValue: 'v0.0.1', newValue: 'v0.0.2', packageFile: '.gitmodules', }; const update = await updateDependency({ fileContent: '', upgrade, }); expect(update).toBe(updatedGitModules); expect(gitMock.subModule).toHaveBeenCalledWith([ 'set-branch', '--branch', 'v0.0.2', 'renovate', ]); }); it('do not update gitmodule branch value if value not changed', async () => { gitMock.submoduleUpdate.mockResolvedValue(''); gitMock.checkout.mockResolvedValue(''); upgrade = { depName: 'renovate', currentValue: 'main', newValue: 'main', packageFile: '.gitmodules', }; const update = await updateDependency({ fileContent: '', upgrade, }); expect(update).toBe(''); expect(gitMock.subModule).toHaveBeenCalledTimes(0); }); it('returns content on update and uses git environment variables for git-tags/git-refs', async () => { gitMock.submoduleUpdate.mockResolvedValue(''); gitMock.checkout.mockResolvedValue(''); hostRules.add({ hostType: 'git-refs', matchHost: 'gitrefs.com', username: 'git-refs-user', password: 'git-refs-password', }); hostRules.add({ hostType: 'git-tags', matchHost: 'gittags.com', username: 'git-tags-user', password: 'git-tags-password', }); const update = await updateDependency({ fileContent: '', upgrade, }); expect(update).toBe(''); expect(gitMock.env).toHaveBeenCalledWith({ GIT_CONFIG_COUNT: '6', GIT_CONFIG_KEY_0: 'url.https://git-refs-user:git-refs-password@gitrefs.com/.insteadOf', GIT_CONFIG_KEY_1: 'url.https://git-refs-user:git-refs-password@gitrefs.com/.insteadOf', GIT_CONFIG_KEY_2: 'url.https://git-refs-user:git-refs-password@gitrefs.com/.insteadOf', GIT_CONFIG_KEY_3: 'url.https://git-tags-user:git-tags-password@gittags.com/.insteadOf', GIT_CONFIG_KEY_4: 'url.https://git-tags-user:git-tags-password@gittags.com/.insteadOf', GIT_CONFIG_KEY_5: 'url.https://git-tags-user:git-tags-password@gittags.com/.insteadOf', GIT_CONFIG_VALUE_0: 'ssh://git@gitrefs.com/', GIT_CONFIG_VALUE_1: 'git@gitrefs.com:', GIT_CONFIG_VALUE_2: 'https://gitrefs.com/', GIT_CONFIG_VALUE_3: 'ssh://git@gittags.com/', GIT_CONFIG_VALUE_4: 'git@gittags.com:', GIT_CONFIG_VALUE_5: 'https://gittags.com/', }); }); }); });