feat: integrate tool with gitlab service (#39)

* feat: integrate tool with gitlab service

Fix https://github.com/lampajr/backporting/issues/30
This commit is contained in:
Andrea Lamparelli 2023-07-02 00:05:17 +02:00 committed by GitHub
parent 8a007941d1
commit 107f5e52d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 17821 additions and 1553 deletions

View file

@ -0,0 +1,34 @@
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import GitHubClient from "@bp/service/git/github/github-client";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
describe("git client factory test", () => {
beforeEach(() => {
// reset git service
GitClientFactory.reset();
});
test("correctly create github client", () => {
const client = GitClientFactory.getOrCreate(GitClientType.GITHUB, "auth", "apiurl");
expect(client).toBeInstanceOf(GitHubClient);
});
test("correctly create gitlab client", () => {
const client = GitClientFactory.getOrCreate(GitClientType.GITLAB, "auth", "apiurl");
expect(client).toBeInstanceOf(GitLabClient);
});
test("check get service github", () => {
const create = GitClientFactory.getOrCreate(GitClientType.GITHUB, "auth", "apiurl");
const get = GitClientFactory.getClient();
expect(create).toStrictEqual(get);
});
test("check get service gitlab", () => {
const create = GitClientFactory.getOrCreate(GitClientType.GITLAB, "auth", "apiurl");
const get = GitClientFactory.getClient();
expect(create).toStrictEqual(get);
});
});

View file

@ -0,0 +1,37 @@
import { inferGitApiUrl, inferGitClient } from "@bp/service/git/git-util";
import { GitClientType } from "@bp/service/git/git.types";
describe("check git utilities", () => {
test("check infer gitlab api", ()=> {
expect(inferGitApiUrl("https://my.gitlab.awesome.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual("https://my.gitlab.awesome.com/api/v4");
});
test("check infer gitlab api with different version", ()=> {
expect(inferGitApiUrl("http://my.gitlab.awesome.com/superuser/backporting-example/-/merge_requests/4", "v2")).toStrictEqual("http://my.gitlab.awesome.com/api/v2");
});
test("check infer github api", ()=> {
expect(inferGitApiUrl("https://github.com/superuser/backporting-example/pull/4")).toStrictEqual("https://api.github.com");
});
test("check infer custom github api", ()=> {
expect(inferGitApiUrl("http://github.acme-inc.com/superuser/backporting-example/pull/4")).toStrictEqual("http://github.acme-inc.com/api/v4");
});
test("check infer custom github api with different version", ()=> {
expect(inferGitApiUrl("http://github.acme-inc.com/superuser/backporting-example/pull/4", "v3")).toStrictEqual("http://github.acme-inc.com/api/v3");
});
test("check infer github client", ()=> {
expect(inferGitClient("https://github.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual(GitClientType.GITHUB);
});
test("check infer gitlab client", ()=> {
expect(inferGitClient("https://my.gitlab.awesome.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual(GitClientType.GITLAB);
});
test("Not recognized git client type", ()=> {
expect(() => inferGitClient("https://not.recognized/superuser/backporting-example/-/merge_requests/4")).toThrowError("Remote git service not recognized from pr url: https://not.recognized/superuser/backporting-example/-/merge_requests/4");
});
});

View file

@ -1,27 +1,28 @@
import GitServiceFactory from "@bp/service/git/git-service-factory";
import { GitPullRequest, GitServiceType } from "@bp/service/git/git.types";
import GitHubService from "@bp/service/git/github/github-service";
import { mergedPullRequestFixture, repo, targetOwner } from "../../../support/moctokit/moctokit-data";
import { setupMoctokit } from "../../../support/moctokit/moctokit-support";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitPullRequest, GitClientType } from "@bp/service/git/git.types";
import GitHubClient from "@bp/service/git/github/github-client";
import { mergedPullRequestFixture, repo, targetOwner } from "../../../support/mock/github-data";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
describe("github service", () => {
let gitService: GitHubService;
let gitClient: GitHubClient;
beforeAll(() => {
// init git service
GitServiceFactory.getOrCreate(GitServiceType.GITHUB, "whatever");
GitClientFactory.reset();
GitClientFactory.getOrCreate(GitClientType.GITHUB, "whatever", "http://localhost/api/v3");
});
beforeEach(() => {
// mock github api calls
setupMoctokit();
mockGitHubClient("http://localhost/api/v3");
gitService = GitServiceFactory.getService() as GitHubService;
gitClient = GitClientFactory.getClient() as GitHubClient;
});
test("get pull request: success", async () => {
const res: GitPullRequest = await gitService.getPullRequest(targetOwner, repo, mergedPullRequestFixture.number);
const res: GitPullRequest = await gitClient.getPullRequest(targetOwner, repo, mergedPullRequestFixture.number);
expect(res.sourceRepo).toEqual({
owner: "fork",
project: "reponame",

View file

@ -0,0 +1,249 @@
import GitClientFactory from "@bp/service/git/git-client-factory";
import { NEW_GITLAB_MR_ID, SECOND_NEW_GITLAB_MR_ID, getAxiosMocked, postAxiosMocked, putAxiosMocked } from "../../../support/mock/git-client-mock-support";
import { BackportPullRequest, GitClientType, GitPullRequest } from "@bp/service/git/git.types";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import axios from "axios";
jest.mock("axios");
const axiosSpy = axios.create as jest.Mock;
let axiosInstanceSpy: {[key: string]: jest.Func};
function setupAxiosSpy() {
const getSpy = jest.fn(getAxiosMocked);
const postSpy = jest.fn(postAxiosMocked);
const putSpy = jest.fn(putAxiosMocked);
const axiosInstance = {
get: getSpy,
post: postSpy,
put: putSpy,
};
axiosSpy.mockImplementation(() => (axiosInstance));
return axiosInstance;
}
describe("github service", () => {
let gitClient: GitLabClient;
beforeEach(() => {
axiosInstanceSpy = setupAxiosSpy();
GitClientFactory.reset();
gitClient = GitClientFactory.getOrCreate(GitClientType.GITLAB, "whatever", "apiUrl") as GitLabClient;
});
afterEach(() => {
jest.clearAllMocks();
});
test("get merged pull request", async () => {
const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 1);
// check content
expect(res.sourceRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.targetRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.title).toBe("Update test.txt");
expect(res.commits!.length).toBe(1);
expect(res.commits).toEqual(["ebb1eca696c42fd067658bd9b5267709f78ef38e"]);
// check axios invocation
expect(axiosInstanceSpy.get).toBeCalledTimes(3); // merge request and 2 repos
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/1");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
});
test("get open pull request", async () => {
const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 2);
expect(res.sourceRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.targetRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.title).toBe("Update test.txt opened");
expect(res.commits!.length).toBe(1);
expect(res.commits).toEqual(["9e15674ebd48e05c6e428a1fa31dbb60a778d644"]);
// check axios invocation
expect(axiosInstanceSpy.get).toBeCalledTimes(3); // merge request and 2 repos
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/2");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
});
test("create backport pull request without reviewers and assignees", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch",
reviewers: [],
assignees: [],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(0); // no reviewers nor assignees
expect(axiosInstanceSpy.put).toBeCalledTimes(0); // no reviewers nor assignees
});
test("create backport pull request with reviewers", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch",
reviewers: ["superuser", "invalid"],
assignees: [],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just reviewers, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just reviewers
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + NEW_GITLAB_MR_ID, {
reviewer_ids: [14041],
});
});
test("create backport pull request with assignees", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch",
reviewers: [],
assignees: ["superuser", "invalid"],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just assignees, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just assignees
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + NEW_GITLAB_MR_ID, {
assignee_ids: [14041],
});
});
test("create backport pull request with failure assigning reviewers", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch-2",
reviewers: ["superuser", "invalid"],
assignees: [],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch-2",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just reviewers, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just reviewers
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID, {
reviewer_ids: [14041],
});
});
test("create backport pull request with failure assigning assignees", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch-2",
reviewers: [],
assignees: ["superuser", "invalid"],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch-2",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just assignees, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just assignees
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID, {
assignee_ids: [14041],
});
});
});