Files
renovate/lib/modules/platform/codecommit/index.spec.ts
Sebastian Poxhofer 05e1271376 test: use expect().resolves instead of awaiting inside expect (#45672)
Enables the vitest/prefer-expect-resolves oxlint rule and applies its
autofix across the spec suite.
2026-09-04 10:40:46 +00:00

1275 lines
38 KiB
TypeScript

import {
CodeCommitClient,
CreatePullRequestApprovalRuleCommand,
CreatePullRequestCommand,
type CreatePullRequestOutput,
DeleteCommentContentCommand,
GetCommentsForPullRequestCommand,
GetFileCommand,
GetPullRequestCommand,
type GetPullRequestOutput,
GetRepositoryCommand,
ListPullRequestsCommand,
ListRepositoriesCommand,
PostCommentForPullRequestCommand,
PullRequestStatusEnum,
UpdatePullRequestDescriptionCommand,
UpdatePullRequestStatusCommand,
UpdatePullRequestTitleCommand,
} from '@aws-sdk/client-codecommit';
import { mockClient } from 'aws-sdk-client-mock';
import * as aws4 from 'aws4';
import { git, logger } from '~test/util.ts';
import {
PLATFORM_BAD_CREDENTIALS,
REPOSITORY_EMPTY,
REPOSITORY_NOT_FOUND,
} from '../../../constants/error-messages.ts';
import type { Platform } from '../types.ts';
import { getCodeCommitUrl } from './codecommit-client.ts';
import * as codeCommit from './index.ts';
const codeCommitClient = mockClient(CodeCommitClient);
async function reInitRepo(codeCommit: Platform): Promise<void> {
codeCommitClient.on(GetRepositoryCommand).resolvesOnce({
repositoryMetadata: {
defaultBranch: 'main',
repositoryId: 'id',
},
});
vi.stubEnv('AWS_ACCESS_KEY_ID', 'something');
vi.stubEnv('AWS_SECRET_ACCESS_KEY', 'something');
await codeCommit.initRepo({ repository: 'repositoryName' });
}
describe('modules/platform/codecommit/index', () => {
beforeAll(async () => {
await codeCommit.initPlatform({
endpoint: 'https://git-codecommit.eu-central-1.amazonaws.com/',
username: 'accessKeyId',
password: 'SecretAccessKey',
token: 'token',
});
});
beforeEach(() => {
vi.stubEnv('AWS_REGION', undefined);
vi.stubEnv('AWS_ACCESS_KEY_ID', undefined);
vi.stubEnv('AWS_SECRET_ACCESS_KEY', undefined);
codeCommitClient.reset();
vi.useRealTimers();
});
describe('massageMarkdown', () => {
it('validates massageMarkdown functionality', () => {
const newStr = codeCommit.massageMarkdown(
'<details><summary>foo</summary>bar</details>text<details>\n<!--renovate-debug:hiddenmessage123-->',
);
expect(newStr).toBe(
'**foo**bartext\n[//]: # (<!--renovate-debug:hiddenmessage123-->)',
);
});
it('replaces pr links', () => {
const body =
'[#123](../pull/123) [#124](../pull/124) [#125](../pull/125)';
expect(codeCommit.massageMarkdown(body)).toBe(
'[#123](../../pull-requests/123) [#124](../../pull-requests/124) [#125](../../pull-requests/125)',
);
});
it('replaces issue links', () => {
const body =
'[#123](../issues/123) [#124](../issues/124) [#125](../issues/125)';
expect(codeCommit.massageMarkdown(body)).toBe(
'[#123](#123) [#124](#124) [#125](#125)',
);
});
});
it('maxBodyLength', () => {
expect(codeCommit.maxBodyLength()).toBe(Infinity);
});
describe('initPlatform()', () => {
it('should init', async () => {
await expect(
codeCommit.initPlatform({
endpoint: 'https://git-codecommit.REGION.amazonaws.com/',
username: 'abc',
password: '123',
}),
).resolves.toEqual({
endpoint: 'https://git-codecommit.REGION.amazonaws.com/',
});
});
it('should init with env vars', async () => {
vi.stubEnv('AWS_REGION', 'REGION');
await expect(
codeCommit.initPlatform({
username: 'abc',
password: '123',
}),
).resolves.toEqual({
endpoint: 'https://git-codecommit.REGION.amazonaws.com/',
});
});
it('should', async () => {
await expect(
codeCommit.initPlatform({ endpoint: 'non://parsable.url' }),
).resolves.toEqual({
endpoint: 'non://parsable.url',
});
});
it('should as well', async () => {
await expect(codeCommit.initPlatform({})).resolves.toEqual({
endpoint: 'https://git-codecommit.us-east-1.amazonaws.com/',
});
});
});
describe('initRepos()', () => {
it('fails to git.initRepo', async () => {
git.initRepo.mockImplementationOnce(() => {
throw new Error('any error');
});
codeCommitClient.on(GetRepositoryCommand).resolvesOnce({
repositoryMetadata: {
defaultBranch: 'main',
repositoryId: 'id',
},
});
await expect(
codeCommit.initRepo({ repository: 'repositoryName' }),
).rejects.toThrow(new Error(PLATFORM_BAD_CREDENTIALS));
});
it('fails on getRepositoryInfo', async () => {
codeCommitClient
.on(GetRepositoryCommand)
.rejectsOnce(new Error('Could not find repository'));
await expect(
codeCommit.initRepo({ repository: 'repositoryName' }),
).rejects.toThrow(new Error(REPOSITORY_NOT_FOUND));
});
it('getRepositoryInfo returns bad results', async () => {
git.initRepo.mockReturnValueOnce(Promise.resolve());
codeCommitClient.on(GetRepositoryCommand).resolvesOnce({});
await expect(
codeCommit.initRepo({ repository: 'repositoryName' }),
).rejects.toThrow(new Error(REPOSITORY_NOT_FOUND));
});
it('getRepositoryInfo returns bad results 2', async () => {
codeCommitClient.on(GetRepositoryCommand).resolvesOnce({
repositoryMetadata: {
repositoryId: 'id',
},
});
await expect(
codeCommit.initRepo({ repository: 'repositoryName' }),
).rejects.toThrow(new Error(REPOSITORY_EMPTY));
});
it('initiates repo successfully', async () => {
codeCommitClient.on(GetRepositoryCommand).resolvesOnce({
repositoryMetadata: {
defaultBranch: 'main',
repositoryId: 'id',
},
});
vi.stubEnv('AWS_ACCESS_KEY_ID', 'something');
vi.stubEnv('AWS_SECRET_ACCESS_KEY', 'something');
await expect(
codeCommit.initRepo({ repository: 'repositoryName' }),
).resolves.toEqual({
repoFingerprint:
'1b375a58e9961e5c2c8cdc497c5975beb287d538b4692918a3306b92db181cd125c5bd0b1bf8e399cf31cd5f1d24b6dad5a80bdf061f6003cf1c33790525f9c6',
defaultBranch: 'main',
isFork: false,
});
});
it('gets the right url', () => {
vi.stubEnv('AWS_ACCESS_KEY_ID', '');
vi.stubEnv('AWS_SECRET_ACCESS_KEY', '');
expect(
getCodeCommitUrl(
{
defaultBranch: 'main',
repositoryId: 'id',
cloneUrlHttp:
'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/name',
},
'name',
),
).toBe('https://git-codecommit.us-east-1.amazonaws.com/v1/repos/name');
});
it('gets the eu-central-1 url', () => {
vi.stubEnv('AWS_ACCESS_KEY_ID', '');
vi.stubEnv('AWS_SECRET_ACCESS_KEY', '');
vi.stubEnv('AWS_REGION', 'eu-central-1');
expect(
getCodeCommitUrl(
{
defaultBranch: 'main',
repositoryId: 'id',
},
'name',
),
).toBe('https://git-codecommit.eu-central-1.amazonaws.com/v1/repos/name');
});
it('gets url with username and token', () => {
vi.useFakeTimers().setSystemTime(new Date('2020-01-01'));
vi.stubEnv('AWS_ACCESS_KEY_ID', 'access-key-id');
vi.stubEnv('AWS_SECRET_ACCESS_KEY', 'secret-access-key');
vi.stubEnv('AWS_REGION', 'eu-central-1');
vi.stubEnv('AWS_SESSION_TOKEN', '');
const signer = new aws4.RequestSigner({
service: 'codecommit',
host: 'git-codecommit.eu-central-1.amazonaws.com',
method: 'GIT',
path: 'v1/repos/name',
});
const dateTime = signer.getDateTime();
const token = `${dateTime}Z${signer.signature()}`;
expect(
getCodeCommitUrl(
{
defaultBranch: 'main',
repositoryId: 'id',
},
'name',
),
).toBe(
`https://access-key-id:${token}@git-codecommit.eu-central-1.amazonaws.com/v1/repos/name`,
);
});
});
describe('getRepos()', () => {
it('returns repos', async () => {
const result = {
repositories: [
{
repositoryId: 'id',
repositoryName: 'repoName',
},
],
};
codeCommitClient.on(ListRepositoriesCommand).resolvesOnce(result);
const res = await codeCommit.getRepos();
expect(res).toEqual(['repoName']);
});
it('returns empty if error', async () => {
codeCommitClient
.on(ListRepositoriesCommand)
.rejectsOnce(new Error('something'));
const res = await codeCommit.getRepos();
expect(res).toEqual([]);
});
});
describe('getPrList()', () => {
beforeAll(async () => {
// reset state for tests
await reInitRepo(codeCommit);
});
it('gets PR list by author', async () => {
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1', '2'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce({});
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.getPrList();
expect(res).toMatchObject([
{
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'open',
number: 1,
title: 'someTitle',
},
]);
codeCommitClient
.on(GetPullRequestCommand)
.rejectsOnce(new Error('failed connection'));
// test cache
const res2 = await codeCommit.getPrList();
expect(res2).toMatchObject([
{
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'open',
number: 1,
title: 'someTitle',
},
]);
});
it('checks if nullcheck works for list prs', async () => {
// This test expects a clean cache as we want to check the behaviour when an AWS call is made
await reInitRepo(codeCommit);
codeCommitClient.on(ListPullRequestsCommand).resolvesOnce({});
const res = await codeCommit.getPrList();
expect(res).toEqual([]);
});
});
describe('findPr()', () => {
beforeEach(async () => {
// reset state for tests
await reInitRepo(codeCommit);
});
it('throws error on findPr', async () => {
const err = new Error('failed');
codeCommitClient.on(ListPullRequestsCommand).rejectsOnce(err);
const res = await codeCommit.findPr({
branchName: 'sourceBranch',
prTitle: 'someTitle',
state: 'open',
});
expect(res).toBeNull();
expect(logger.logger.error).toHaveBeenCalledWith({ err }, 'findPr error');
});
it('finds pr', async () => {
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.findPr({
branchName: 'sourceBranch',
prTitle: 'someTitle',
state: 'open',
});
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'open',
number: 1,
title: 'someTitle',
});
});
it('finds any pr with that title in regardless of state', async () => {
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.findPr({
branchName: 'sourceBranch',
prTitle: 'someTitle',
state: 'all',
});
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'open',
number: 1,
title: 'someTitle',
});
});
it('finds closed/merged pr', async () => {
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'CLOSED',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.findPr({
branchName: 'sourceBranch',
prTitle: 'someTitle',
state: '!open',
});
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'closed',
number: 1,
title: 'someTitle',
});
});
it('finds any pr', async () => {
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'CLOSED',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.findPr({
branchName: 'sourceBranch',
prTitle: 'someTitle',
});
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'closed',
number: 1,
title: 'someTitle',
});
});
it('returns empty list in case prs dont exist yet', async () => {
const res = await codeCommit.findPr({
branchName: 'sourceBranch',
prTitle: 'someTitle',
state: 'open',
});
expect(res).toBeNull();
});
});
describe('getBranchPr()', () => {
it('codecommit find PR for branch', async () => {
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolves(prRes);
const res = await codeCommit.getBranchPr('sourceBranch');
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'open',
number: 1,
title: 'someTitle',
});
});
it('returns null if no PR for branch', async () => {
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.getBranchPr('branch_without_pr');
expect(res).toBeNull();
});
});
describe('getPr()', () => {
it('gets pr', async () => {
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
description: 'body',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.getPr(1);
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'open',
number: 1,
title: 'someTitle',
});
});
it('gets closed pr', async () => {
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'CLOSED',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.getPr(1);
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'closed',
number: 1,
title: 'someTitle',
});
});
it('gets merged pr', async () => {
const prRes: GetPullRequestOutput = {
pullRequest: {
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
mergeMetadata: {
isMerged: true,
},
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.getPr(1);
expect(res).toMatchObject({
sourceBranch: 'refs/heads/sourceBranch',
targetBranch: 'refs/heads/targetBranch',
state: 'merged',
number: 1,
title: 'someTitle',
});
});
it('returns null in case input is null', async () => {
codeCommitClient
.on(GetPullRequestCommand)
.rejectsOnce(new Error('bad creds'));
const res = await codeCommit.getPr(1);
expect(res).toBeNull();
});
});
describe('getJsonFile()', () => {
it('returns file content', async () => {
const data = { foo: 'bar' };
const uint8arrData = new Uint8Array(Buffer.from(JSON.stringify(data)));
codeCommitClient
.on(GetFileCommand)
.resolvesOnce({ fileContent: uint8arrData });
const res = await codeCommit.getJsonFile('file.json');
expect(res).toEqual(data);
});
it('returns file content in json5 format', async () => {
const json5Data = `
{
// json5 comment
foo: 'bar'
}
`;
const uint8arrData = new Uint8Array(Buffer.from(json5Data));
codeCommitClient
.on(GetFileCommand)
.resolvesOnce({ fileContent: uint8arrData });
const res = await codeCommit.getJsonFile('file.json');
expect(res).toEqual({ foo: 'bar' });
});
it('returns null', async () => {
codeCommitClient
.on(GetFileCommand)
.resolvesOnce({ fileContent: undefined });
const res = await codeCommit.getJsonFile('file.json');
expect(res).toBeNull();
});
});
describe('getRawFile()', () => {
it('returns file content', async () => {
const data = { foo: 'bar' };
const uint8arrData = new Uint8Array(Buffer.from(JSON.stringify(data)));
codeCommitClient
.on(GetFileCommand)
.resolvesOnce({ fileContent: uint8arrData });
const res = await codeCommit.getRawFile('file.json');
expect(res).toBe('{"foo":"bar"}');
});
it('returns null', async () => {
codeCommitClient
.on(GetFileCommand)
.resolvesOnce({ fileContent: undefined });
const res = await codeCommit.getRawFile('file.json');
expect(res).toBeNull();
});
it('returns file content in json5 format', async () => {
const json5Data = `
{
// json5 comment
foo: 'bar'
}
`;
const uint8arrData = new Uint8Array(Buffer.from(json5Data));
codeCommitClient
.on(GetFileCommand)
.resolvesOnce({ fileContent: uint8arrData });
const res = await codeCommit.getRawFile('file.json');
expect(res).toBe(`
{
// json5 comment
foo: 'bar'
}
`);
});
});
describe('createPr()', () => {
beforeAll(async () => {
// reset state for tests
await reInitRepo(codeCommit);
});
it('posts PR', async () => {
const prRes: CreatePullRequestOutput = {
pullRequest: {
pullRequestId: '1',
pullRequestStatus: 'OPEN',
title: 'someTitle',
description: 'mybody',
pullRequestTargets: [
{
sourceCommit: '123',
destinationCommit: '321',
},
],
},
};
codeCommitClient.on(CreatePullRequestCommand).resolvesOnce(prRes);
const pr = await codeCommit.createPr({
sourceBranch: 'sourceBranch',
targetBranch: 'targetBranch',
prTitle: 'mytitle',
prBody: 'mybody',
});
expect(pr).toMatchObject({
number: 1,
state: 'open',
title: 'someTitle',
sourceBranch: 'sourceBranch',
targetBranch: 'targetBranch',
sourceRepo: 'repositoryName',
body: 'mybody',
});
});
it('doesnt return a title', async () => {
const prRes: CreatePullRequestOutput = {
pullRequest: {
pullRequestId: '1',
pullRequestStatus: 'OPEN',
},
};
codeCommitClient.on(CreatePullRequestCommand).resolvesOnce(prRes);
await expect(
codeCommit.createPr({
sourceBranch: 'sourceBranch',
targetBranch: 'targetBranch',
prTitle: 'mytitle',
prBody: 'mybody',
}),
).rejects.toThrow(new Error('Could not create pr, missing PR info'));
});
});
describe('updatePr()', () => {
it('updates PR', async () => {
codeCommitClient.on(UpdatePullRequestDescriptionCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestTitleCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestStatusCommand).resolvesOnce({});
await expect(
codeCommit.updatePr({
number: 1,
prTitle: 'title',
prBody: 'body',
state: 'open',
}),
).toResolve();
});
it('updates PR body if cache is not the same', async () => {
// Start with a clean cache
await reInitRepo(codeCommit);
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
codeCommitClient.on(GetPullRequestCommand).resolvesOnce({
pullRequest: {
pullRequestTargets: [
{
destinationReference: 'targetBranch',
sourceReference: 'sourceBranch',
destinationCommit: '321',
sourceCommit: '123',
},
],
pullRequestStatus: PullRequestStatusEnum.OPEN,
title: 'someTitle',
description: 'some old description',
},
});
const prList = await codeCommit.getPrList();
expect(prList).toHaveLength(1);
codeCommitClient.on(UpdatePullRequestDescriptionCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestTitleCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestStatusCommand).resolvesOnce({});
await expect(
codeCommit.updatePr({
number: 1,
prTitle: 'title',
prBody: 'new description',
state: 'open',
}),
).toResolve();
});
it('updates PR body does not update if cache is the same', async () => {
// Start with a clean cache
await reInitRepo(codeCommit);
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['1'] });
codeCommitClient.on(GetPullRequestCommand).resolvesOnce({
pullRequest: {
pullRequestTargets: [
{
destinationReference: 'targetBranch',
sourceReference: 'sourceBranch',
destinationCommit: '321',
sourceCommit: '123',
},
],
pullRequestStatus: PullRequestStatusEnum.OPEN,
title: 'someTitle',
description: 'news description',
},
});
const prList = await codeCommit.getPrList();
expect(prList).toHaveLength(1);
codeCommitClient.on(UpdatePullRequestTitleCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestStatusCommand).resolvesOnce({});
await expect(
codeCommit.updatePr({
number: 1,
prTitle: 'title',
prBody: 'new description',
state: 'open',
}),
).toResolve();
});
it('updates PR regardless of status failure', async () => {
codeCommitClient.on(UpdatePullRequestDescriptionCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestTitleCommand).resolvesOnce({});
codeCommitClient
.on(UpdatePullRequestStatusCommand)
.rejectsOnce(new Error('update status failure'));
await expect(
codeCommit.updatePr({
number: 1,
prTitle: 'title',
prBody: 'body',
state: 'open',
}),
).toResolve();
});
it('updates PR with status closed', async () => {
codeCommitClient.on(UpdatePullRequestDescriptionCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestTitleCommand).resolvesOnce({});
codeCommitClient.on(UpdatePullRequestStatusCommand).resolvesOnce({});
await expect(
codeCommit.updatePr({
number: 1,
prTitle: 'title',
prBody: 'body',
state: 'closed',
}),
).toResolve();
});
});
describe('ensureComment', () => {
beforeEach(async () => {
// reset state for tests
await reInitRepo(codeCommit);
});
it('adds comment if missing', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
comments: [
{
commentId: '1',
content: 'my comment content',
},
],
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['42'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
pullRequestId: '42',
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
sourceCommit: '123',
destinationCommit: '321',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
codeCommitClient.on(PostCommentForPullRequestCommand).resolvesOnce({});
const res = await codeCommit.ensureComment({
number: 42,
topic: 'some-subject',
content: 'some\ncontent',
});
expect(res).toBeTrue();
expect(logger.logger.info).toHaveBeenCalledWith(
{ repository: 'repositoryName', prNo: 42, topic: 'some-subject' },
'Comment added',
);
});
it('updates comment if different content', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
comments: [
{
commentId: '1',
content: '### some-subject\n\n - my comment content',
},
],
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
codeCommitClient.on(PostCommentForPullRequestCommand).resolvesOnce({});
const res = await codeCommit.ensureComment({
number: 42,
topic: 'some-subject',
content: 'some\ncontent',
});
expect(res).toBeTrue();
expect(logger.logger.debug).toHaveBeenCalledWith(
{ repository: 'repositoryName', prNo: 42, topic: 'some-subject' },
'Comment updated',
);
});
it('does nothing if comment exists and is the same', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
comments: [
{
commentId: '1',
content: '### some-subject\n\nmy comment content',
},
],
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
const res = await codeCommit.ensureComment({
number: 42,
topic: 'some-subject',
content: 'my comment content',
});
expect(res).toBeTrue();
expect(logger.logger.debug).toHaveBeenCalledWith(
{ repository: 'repositoryName', prNo: 42, topic: 'some-subject' },
'Comment is already up-to-date',
);
});
it('does nothing if comment exists and is the same when there is no topic', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
comments: [
{
commentId: '1',
content: 'my comment content',
},
],
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
const res = await codeCommit.ensureComment({
number: 42,
topic: null,
content: 'my comment content',
});
expect(res).toBeTrue();
expect(logger.logger.debug).toHaveBeenCalledWith(
{ repository: 'repositoryName', prNo: 42, topic: null },
'Comment is already up-to-date',
);
});
it('throws an exception in case of api failed connection', async () => {
const err = new Error('some error');
codeCommitClient.on(GetCommentsForPullRequestCommand).rejectsOnce(err);
const res = await codeCommit.ensureComment({
number: 42,
topic: null,
content: 'my comment content',
});
expect(res).toBeFalse();
expect(logger.logger.debug).toHaveBeenCalledWith(
{ err },
'Unable to retrieve pr comments',
);
});
it('fails at null check for response', async () => {
codeCommitClient.on(GetCommentsForPullRequestCommand).resolvesOnce({});
const res = await codeCommit.ensureComment({
number: 42,
topic: null,
content: 'my comment content',
});
expect(res).toBeFalse();
});
it('doesnt find comments obj and source or destination commit', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
codeCommitClient
.on(ListPullRequestsCommand)
.resolvesOnce({ pullRequestIds: ['42'] });
const prRes: GetPullRequestOutput = {
pullRequest: {
pullRequestId: '42',
title: 'someTitle',
pullRequestStatus: 'OPEN',
pullRequestTargets: [
{
sourceReference: 'refs/heads/sourceBranch',
destinationReference: 'refs/heads/targetBranch',
},
],
},
};
codeCommitClient.on(GetPullRequestCommand).resolvesOnce(prRes);
const res = await codeCommit.ensureComment({
number: 42,
topic: null,
content: 'my comment content',
});
expect(res).toBeFalse();
});
});
describe('ensureCommentRemoval', () => {
it('deletes comment by topic if found', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
comments: [
{
commentId: '1',
content: '### some-subject\n\nmy comment content',
},
],
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
codeCommitClient.on(DeleteCommentContentCommand).resolvesOnce({});
await codeCommit.ensureCommentRemoval({
type: 'by-topic',
number: 42,
topic: 'some-subject',
});
expect(logger.logger.debug).toHaveBeenCalledWith(
'comment "some-subject" in PR #42 was removed',
);
});
it('doesnt find commentsForPullRequestData', async () => {
codeCommitClient.on(GetCommentsForPullRequestCommand).resolvesOnce({});
codeCommitClient.on(DeleteCommentContentCommand).resolvesOnce({});
await codeCommit.ensureCommentRemoval({
type: 'by-topic',
number: 42,
topic: 'some-subject',
});
expect(logger.logger.debug).toHaveBeenCalledWith(
'commentsForPullRequestData not found',
);
});
it('doesnt find comment obj', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
codeCommitClient.on(DeleteCommentContentCommand).resolvesOnce({});
await codeCommit.ensureCommentRemoval({
type: 'by-topic',
number: 42,
topic: 'some-subject',
});
expect(logger.logger.debug).toHaveBeenCalledWith(
'comments object not found under commentsForPullRequestData',
);
});
it('deletes comment by content if found', async () => {
const commentsRes = {
commentsForPullRequestData: [
{
pullRequestId: '42',
repositoryName: 'someRepo',
beforeCommitId: 'beforeCommitId',
afterCommitId: 'afterCommitId',
comments: [
{
commentId: '1',
content: 'my comment content',
},
],
},
],
};
codeCommitClient
.on(GetCommentsForPullRequestCommand)
.resolvesOnce(commentsRes);
codeCommitClient.on(DeleteCommentContentCommand).resolvesOnce({});
await codeCommit.ensureCommentRemoval({
type: 'by-content',
number: 42,
content: 'my comment content',
});
expect(logger.logger.debug).toHaveBeenCalledWith(
'comment "my comment content" in PR #42 was removed',
);
});
it('throws exception in case failed api connection', async () => {
const err = new Error('some error');
codeCommitClient.on(GetCommentsForPullRequestCommand).rejectsOnce(err);
await codeCommit.ensureCommentRemoval({
type: 'by-content',
number: 42,
content: 'my comment content',
});
expect(logger.logger.debug).toHaveBeenCalledWith(
{ err },
'Unable to retrieve pr comments',
);
});
});
describe('addReviewers', () => {
it('checks that the function resolves', async () => {
const res = {
approvalRule: {
approvalRuleName: 'Assignees By Renovate',
lastModifiedDate: new Date(),
ruleContentSha256: '7c44e6ebEXAMPLE',
creationDate: new Date(),
approvalRuleId: 'aac33506-EXAMPLE',
approvalRuleContent:
'{"Version": "2018-11-08","Statements": [{"Type": "Approvers","NumberOfApprovalsNeeded": 1,"ApprovalPoolMembers": ["arn:aws:iam::someUser:user/ReviewerUser"]}]}',
lastModifiedUser: 'arn:aws:iam::someUser:user/ReviewerUser',
},
};
codeCommitClient
.on(CreatePullRequestApprovalRuleCommand)
.resolvesOnce(res);
await expect(
codeCommit.addReviewers(13, [
'arn:aws:iam::someUser:user/ReviewerUser',
]),
).toResolve();
expect(logger.logger.debug).toHaveBeenCalledWith(
res,
'Approval Rule Added to PR #13:',
);
});
});
});