mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-01 10:09:50 +00:00
e01b50c6ab
* refactor: flag all typed object literal casts in prefer-partial-in-specs * refactor: type maven spec httpError helper against got response shape
240 lines
7.4 KiB
TypeScript
240 lines
7.4 KiB
TypeScript
import { partial, platform } from '~test/util.ts';
|
|
import { GlobalConfig } from '../../../../config/global.ts';
|
|
import type { RenovateConfig } from '../../../../config/types.ts';
|
|
import type { Pr } from '../../../../modules/platform/types.ts';
|
|
import * as _util from '../../../../util/sample.ts';
|
|
import * as _codeOwners from './code-owners.ts';
|
|
import { addParticipants } from './participants.ts';
|
|
|
|
vi.mock('../../../../util/sample.ts');
|
|
const util = vi.mocked(_util);
|
|
|
|
vi.mock('./code-owners.ts');
|
|
const codeOwners = vi.mocked(_codeOwners);
|
|
|
|
describe('workers/repository/update/pr/participants', () => {
|
|
// oxlint-disable-next-line renovate/prefer-partial-in-specs -- assigneesSampleSize/reviewersSampleSize intentionally set to null, which the type does not allow, to simulate an unset value
|
|
const config: RenovateConfig = {
|
|
assignees: ['a', 'b', '@c'],
|
|
reviewers: ['x', 'y', '@z'],
|
|
additionalReviewers: [],
|
|
assigneesSampleSize: null,
|
|
reviewersSampleSize: null,
|
|
} as never;
|
|
|
|
const pr = partial<Pr>({ number: 123 });
|
|
|
|
beforeEach(() => {
|
|
GlobalConfig.reset();
|
|
});
|
|
|
|
describe('assignees', () => {
|
|
it('does not assignees when there are none', async () => {
|
|
await addParticipants({ ...config, assignees: undefined }, pr);
|
|
expect(platform.addAssignees).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('adds assignees', async () => {
|
|
await addParticipants(config, pr);
|
|
expect(platform.addAssignees).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'a',
|
|
'b',
|
|
'c',
|
|
]);
|
|
});
|
|
|
|
it('filters assignees', async () => {
|
|
platform.filterUnavailableUsers = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(['a', 'b']);
|
|
await addParticipants({ ...config, filterUnavailableUsers: true }, pr);
|
|
expect(platform.addAssignees).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'a',
|
|
'b',
|
|
]);
|
|
});
|
|
|
|
it('expands group code owners assignees', async () => {
|
|
codeOwners.codeOwnersForPr.mockResolvedValueOnce([
|
|
'user',
|
|
'@group',
|
|
'u@email.com',
|
|
]);
|
|
platform.expandGroupMembers = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(['u@email.com', 'user', 'group.user']);
|
|
await addParticipants(
|
|
{
|
|
...config,
|
|
assigneesFromCodeOwners: true,
|
|
expandCodeOwnersGroups: true,
|
|
},
|
|
pr,
|
|
);
|
|
expect(platform.expandGroupMembers).toHaveBeenCalledExactlyOnceWith([
|
|
'user',
|
|
'@group',
|
|
'u@email.com',
|
|
]);
|
|
expect(codeOwners.codeOwnersForPr).toHaveBeenCalledExactlyOnceWith({
|
|
number: 123,
|
|
});
|
|
expect(platform.addAssignees).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'a',
|
|
'b',
|
|
'c',
|
|
'u@email.com',
|
|
'user',
|
|
'group.user',
|
|
]);
|
|
});
|
|
|
|
it('does not expand group code owners assignees when assigneesFromCodeOwners disabled', async () => {
|
|
codeOwners.codeOwnersForPr.mockResolvedValueOnce(['user', '@group']);
|
|
platform.expandGroupMembers = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(['user', 'group.user']);
|
|
await addParticipants(config, pr);
|
|
expect(codeOwners.codeOwnersForPr).not.toHaveBeenCalled();
|
|
expect(platform.expandGroupMembers).not.toHaveBeenCalled();
|
|
expect(platform.addAssignees).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'a',
|
|
'b',
|
|
'c',
|
|
]);
|
|
});
|
|
|
|
it('does not expand group code owners assignees when expandCodeOwnersGroups disabled', async () => {
|
|
codeOwners.codeOwnersForPr.mockResolvedValueOnce(['user', '@group']);
|
|
platform.expandGroupMembers = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(['user', 'group.user']);
|
|
await addParticipants({ ...config, assigneesFromCodeOwners: true }, pr);
|
|
expect(codeOwners.codeOwnersForPr).toHaveBeenCalledExactlyOnceWith({
|
|
number: 123,
|
|
});
|
|
expect(platform.expandGroupMembers).not.toHaveBeenCalled();
|
|
expect(platform.addAssignees).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'a',
|
|
'b',
|
|
'c',
|
|
'user',
|
|
'group',
|
|
]);
|
|
});
|
|
|
|
it('supports assigneesSampleSize', async () => {
|
|
util.sampleSize.mockReturnValueOnce(['a', 'c']);
|
|
await addParticipants({ ...config, assigneesSampleSize: 2 }, pr);
|
|
expect(platform.addAssignees).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'a',
|
|
'c',
|
|
]);
|
|
});
|
|
|
|
it('handles add assignee errors', async () => {
|
|
platform.addAssignees.mockRejectedValueOnce('Unknown error');
|
|
await expect(addParticipants(config, pr)).not.toReject();
|
|
});
|
|
|
|
it('supports dry run assignee adding', async () => {
|
|
GlobalConfig.set({ dryRun: 'full' });
|
|
await addParticipants(config, pr);
|
|
expect(platform.addAssignees).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('supports assigneesFromCodeOwners', async () => {
|
|
codeOwners.codeOwnersForPr.mockResolvedValueOnce(['foo', 'bar', 'baz']);
|
|
await addParticipants({ ...config, assigneesFromCodeOwners: true }, pr);
|
|
expect(platform.addAssignees).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'a',
|
|
'b',
|
|
'c',
|
|
'foo',
|
|
'bar',
|
|
'baz',
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('reviewers', () => {
|
|
it('does not assignees when there are none', async () => {
|
|
await addParticipants({ ...config, reviewers: undefined }, pr);
|
|
expect(platform.addReviewers).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('adds reviewers', async () => {
|
|
await addParticipants(config, pr);
|
|
expect(platform.addReviewers).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'x',
|
|
'y',
|
|
'z',
|
|
]);
|
|
});
|
|
|
|
it('handles add assignee errors', async () => {
|
|
platform.addReviewers.mockRejectedValueOnce('Unknown error');
|
|
await expect(addParticipants(config, pr)).not.toReject();
|
|
});
|
|
|
|
it('supports reviewersSampleSize', async () => {
|
|
util.sampleSize.mockReturnValueOnce(['x', 'z']);
|
|
await addParticipants({ ...config, reviewersSampleSize: 2 }, pr);
|
|
expect(platform.addReviewers).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'x',
|
|
'z',
|
|
]);
|
|
});
|
|
|
|
it('supports dry run assignee adding', async () => {
|
|
GlobalConfig.set({ dryRun: 'full' });
|
|
await addParticipants(config, pr);
|
|
expect(platform.addReviewers).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('supports reviewersFromCodeOwners', async () => {
|
|
codeOwners.codeOwnersForPr.mockResolvedValueOnce(['foo', 'bar', 'baz']);
|
|
await addParticipants({ ...config, reviewersFromCodeOwners: true }, pr);
|
|
expect(platform.addReviewers).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'x',
|
|
'y',
|
|
'z',
|
|
'foo',
|
|
'bar',
|
|
'baz',
|
|
]);
|
|
});
|
|
|
|
it('filters out bare @ from malformed CODEOWNERS entries', async () => {
|
|
codeOwners.codeOwnersForPr.mockResolvedValueOnce([
|
|
'@UserOne',
|
|
'@UserTwo',
|
|
'@',
|
|
]);
|
|
await addParticipants(
|
|
{ ...config, reviewers: [], reviewersFromCodeOwners: true },
|
|
pr,
|
|
);
|
|
expect(platform.addReviewers).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'UserOne',
|
|
'UserTwo',
|
|
]);
|
|
});
|
|
|
|
it('supports additionalReviewers', async () => {
|
|
await addParticipants(
|
|
{ ...config, additionalReviewers: ['foo', 'bar', 'baz'] },
|
|
pr,
|
|
);
|
|
expect(platform.addReviewers).toHaveBeenCalledExactlyOnceWith(123, [
|
|
'x',
|
|
'y',
|
|
'z',
|
|
'foo',
|
|
'bar',
|
|
'baz',
|
|
]);
|
|
});
|
|
});
|
|
});
|