@dxdeveloperexperience/hygie
Version:
Hygie is an easy-to-use Open-Source REST API allowing you to interact with GIT events. This NestJS API expose a set of customizable rules to automate your project's life cycle.
604 lines (500 loc) • 19.3 kB
text/typescript
import { Test, TestingModule } from '@nestjs/testing';
import { HttpService } from '@nestjs/common';
import {
MockHttpService,
MockObservable,
MockDataAccessService,
} from '../__mocks__/mocks';
import { GitApiInfos } from '../git/gitApiInfos';
import { GitCommitStatusInfos } from '../git/gitCommitStatusInfos';
import { CommitStatusEnum } from '../webhook/utils.enum';
import {
GitIssueInfos,
IssuePRStateEnum,
GitIssuePRSearch,
IssueSortEnum,
} from '../git/gitIssueInfos';
import {
GitPRInfos,
GitCommentPRInfos,
GitMergePRInfos,
PRMethodsEnum,
} from '../git/gitPRInfos';
import { Observable, of } from 'rxjs';
import { GitlabService } from './gitlab.service';
import { GitFileInfos } from '../git/gitFileInfos';
import { DataAccessService } from '../data_access/dataAccess.service';
import { GitRelease } from '../git/gitRelease';
import { GitTag } from '../git/gitTag';
import { GitBranchCommit } from '../git/gitBranchSha';
import { logger } from '../logger/logger.service';
import { Utils } from '../utils/utils';
describe('Gitlab Service', () => {
let app: TestingModule;
let gitlabService: GitlabService;
let httpService: HttpService;
let observable: Observable<any>;
let dataAccessService: DataAccessService;
let gitCommitStatusInfos: GitCommitStatusInfos;
let expectedConfig: any = {};
beforeAll(async () => {
app = await Test.createTestingModule({
providers: [
{ provide: HttpService, useClass: MockHttpService },
{ provide: Observable, useClass: MockObservable },
{ provide: DataAccessService, useClass: MockDataAccessService },
GitlabService,
],
}).compile();
gitlabService = app.get(GitlabService);
httpService = app.get(HttpService);
observable = app.get(Observable);
dataAccessService = app.get(DataAccessService);
gitlabService.setToken('0123456789abcdef');
gitlabService.setUrlApi('https://gitlab.com/api/v4');
gitlabService.setProjectId('1');
expectedConfig = {
headers: {
'PRIVATE-TOKEN': gitlabService.token,
},
};
});
beforeEach(() => {
jest.clearAllMocks();
});
describe('updateCommitStatus', () => {
it('should emit a POST request with specific params', () => {
gitCommitStatusInfos = new GitCommitStatusInfos();
gitCommitStatusInfos.commitSha = '1';
gitCommitStatusInfos.commitStatus = CommitStatusEnum.Success;
gitCommitStatusInfos.descriptionMessage = 'Well done';
gitCommitStatusInfos.targetUrl = 'https://www.zenika.com';
gitlabService.updateCommitStatus(gitCommitStatusInfos);
const expectedUrl = `${gitlabService.urlApi}/projects/1/statuses/1`;
expectedConfig.params = {
context: process.env.APPLICATION_NAME + '/commit',
state: 'success',
target_url: 'https://www.zenika.com',
description: 'Well done',
};
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('addIssueComment', () => {
it('should emit a POST request with specific params', () => {
const gitIssueInfos = new GitIssueInfos();
gitIssueInfos.number = '1';
gitIssueInfos.comment = 'my comment';
gitlabService.addIssueComment(gitIssueInfos);
const expectedUrl = `${gitlabService.urlApi}/projects/1/issues/1/notes`;
expectedConfig.params = {
body: 'my comment',
};
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('updateIssue', () => {
it('should emit a PUT request with specific params', () => {
const gitIssueInfos = new GitIssueInfos();
gitIssueInfos.number = '1';
gitIssueInfos.state = IssuePRStateEnum.Close;
gitlabService.updateIssue(gitIssueInfos);
const expectedUrl = `${gitlabService.urlApi}/projects/1/issues/1`;
expectedConfig.params = {
state_event: 'close',
};
expect(httpService.put).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
it('should emit a PUT request with specific params', () => {
const gitIssueInfos = new GitIssueInfos();
gitIssueInfos.number = '1';
gitIssueInfos.state = IssuePRStateEnum.Open;
gitlabService.updateIssue(gitIssueInfos);
const expectedUrl = `${gitlabService.urlApi}/projects/1/issues/1`;
expectedConfig.params = {
state_event: 'reopen',
};
expect(httpService.put).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('addPRComment', () => {
it('should emit a POST request with specific params', () => {
const gitCommentPRInfos = new GitCommentPRInfos();
gitCommentPRInfos.number = '1';
gitCommentPRInfos.comment = 'my comment';
gitlabService.addPRComment(gitCommentPRInfos);
const expectedUrl = `${
gitlabService.urlApi
}/projects/1/merge_requests/1/notes`;
expectedConfig.params = {
body: 'my comment',
};
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('createPullRequest', () => {
it('should emit a POST request with specific params', () => {
const gitCreatePRInfos = new GitPRInfos();
gitCreatePRInfos.title = 'my PR';
gitCreatePRInfos.description = 'my desc';
gitCreatePRInfos.source = 'develop';
gitCreatePRInfos.target = 'master';
gitlabService.createPullRequest(gitCreatePRInfos);
const expectedUrl = `${gitlabService.urlApi}/projects/1/merge_requests`;
expectedConfig.params = {
title: 'my PR',
description: 'my desc',
source_branch: 'develop',
target_branch: 'master',
};
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('createIssue', () => {
it('should emit a POST request with specific params', async () => {
const gitIssueInfos = new GitIssueInfos();
gitIssueInfos.title = 'my new issue';
gitIssueInfos.description = 'my desc';
gitIssueInfos.labels = ['good first issue', 'rules'];
httpService.post = jest.fn().mockImplementationOnce(() => {
return of({ data: { iid: 1 } });
});
await gitlabService.createIssue(gitIssueInfos);
const expectedUrl = `${gitlabService.urlApi}/projects/1/issues`;
expectedConfig.params = {
title: 'my new issue',
description: 'my desc',
labels: 'good first issue,rules',
};
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
// Restore mock
httpService.post = jest.fn().mockImplementation(() => {
return of([]);
});
});
});
describe('deleteBranch', () => {
it('should emit a DELETE request with specific params', () => {
gitlabService.deleteBranch('feature/test');
const expectedUrl = `${
gitlabService.urlApi
}/projects/1/repository/branches/feature%2Ftest`;
expect(httpService.delete).toBeCalledWith(expectedUrl, {
headers: expectedConfig.headers,
});
});
});
describe('deleteFile', () => {
it('should emit a DELETE request with specific params', () => {
const gitFileInfos = new GitFileInfos();
gitFileInfos.fileBranch = 'master';
gitFileInfos.filePath = 'file/to/delete.txt';
gitFileInfos.commitMessage = 'delete file';
gitlabService.deleteFile(gitFileInfos).catch(err => logger.error(err));
const expectedUrl = `${
gitlabService.urlApi
}/projects/1/repository/files/file%2Fto%2Fdelete.txt`;
expectedConfig.params = {
branch: 'master',
commit_message: 'delete file',
};
expect(httpService.delete).toBeCalledWith(expectedUrl, expectedConfig);
});
});
describe('mergePullRequest', () => {
it('should emit a PUT request with specific params', () => {
const gitMergePRInfos = new GitMergePRInfos();
gitMergePRInfos.number = 42;
gitMergePRInfos.commitTitle = 'commit title';
gitMergePRInfos.commitMessage = 'commit message';
gitMergePRInfos.method = PRMethodsEnum.Squash;
gitlabService.mergePullRequest(gitMergePRInfos);
const expectedUrl = `${
gitlabService.urlApi
}/projects/1/merge_requests/42/merge`;
expectedConfig.params = {
squash: true,
merge_commit_message: 'commit message',
squash_commit_message: 'commit message',
};
expect(httpService.put).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('updatePullRequest', () => {
it('should emit a PUT request with specific params', () => {
const gitPRInfos = new GitPRInfos();
gitPRInfos.number = 42;
gitPRInfos.title = 'pr title';
gitPRInfos.description = 'pr description';
gitPRInfos.target = 'master';
gitPRInfos.state = IssuePRStateEnum.Close;
gitlabService.updatePullRequest(gitPRInfos);
const expectedUrl = `${
gitlabService.urlApi
}/projects/1/merge_requests/42`;
expectedConfig.params = {
title: 'pr title',
description: 'pr description',
state_event: 'close',
target_branch: 'master',
};
expect(httpService.put).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('createWebhook', () => {
it('should emit a POST request with specific params', () => {
const webhookURL: string = 'https://some.url.com';
gitlabService.createWebhook(webhookURL);
const expectedUrl = `${gitlabService.urlApi}/projects/1/hooks`;
expectedConfig.params = {
confidential_issues_events: true,
confidential_note_events: true,
enable_ssl_verification: true,
issues_events: true,
job_events: true,
merge_requests_events: true,
note_events: true,
pipeline_events: true,
push_events: true,
tag_push_events: true,
url: 'https://some.url.com',
wiki_page_events: true,
};
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('getIssues', () => {
it('should emit a GET request with specific params', () => {
const gitIssueSearch: GitIssuePRSearch = new GitIssuePRSearch();
gitIssueSearch.state = IssuePRStateEnum.Open;
gitIssueSearch.sort = IssueSortEnum.Asc;
httpService.get = jest.fn().mockImplementationOnce((...args) => {
return new Observable(observer => observer.next({ data: [] }));
});
gitlabService.getIssues(gitIssueSearch).catch(err => logger.error(err));
const expectedUrl = `${gitlabService.urlApi}/projects/1/issues`;
expectedConfig.params = {
sort: 'asc',
state: 'opened',
};
expect(httpService.get).toBeCalledWith(expectedUrl, expectedConfig);
});
});
describe('getPullRequests', () => {
it('should emit a GET request with specific params', () => {
const gitIssueSearch: GitIssuePRSearch = new GitIssuePRSearch();
gitIssueSearch.state = IssuePRStateEnum.Open;
gitIssueSearch.sort = IssueSortEnum.Asc;
httpService.get = jest.fn().mockImplementationOnce((...args) => {
return new Observable(observer => observer.next({ data: [] }));
});
gitlabService
.getPullRequests(gitIssueSearch)
.catch(err => logger.error(err));
const expectedUrl = `${gitlabService.urlApi}/projects/1/merge_requests`;
expectedConfig.params = {
sort: 'asc',
state: 'opened',
};
expect(httpService.get).toBeCalledWith(expectedUrl, expectedConfig);
});
});
describe('createRelease', () => {
it('should emit a POST request with specific params', () => {
const gitRelease = new GitRelease();
gitRelease.name = 'v0.0.1';
gitRelease.tag = 'v0.0.1';
gitRelease.description = 'this is the first release';
const expectedUrl = `${gitlabService.urlApi}/projects/1/releases`;
expectedConfig.params = {
name: 'v0.0.1',
tag_name: 'v0.0.1',
description: 'this is the first release',
};
gitlabService.createRelease(gitRelease);
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('createTag', () => {
it('should emit a POST request with specific params', () => {
const gitTag = new GitTag();
gitTag.sha = '1';
gitTag.tag = 'v0.0.1';
gitTag.type = 'commit';
gitTag.message = 'new tag';
const expectedUrl = `${gitlabService.urlApi}/projects/1/repository/tags`;
expectedConfig.params = {
message: 'new tag',
ref: '1',
tag_name: 'v0.0.1',
};
gitlabService.createTag(gitTag);
expect(httpService.post).toBeCalledWith(expectedUrl, {}, expectedConfig);
});
});
describe('getLastBranchesCommitSha', () => {
it('should emit a GET request with specific params', async () => {
httpService.get = jest.fn().mockImplementationOnce((...args) => {
return of({
data: [
{
name: 'develop',
commit: {
id: 'c072f9cab23bbd992a3acc3ad6eb4a6c70c7c5aa',
short_id: 'c072f9ca',
created_at: '2019-05-23T14:37:12.000+00:00',
parent_ids: null,
title: 'Merge branch master into develop',
message: 'Merge branch master into develop',
author_name: 'Bastien Terrier',
author_email: 'bastien.terrier@gmail.com',
authored_date: '2019-05-23T14:37:12.000+00:00',
committer_name: 'Bastien Terrier',
committer_email: 'bastien.terrier@gmail.com',
committed_date: '2019-05-23T14:37:12.000+00:00',
},
merged: false,
protected: false,
developers_can_push: false,
developers_can_merge: false,
can_push: false,
default: false,
},
{
name: 'gl-pages',
commit: {
id: '8a4d7d7d60d259679ef0edab2c156db8f7a7cd9d',
short_id: '8a4d7d7d',
created_at: '2019-06-03T13:12:14.000+00:00',
parent_ids: null,
title: 'Update README.md',
message: 'Update README.md',
author_name: 'Bastien Terrier',
author_email: 'bastien.terrier@gmail.com',
authored_date: '2019-06-03T13:12:14.000+00:00',
committer_name: 'Bastien Terrier',
committer_email: 'bastien.terrier@gmail.com',
committed_date: '2019-06-03T13:12:14.000+00:00',
},
merged: false,
protected: false,
developers_can_push: false,
developers_can_merge: false,
can_push: false,
default: false,
},
{
name: 'master',
commit: {
id: '9bcd827d36537f861c209a0b2a4d3006a281b707',
short_id: '9bcd827d',
created_at: '2019-06-04T14:31:27.000+00:00',
parent_ids: null,
title: 'test',
message: 'test',
author_name: 'TERRIER Bastien',
author_email: 'bastien.terrier@gmail.com',
authored_date: '2019-06-04T14:31:27.000+00:00',
committer_name: 'TERRIER Bastien',
committer_email: 'bastien.terrier@gmail.com',
committed_date: '2019-06-04T14:31:27.000+00:00',
},
merged: false,
protected: true,
developers_can_push: false,
developers_can_merge: false,
can_push: false,
default: true,
},
{
name: 'somebranch',
commit: {
id: 'b01a3298ec6f410bbcdf13667a6f6fda6d655442',
short_id: 'b01a3298',
created_at: '2019-06-04T10:43:54.000+00:00',
parent_ids: null,
title: 'fix(): #v0.1.0#',
message: 'fix(): #v0.1.0#',
author_name: 'TERRIER Bastien',
author_email: 'bastien.terrier@gmail.com',
authored_date: '2019-06-04T10:43:54.000+00:00',
committer_name: 'TERRIER Bastien',
committer_email: 'bastien.terrier@gmail.com',
committed_date: '2019-06-04T10:43:54.000+00:00',
},
merged: true,
protected: false,
developers_can_push: false,
developers_can_merge: false,
can_push: false,
default: false,
},
],
});
});
const result: GitBranchCommit[] = await gitlabService.getLastBranchesCommitSha();
const expectedUrl = `${
gitlabService.urlApi
}/projects/1/repository/branches`;
expectedConfig.params = {};
expect(httpService.get).toBeCalledWith(expectedUrl, expectedConfig);
expect(result).toEqual([
{
branch: 'develop',
commitSha: 'c072f9cab23bbd992a3acc3ad6eb4a6c70c7c5aa',
},
{
branch: 'gl-pages',
commitSha: '8a4d7d7d60d259679ef0edab2c156db8f7a7cd9d',
},
{
branch: 'master',
commitSha: '9bcd827d36537f861c209a0b2a4d3006a281b707',
},
{
branch: 'somebranch',
commitSha: 'b01a3298ec6f410bbcdf13667a6f6fda6d655442',
},
]);
});
});
// TESTS BEFORE
describe('setToken', () => {
it('should set the token', () => {
gitlabService.setToken('azertyuiop');
expect(gitlabService.token).toBe('azertyuiop');
});
});
describe('setUrlApi', () => {
it('should set the url of the API', () => {
gitlabService.setUrlApi('https://githubapi.com');
expect(gitlabService.urlApi).toBe('https://githubapi.com');
});
});
describe('setProjectId', () => {
it('should set the project Id', () => {
gitlabService.setProjectId('1');
expect(gitlabService.projectId).toBe('1');
});
});
describe('setEnvironmentVariables', () => {
it('should set the token and urlApi', async () => {
process.env.ENCRYPTION_KEY = 'somekey';
dataAccessService.readEnv = jest.fn().mockResolvedValue({
gitApi: 'https://mygitlabapi.com',
gitToken: Utils.encryptValue('gitlabToken'),
gitlabId: '1',
});
gitlabService.setToken = jest.fn().mockName('setTokenGitlab');
gitlabService.setUrlApi = jest.fn().mockName('setUrlApiGitlab');
gitlabService.setProjectId = jest.fn().mockName('setProjectIdGitlab');
await gitlabService.setEnvironmentVariables(
dataAccessService,
'some/repo',
);
expect(gitlabService.setToken).toBeCalledWith('gitlabToken');
expect(gitlabService.setUrlApi).toBeCalledWith('https://mygitlabapi.com');
expect(gitlabService.setProjectId).toBeCalledWith('1');
});
});
});