Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trigger for user membership in a team #374

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions __mocks__/rules/rule1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"customMessage": "This is a custom message for a rule",
"users": ["eeny", "meeny", "miny", "moe"],
"action": "comment",
"isMemberOf": ["counting_out_game"],
"includes": ["*.ts"]
}
35 changes: 29 additions & 6 deletions __tests__/index.HttpFailure.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { env } from '../src/environment';
import { Event, HttpErrors } from '../src/util/constants';
import * as actions from '@actions/core';
import { Main, mockedInput } from './util/helpers';
import event from '../__mocks__/event.json';
import getCommentsResponse from '../__mocks__/scenarios/get_comments.json';
import { mockCompareCommits } from './util/mockGitHubRequest';
import { mockCompareCommits, mockRequest } from './util/mockGitHubRequest';


jest.mock('@actions/core');
jest.mock('../src/environment', () => {
Expand All @@ -19,7 +21,16 @@ jest.mock('../src/environment', () => {
},
};
});
jest.mock('@actions/github', () => {
const workflowEvent = jest.requireActual('../__mocks__/event.json') as Event;

return {
context: {
actor: workflowEvent.repository.name,
repo: { owner: workflowEvent.repository.owner.login },
},
};
});
describe('use-herald', () => {
const getInput = actions.getInput as jest.Mock<any>;
const setFailed = actions.setFailed as jest.Mock<any>;
Expand All @@ -35,7 +46,7 @@ describe('use-herald', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
} = require(`../${env.GITHUB_EVENT_PATH}`) as Event;

const getGithubMock = () =>
const getCompareCommitsMock = () =>
mockCompareCommits({
login,
name,
Expand All @@ -49,13 +60,23 @@ describe('use-herald', () => {
});

const prIssue = 2;
const github = getGithubMock();
const compareCommitsMock = getCompareCommitsMock();
const membershipMock = mockRequest(
'get',
`/orgs/${event.repository.owner.login}/teams/counting_out_game/memberships/${event.repository.name}`,
200,
{
role: 'maintainer',
state: 'active',
url: `https://api.github.com/teams/1/memberships/${event.repository.owner.login}`,
}
);

github
compareCommitsMock
.get(`/repos/${login}/${name}/issues/${prIssue}/comments?page=1&per_page=100`)
.reply(200, getCommentsResponse);

github
compareCommitsMock
.post(`/repos/${login}/${name}/issues/2/comments`)
.replyWithError({ message: 'Resource not accessible by integration', code: HttpErrors.RESOURCE_NOT_ACCESSIBLE });

Expand All @@ -73,6 +94,8 @@ describe('use-herald', () => {
],
]
`);
expect(github.isDone()).toBe(true);
expect(compareCommitsMock.isDone()).toBe(true);
expect(membershipMock.isDone()).toBe(true);
});

});
88 changes: 75 additions & 13 deletions __tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,53 @@
import { Props } from '../src';
import { Event } from '../src/util/constants';
import * as actions from '@actions/core';
import { env } from '../src/environment';
import * as comment from '../src/comment';
import { mockCompareCommits } from './util/mockGitHubRequest';
import { mockCompareCommits, mockRequest, MockResponse } from './util/mockGitHubRequest';
import getCompareCommitsResponse from '../__mocks__/scenarios/get_compare_commits.json';
import { Main, mockedInput } from './util/helpers';
import event from '../__mocks__/event.json';
import { env } from '../src/environment';

jest.mock('@actions/core');
jest.mock('../src/comment');

jest.mock('../src/environment', () => {
const { env } = jest.requireActual('../src/environment');

const GITHUB_EVENT_PATH = '__mocks__/event.json';

return {
env: {
...env,
GITHUB_EVENT_PATH: '__mocks__/event.json',
GITHUB_EVENT_PATH,
GITHUB_EVENT_NAME: 'pull_request',
},
};
});

const event = require(`../${env.GITHUB_EVENT_PATH}`) as Event;
jest.mock('@actions/github', () => {
const workflowEvent = jest.requireActual('../__mocks__/event.json') as Event;

return {
context: {
actor: workflowEvent.repository.name,
repo: { owner: workflowEvent.repository.owner.login },
},
};
});

const handleComment = comment.handleComment as jest.Mock<any>;
const setOutput = actions.setOutput as jest.Mock<any>;
const setFailed = actions.setFailed as jest.Mock<any>;
const getInput = actions.getInput as jest.Mock<any>;

const getGithubMock = () =>
const getCompareCommitsMock = (response?: MockResponse) =>
mockCompareCommits({
login: event.repository.owner.login,
name: event.repository.name,
base: event.pull_request.base.sha,
head: event.pull_request.head.sha,
response,
});

describe('use-herald-action', () => {
Expand All @@ -55,13 +70,33 @@ describe('use-herald-action', () => {
expect(setFailed).toHaveBeenCalled();
});

it('should fail if the compareCommits response does not have files', async () => {
const changedRulesDirectory = { ...mockedInput, [Props.rulesLocation]: '__mocks__/required_rules/*.json' };
getInput.mockImplementation((key: Partial<keyof typeof changedRulesDirectory>) => {
return changedRulesDirectory[key];
});

const compareCommitsMock = getCompareCommitsMock({ getCompareCommitsResponse, files: null });

const { main } = require('../src') as Main;

await main();

expect(setFailed.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"There were no files returned from f95f852bd8fca8fcc58a9a2d6c842781e32a215e base and ec26c3e57ca3a959ca5aad62de7213c562f8c821 head",
]
`);
expect(setOutput).not.toHaveBeenCalled();
expect(compareCommitsMock.isDone()).toBe(true);
});
it('should fail if rules with errorLevel set to "error" does not match', async () => {
const changedRulesDirectory = { ...mockedInput, [Props.rulesLocation]: '__mocks__/required_rules/*.json' };
getInput.mockImplementation((key: Partial<keyof typeof changedRulesDirectory>) => {
return changedRulesDirectory[key];
});

const github = getGithubMock();
const compareCommitsMock = getCompareCommitsMock();

const { main } = require('../src') as Main;

Expand All @@ -73,23 +108,35 @@ describe('use-herald-action', () => {
]
`);
expect(setOutput).not.toHaveBeenCalled();
expect(github.isDone()).toBe(true);
expect(compareCommitsMock.isDone()).toBe(true);
});

it('should run normally (with dryRun: true)', async () => {
getInput.mockImplementation((key: Partial<keyof typeof mockedInput>) => {
return mockedInput[key];
});

const github = getGithubMock();
const compareCommitsMock = getCompareCommitsMock();

const membershipMock = mockRequest(
'get',
`/orgs/${event.repository.owner.login}/teams/counting_out_game/memberships/${event.repository.name}`,
200,
{
role: 'maintainer',
state: 'active',
url: `https://api.github.com/teams/1/memberships/${event.repository.owner.login}`,
}
);

const { main } = require('../src') as Main;

await main();

expect(setFailed).not.toHaveBeenCalled();
expect(setOutput).toHaveBeenCalled();
expect(github.isDone()).toBe(true);
expect(compareCommitsMock.isDone()).toBe(true);
expect(membershipMock.isDone()).toBe(true);
});

