From d3cd35c5f2827b62e28db36fb8542fbe77bacc75 Mon Sep 17 00:00:00 2001 From: Niklas Lochschmidt Date: Thu, 15 Oct 2020 18:15:58 +0000 Subject: [PATCH] Add approval rule management (#1233) See: https://docs.gitlab.com/ee/api/merge_request_approvals.html * Move Approval API into MergeRequestApprovals Breaking change, see https://github.com/jdalrymple/gitbeaker/pull/1233#issuecomment-709262998 --- README.md | 2 + packages/gitbeaker-browser/src/index.ts | 1 + packages/gitbeaker-core/src/index.ts | 1 + .../src/services/MergeRequestApprovals.ts | 179 +++++++++++++ .../src/services/MergeRequests.ts | 86 ------- packages/gitbeaker-core/src/services/index.ts | 1 + .../test/unit/bundles/ProjectsBundle.ts | 1 + .../unit/services/MergeRequestApprovals.ts | 239 ++++++++++++++++++ .../test/unit/services/MergeRequests.ts | 97 ------- packages/gitbeaker-node/src/index.ts | 1 + 10 files changed, 425 insertions(+), 183 deletions(-) create mode 100644 packages/gitbeaker-core/src/services/MergeRequestApprovals.ts create mode 100644 packages/gitbeaker-core/test/unit/services/MergeRequestApprovals.ts diff --git a/README.md b/README.md index a690414b..30b39b62 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,7 @@ IssueAwardEmojis Jobs Labels MergeRequests +MergeRequestApprovals MergeRequestAwardEmojis MergeRequestDiscussions MergeRequestNotes @@ -334,6 +335,7 @@ IssueAwardEmojis Jobs Labels MergeRequests +MergeRequestApprovals MergeRequestAwardEmojis MergeRequestDiscussions MergeRequestNotes diff --git a/packages/gitbeaker-browser/src/index.ts b/packages/gitbeaker-browser/src/index.ts index 611977f9..fe28b021 100644 --- a/packages/gitbeaker-browser/src/index.ts +++ b/packages/gitbeaker-browser/src/index.ts @@ -47,6 +47,7 @@ export const { Jobs, Labels, MergeRequests, + MergeRequestApprovals, MergeRequestAwardEmojis, MergeRequestDiscussions, MergeRequestNotes, diff --git a/packages/gitbeaker-core/src/index.ts b/packages/gitbeaker-core/src/index.ts index 83ed1e53..6a403f57 100644 --- a/packages/gitbeaker-core/src/index.ts +++ b/packages/gitbeaker-core/src/index.ts @@ -54,6 +54,7 @@ export const ProjectsBundle = bundler({ Jobs: APIServices.Jobs, Labels: APIServices.Labels, MergeRequests: APIServices.MergeRequests, + MergeRequestApprovals: APIServices.MergeRequestApprovals, MergeRequestAwardEmojis: APIServices.MergeRequestAwardEmojis, MergeRequestDiscussions: APIServices.MergeRequestDiscussions, MergeRequestNotes: APIServices.MergeRequestNotes, diff --git a/packages/gitbeaker-core/src/services/MergeRequestApprovals.ts b/packages/gitbeaker-core/src/services/MergeRequestApprovals.ts new file mode 100644 index 00000000..51a142bb --- /dev/null +++ b/packages/gitbeaker-core/src/services/MergeRequestApprovals.ts @@ -0,0 +1,179 @@ +import { BaseService } from '@gitbeaker/requester-utils'; +import { BaseRequestOptions, RequestHelper, Sudo } from '../infrastructure'; + +export type ApprovalRulesRequestOptions = { + userIds?: number[]; + groupIds?: number[]; + protectedBranchIds?: number[]; +}; + +export class MergeRequestApprovals extends BaseService { + addApprovalRule( + projectId: string | number, + name: string, + approvalsRequired: number, + { + mergerequestIid, + ...options + }: { mergerequestIid?: number } & ApprovalRulesRequestOptions & BaseRequestOptions, + ) { + const pId = encodeURIComponent(projectId); + + let url; + + if (mergerequestIid) { + const mIid = encodeURIComponent(mergerequestIid); + url = `projects/${pId}/merge_requests/${mIid}/approval_rules`; + } else { + url = `projects/${pId}/approval_rules`; + } + + return RequestHelper.post(this, url, { name, approvalsRequired, ...options }); + } + + approvalRules( + projectId: string | number, + { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, + ) { + const pId = encodeURIComponent(projectId); + + let url; + + if (mergerequestIid) { + const mIid = encodeURIComponent(mergerequestIid); + url = `projects/${pId}/merge_requests/${mIid}/approval_rules`; + } else { + url = `projects/${pId}/approval_rules`; + } + return RequestHelper.get(this, url, options); + } + + approvals( + projectId: string | number, + { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, + ) { + const pId = encodeURIComponent(projectId); + + let url; + + if (mergerequestIid) { + const mIid = encodeURIComponent(mergerequestIid); + url = `projects/${pId}/merge_requests/${mIid}/approvals`; + } else { + url = `projects/${pId}/approvals`; + } + + return RequestHelper.get(this, url, options); + } + + approvalState( + projectId: string | number, + mergerequestIid: number, + options?: { sha?: string } & BaseRequestOptions, + ) { + const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); + + return RequestHelper.get( + this, + `projects/${pId}/merge_requests/${mIid}/approval_state`, + options, + ); + } + + approve( + projectId: string | number, + mergerequestIid: number, + options?: { sha?: string } & BaseRequestOptions, + ) { + const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); + + return RequestHelper.post(this, `projects/${pId}/merge_requests/${mIid}/approve`, options); + } + + approvers( + projectId: string | number, + approverIds: number[], + approverGroupIds: (string | number)[], + { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, + ) { + const pId = encodeURIComponent(projectId); + + let url; + + if (mergerequestIid) { + const mIid = encodeURIComponent(mergerequestIid); + url = `projects/${pId}/merge_requests/${mIid}/approvers`; + } else { + url = `projects/${pId}/approvers`; + } + + return RequestHelper.put(this, url, { approverIds, approverGroupIds, ...options }); + } + + editApprovalRule( + projectId: string | number, + approvalRuleId: number, + name: string, + approvalsRequired: number, + { + mergerequestIid, + ...options + }: { mergerequestIid?: number } & ApprovalRulesRequestOptions & BaseRequestOptions = {}, + ) { + const [pId, aId] = [projectId, approvalRuleId].map(encodeURIComponent); + + let url; + + if (mergerequestIid) { + const mIid = encodeURIComponent(mergerequestIid); + url = `projects/${pId}/merge_requests/${mIid}/approval_rules/${aId}`; + } else { + url = `projects/${pId}/approval_rules/${aId}`; + } + + return RequestHelper.put(this, url, { name, approvalsRequired, ...options }); + } + + editApprovals( + projectId: string | number, + { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, + ) { + const pId = encodeURIComponent(projectId); + + let url; + + if (mergerequestIid) { + const mIid = encodeURIComponent(mergerequestIid); + url = `projects/${pId}/merge_requests/${mIid}/approvals`; + } else { + url = `projects/${pId}/approvals`; + } + + return RequestHelper.post(this, url, options); + } + + removeApprovalRule( + projectId: string | number, + approvalRuleId: number, + { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, + ) { + const [pId, aId] = [projectId, approvalRuleId].map(encodeURIComponent); + + let url; + + if (mergerequestIid) { + const mIid = encodeURIComponent(mergerequestIid); + url = `projects/${pId}/merge_requests/${mIid}/approval_rules/${aId}`; + } else { + url = `projects/${pId}/approval_rules/${aId}`; + } + + return RequestHelper.del(this, url, options); + } + + unapprove(projectId: string | number, mergerequestIid: number, options?: Sudo) { + const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); + + return RequestHelper.post(this, `projects/${pId}/merge_requests/${mIid}/unapprove`, options); + } +} diff --git a/packages/gitbeaker-core/src/services/MergeRequests.ts b/packages/gitbeaker-core/src/services/MergeRequests.ts index c3dc689f..b3d1687b 100644 --- a/packages/gitbeaker-core/src/services/MergeRequests.ts +++ b/packages/gitbeaker-core/src/services/MergeRequests.ts @@ -131,68 +131,6 @@ export class MergeRequests extends BaseService { return RequestHelper.get(this, url, options); } - approve( - projectId: string | number, - mergerequestIid: number, - options?: { sha?: string } & BaseRequestOptions, - ) { - const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); - - return RequestHelper.post(this, `projects/${pId}/merge_requests/${mIid}/approve`, options); - } - - approvals( - projectId: string | number, - { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, - ) { - const pId = encodeURIComponent(projectId); - - let url; - - if (mergerequestIid) { - const mIid = encodeURIComponent(mergerequestIid); - url = `projects/${pId}/merge_requests/${mIid}/approvals`; - } else { - url = `projects/${pId}/approvals`; - } - - return RequestHelper.get(this, url, options); - } - - approvalState( - projectId: string | number, - mergerequestIid: number, - options?: { sha?: string } & BaseRequestOptions, - ) { - const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); - - return RequestHelper.get( - this, - `projects/${pId}/merge_requests/${mIid}/approval_state`, - options, - ); - } - - approvers( - projectId: string | number, - approverIds: number[], - approverGroupIds: (string | number)[], - { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, - ) { - const pId = encodeURIComponent(projectId); - - let url; - - if (mergerequestIid) { - const mIid = encodeURIComponent(mergerequestIid); - url = `projects/${pId}/merge_requests/${mIid}/approvers`; - } else { - url = `projects/${pId}/approvers`; - } - - return RequestHelper.put(this, url, { approverIds, approverGroupIds, ...options }); - } - cancelOnPipelineSucess(projectId: string | number, mergerequestIid: number, options?: Sudo) { const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); @@ -249,24 +187,6 @@ export class MergeRequests extends BaseService { return RequestHelper.put(this, `projects/${pId}/merge_requests/${mIid}`, options); } - editApprovals( - projectId: string | number, - { mergerequestIid, ...options }: { mergerequestIid?: number } & BaseRequestOptions = {}, - ) { - const pId = encodeURIComponent(projectId); - - let url; - - if (mergerequestIid) { - const mIid = encodeURIComponent(mergerequestIid); - url = `projects/${pId}/merge_requests/${mIid}/approvals`; - } else { - url = `projects/${pId}/approvals`; - } - - return RequestHelper.post(this, url, options); - } - participants(projectId: string | number, mergerequestIid: number, options?: Sudo) { const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); @@ -349,12 +269,6 @@ export class MergeRequests extends BaseService { return RequestHelper.get(this, `projects/${pId}/merge_requests/${mIid}/versions`, options); } - unapprove(projectId: string | number, mergerequestIid: number, options?: Sudo) { - const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); - - return RequestHelper.post(this, `projects/${pId}/merge_requests/${mIid}/unapprove`, options); - } - unsubscribe(projectId: string | number, mergerequestIid: number, options?: Sudo) { const [pId, mIid] = [projectId, mergerequestIid].map(encodeURIComponent); diff --git a/packages/gitbeaker-core/src/services/index.ts b/packages/gitbeaker-core/src/services/index.ts index 6c36487e..32bd97e0 100644 --- a/packages/gitbeaker-core/src/services/index.ts +++ b/packages/gitbeaker-core/src/services/index.ts @@ -41,6 +41,7 @@ export { IssueAwardEmojis } from './IssueAwardEmojis'; export { Jobs } from './Jobs'; export { Labels } from './Labels'; export { MergeRequests } from './MergeRequests'; +export { MergeRequestApprovals } from './MergeRequestApprovals'; export { MergeRequestAwardEmojis } from './MergeRequestAwardEmojis'; export { MergeRequestDiscussions } from './MergeRequestDiscussions'; export { MergeRequestNotes } from './MergeRequestNotes'; diff --git a/packages/gitbeaker-core/test/unit/bundles/ProjectsBundle.ts b/packages/gitbeaker-core/test/unit/bundles/ProjectsBundle.ts index 6c47fed8..3a4ea36a 100644 --- a/packages/gitbeaker-core/test/unit/bundles/ProjectsBundle.ts +++ b/packages/gitbeaker-core/test/unit/bundles/ProjectsBundle.ts @@ -17,6 +17,7 @@ test('All the correct service keys are included in the projects bundle', async ( 'Jobs', 'Labels', 'MergeRequests', + 'MergeRequestApprovals', 'MergeRequestAwardEmojis', 'MergeRequestDiscussions', 'MergeRequestNotes', diff --git a/packages/gitbeaker-core/test/unit/services/MergeRequestApprovals.ts b/packages/gitbeaker-core/test/unit/services/MergeRequestApprovals.ts new file mode 100644 index 00000000..21b9239c --- /dev/null +++ b/packages/gitbeaker-core/test/unit/services/MergeRequestApprovals.ts @@ -0,0 +1,239 @@ +import { RequesterType } from '@gitbeaker/requester-utils'; +import { RequestHelper } from '../../../src/infrastructure'; +import { MergeRequestApprovals } from '../../../src'; + +jest.mock('../../../src/infrastructure/RequestHelper'); + +let service: MergeRequestApprovals; + +beforeEach(() => { + const requester = { + get: jest.fn(() => Promise.resolve([])), + post: jest.fn(() => Promise.resolve({})), + put: jest.fn(() => Promise.resolve({})), + delete: jest.fn(() => Promise.resolve({})), + } as RequesterType; + + service = new MergeRequestApprovals({ + requester, + token: 'abcdefg', + requestTimeout: 3000, + }); +}); + +describe('Instantiating MergeRequestApprovals service', () => { + it('should create a valid service object', async () => { + expect(service).toBeInstanceOf(MergeRequestApprovals); + expect(service.url).toBeDefined(); + expect(service.rejectUnauthorized).toBeTruthy(); + expect(service.headers).toMatchObject({ 'private-token': 'abcdefg' }); + expect(service.requestTimeout).toBe(3000); + }); +}); + +describe('MergeRequests.addApprovalRules', () => { + it('should request POST /projects/:id/approval_rules', async () => { + await service.addApprovalRule(2, 'Some rule', 5, { + userIds: [1, 2], + groupIds: [3, 4], + protectedBranchIds: [5, 6], + }); + + expect(RequestHelper.post).toHaveBeenCalledWith(service, 'projects/2/approval_rules', { + name: 'Some rule', + approvalsRequired: 5, + userIds: [1, 2], + groupIds: [3, 4], + protectedBranchIds: [5, 6], + }); + }); + + it('should request POST /projects/:id/merge_requests/:merge_request_iid/approval_rules when mergerequestIid is passed', async () => { + await service.addApprovalRule(2, 'Some rule', 5, { + mergerequestIid: 3, + userIds: [1, 2], + groupIds: [3, 4], + }); + + expect(RequestHelper.post).toHaveBeenCalledWith( + service, + 'projects/2/merge_requests/3/approval_rules', + { + name: 'Some rule', + approvalsRequired: 5, + userIds: [1, 2], + groupIds: [3, 4], + }, + ); + }); +}); + +describe('MergeRequests.approvals', () => { + it('should request GET /projects/:id/approvals', async () => { + await service.approvals(3); + + expect(RequestHelper.get).toHaveBeenCalledWith(service, 'projects/3/approvals', {}); + }); + + it('should request GET /projects/:id/merge_requests/:merge_request_iid/approvals when mergerequestIid Id is passed', async () => { + await service.approvals(3, { mergerequestIid: 1 }); + + expect(RequestHelper.get).toHaveBeenCalledWith( + service, + 'projects/3/merge_requests/1/approvals', + {}, + ); + }); +}); + +describe('MergeRequests.approvalRules', () => { + it('should request GET /projects/:id/approval_rules', async () => { + await service.approvalRules(2); + + expect(RequestHelper.get).toHaveBeenCalledWith(service, 'projects/2/approval_rules', {}); + }); + + it('should request GET /projects/:id/merge_requests/:merge_request_iid/approval_rules when mergerequestIid Id is passed', async () => { + await service.approvalRules(2, { mergerequestIid: 3 }); + + expect(RequestHelper.get).toHaveBeenCalledWith( + service, + 'projects/2/merge_requests/3/approval_rules', + {}, + ); + }); +}); + +describe('MergeRequests.approvalState', () => { + it('should request GET /projects/:id/merge_requests/:merge_request_iid/approval_state', async () => { + await service.approvalState(2, 3); + + expect(RequestHelper.get).toHaveBeenCalledWith( + service, + 'projects/2/merge_requests/3/approval_state', + undefined, + ); + }); +}); + +describe('MergeRequests.approve', () => { + it('should request POST /projects/:id/merge_requests/:merge_request_iid/approve', async () => { + await service.approve(2, 3); + + expect(RequestHelper.post).toHaveBeenCalledWith( + service, + 'projects/2/merge_requests/3/approve', + undefined, + ); + }); +}); + +describe('MergeRequests.approvers', () => { + it('should request PUT /projects/:id/approvers', async () => { + await service.approvers(3, [4, 5], [6, 7]); + + expect(RequestHelper.put).toHaveBeenCalledWith(service, 'projects/3/approvers', { + approverIds: [4, 5], + approverGroupIds: [6, 7], + }); + }); + + it('should request PUT /projects/:id/merge_requests/:merge_request_iid/approvers when mergerequestIid Id is passed', async () => { + await service.approvers(3, [4, 5], [6, 7], { + approverIds: [4, 5], + approverGroupIds: [6, 7], + mergerequestIid: 1, + }); + + expect(RequestHelper.put).toHaveBeenCalledWith( + service, + 'projects/3/merge_requests/1/approvers', + { approverIds: [4, 5], approverGroupIds: [6, 7] }, + ); + }); +}); + +describe('MergeRequests.editApprovalRules', () => { + it('should request PUT /projects/:id/approval_rules/:approval_rule_id', async () => { + await service.editApprovalRule(2, 30, 'Some rule', 5, { + userIds: [1, 2], + groupIds: [3, 4], + protectedBranchIds: [5, 6], + }); + + expect(RequestHelper.put).toHaveBeenCalledWith(service, 'projects/2/approval_rules/30', { + name: 'Some rule', + approvalsRequired: 5, + userIds: [1, 2], + groupIds: [3, 4], + protectedBranchIds: [5, 6], + }); + }); + + it('should request PUT /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id when mergerequestIid is passed', async () => { + await service.editApprovalRule(2, 30, 'Some rule', 5, { + mergerequestIid: 3, + userIds: [1, 2], + groupIds: [3, 4], + }); + + expect(RequestHelper.put).toHaveBeenCalledWith( + service, + 'projects/2/merge_requests/3/approval_rules/30', + { + name: 'Some rule', + approvalsRequired: 5, + userIds: [1, 2], + groupIds: [3, 4], + }, + ); + }); +}); + +describe('MergeRequests.editApprovals', () => { + it('should request POST /projects/:id/approvals', async () => { + await service.editApprovals(3, { prop: 4 }); + + expect(RequestHelper.post).toHaveBeenCalledWith(service, 'projects/3/approvals', { prop: 4 }); + }); + + it('should request POST /projects/:id/merge_requests/:merge_request_iid/approvals when mergerequestIid Id is passed', async () => { + await service.editApprovals(3, { mergerequestIid: 1, prop: 4 }); + + expect(RequestHelper.post).toHaveBeenCalledWith( + service, + 'projects/3/merge_requests/1/approvals', + { prop: 4 }, + ); + }); +}); + +describe('MergeRequests.removeApprovalRules', () => { + it('should request DELETE /projects/:id/approval_rules/:approval_rule_id', async () => { + await service.removeApprovalRule(2, 30); + + expect(RequestHelper.del).toHaveBeenCalledWith(service, 'projects/2/approval_rules/30', {}); + }); + + it('should request DELETE /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id when mergerequestIid is passed', async () => { + await service.removeApprovalRule(2, 30, { mergerequestIid: 3 }); + + expect(RequestHelper.del).toHaveBeenCalledWith( + service, + 'projects/2/merge_requests/3/approval_rules/30', + {}, + ); + }); +}); + +describe('MergeRequests.unapprove', () => { + it('should request POST /projects/:id/merge_requests/:merge_request_iid/unapprove', async () => { + await service.unapprove(2, 3); + + expect(RequestHelper.post).toHaveBeenCalledWith( + service, + 'projects/2/merge_requests/3/unapprove', + undefined, + ); + }); +}); diff --git a/packages/gitbeaker-core/test/unit/services/MergeRequests.ts b/packages/gitbeaker-core/test/unit/services/MergeRequests.ts index 8081814c..37f202f0 100644 --- a/packages/gitbeaker-core/test/unit/services/MergeRequests.ts +++ b/packages/gitbeaker-core/test/unit/services/MergeRequests.ts @@ -91,73 +91,6 @@ describe('MergeRequests.all', () => { }); }); -describe('MergeRequests.approve', () => { - it('should request POST projects/:id/merge_requests:id/approve', async () => { - await service.approve(2, 3); - - expect(RequestHelper.post).toHaveBeenCalledWith( - service, - 'projects/2/merge_requests/3/approve', - undefined, - ); - }); -}); - -describe('MergeRequests.approvals', () => { - it('should request GET /projects/:id/approvals', async () => { - await service.approvals(3); - - expect(RequestHelper.get).toHaveBeenCalledWith(service, 'projects/3/approvals', {}); - }); - - it('should request GET /projects/:id/merge_requests/:id when mergerequestIid Id is passed', async () => { - await service.approvals(3, { mergerequestIid: 1 }); - - expect(RequestHelper.get).toHaveBeenCalledWith( - service, - 'projects/3/merge_requests/1/approvals', - {}, - ); - }); -}); - -describe('MergeRequests.approvalState', () => { - it('should request GET projects/:id/merge_requests/:id/approval_state', async () => { - await service.approvalState(2, 3); - - expect(RequestHelper.get).toHaveBeenCalledWith( - service, - 'projects/2/merge_requests/3/approval_state', - undefined, - ); - }); -}); - -describe('MergeRequests.approvers', () => { - it('should request PUT /projects/:id/approvers', async () => { - await service.approvers(3, [4, 5], [6, 7]); - - expect(RequestHelper.put).toHaveBeenCalledWith(service, 'projects/3/approvers', { - approverIds: [4, 5], - approverGroupIds: [6, 7], - }); - }); - - it('should request PUT /projects/:id/merge_requests/:id when mergerequestIid Id is passed', async () => { - await service.approvers(3, [4, 5], [6, 7], { - approverIds: [4, 5], - approverGroupIds: [6, 7], - mergerequestIid: 1, - }); - - expect(RequestHelper.put).toHaveBeenCalledWith( - service, - 'projects/3/merge_requests/1/approvers', - { approverIds: [4, 5], approverGroupIds: [6, 7] }, - ); - }); -}); - describe('MergeRequests.cancelOnPipelineSucess', () => { it('should request PUT projects/:id/merge_requests/:id/cancel_merge_when_pipeline_succeeds', async () => { await service.cancelOnPipelineSucess(2, 3); @@ -230,24 +163,6 @@ describe('MergeRequests.edit', () => { }); }); -describe('MergeRequests.editApprovals', () => { - it('should request POST /projects/:id/approvals', async () => { - await service.editApprovals(3, { prop: 4 }); - - expect(RequestHelper.post).toHaveBeenCalledWith(service, 'projects/3/approvals', { prop: 4 }); - }); - - it('should request POST /projects/:id/merge_requests/:id when mergerequestIid Id is passed', async () => { - await service.editApprovals(3, { mergerequestIid: 1, prop: 4 }); - - expect(RequestHelper.post).toHaveBeenCalledWith( - service, - 'projects/3/merge_requests/1/approvals', - { prop: 4 }, - ); - }); -}); - describe('MergeRequests.participants', () => { it('should request GET /projects/:id/merge_requests/:id/participants', async () => { await service.participants(1, 2); @@ -368,18 +283,6 @@ describe('MergeRequests.versions', () => { }); }); -describe('MergeRequests.unapprove', () => { - it('should request POST projects/:id/merge_requests/:iid/unapprove', async () => { - await service.unapprove(2, 3); - - expect(RequestHelper.post).toHaveBeenCalledWith( - service, - 'projects/2/merge_requests/3/unapprove', - undefined, - ); - }); -}); - describe('MergeRequests.unsubscribe', () => { it('should request DEL projects/:id/merge_requests/:iid/unsubscribe', async () => { await service.unsubscribe(2, 3); diff --git a/packages/gitbeaker-node/src/index.ts b/packages/gitbeaker-node/src/index.ts index 609d9c97..cd6b9a2e 100644 --- a/packages/gitbeaker-node/src/index.ts +++ b/packages/gitbeaker-node/src/index.ts @@ -47,6 +47,7 @@ export const { Jobs, Labels, MergeRequests, + MergeRequestApprovals, MergeRequestAwardEmojis, MergeRequestDiscussions, MergeRequestNotes,