it('should run the entire action', async () => {
Expand All @@ -98,7 +145,18 @@ describe('use-herald-action', () => {
return input[key];
});

const github = getGithubMock();
const compareCommitsMock = getCompareCommitsMock();

const membershipMock = mockRequest(
'get',
`/orgs/${event.repository.owner.login}/teams/counting_out_game/memberships/${event.repository.name}`,
200,
{
role: 'maintainer',
state: 'active',
url: `https://api.github.com/teams/1/memberships/${event.repository.owner.login}`,
}
);

const { main } = require('../src') as Main;

Expand All @@ -119,6 +177,9 @@ describe('use-herald-action', () => {
"*.ts",
],
"includesInPatch": Array [],
"isMemberOf": Array [
"counting_out_game",
],
"matched": true,
"name": "rule1.json",
"path": "${env.GITHUB_WORKSPACE}/__mocks__/rules/rule1.json",
Expand All @@ -135,7 +196,8 @@ describe('use-herald-action', () => {
]
`);

expect(github.isDone()).toBe(true);
expect(compareCommitsMock.isDone()).toBe(true);
expect(membershipMock.isDone()).toBe(true);
});

it('should run the entire action (no rules found)', async () => {
Expand All @@ -149,14 +211,14 @@ describe('use-herald-action', () => {
return input[key];
});

const github = getGithubMock();
const compareCommitsMock = getCompareCommitsMock();
const { main } = require('../src') as Main;

await main();

expect(handleComment).not.toHaveBeenCalled();
expect(setFailed.mock.calls).toMatchInlineSnapshot('Array []');
expect(setOutput.mock.calls).toMatchSnapshot();
expect(github.isDone()).toBe(true);
expect(compareCommitsMock.isDone()).toBe(true);
});
});
21 changes: 21 additions & 0 deletions __tests__/isMemberOf.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Event } from '../src/util/constants';
import { handleMembership } from '../src/isMemberOf';
import { Octokit } from '@octokit/rest';

jest.mock('@actions/github', () => {
const workflowEvent = jest.requireActual('../__mocks__/event.json') as Event;
return {
context: {
actor: workflowEvent.repository.name,
repo: { owner: workflowEvent.repository.owner.login },
},
};
});

describe('handleLabels', () => {
const client = new Octokit();
it('should not match the rule if no team si provided', async () => {
const response = await handleMembership(client, undefined);
expect(response).toBe(false);
});
});
Loading