Refactored to provide better API for Builds
Signed-off-by: Andre Wanlin <awanlin@rapidrtc.com>
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
|
||||
```ts
|
||||
import { Build } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { BuildDefinitionReference } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { BuildRun } from '@backstage/plugin-azure-devops-common';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common';
|
||||
import express from 'express';
|
||||
@@ -25,9 +27,8 @@ export class AzureDevOpsApi {
|
||||
// (undocumented)
|
||||
getBuildList(
|
||||
projectName: string,
|
||||
definitions?: number[],
|
||||
repoId?: string,
|
||||
top?: number,
|
||||
repoId: string,
|
||||
top: number,
|
||||
): Promise<Build[]>;
|
||||
// (undocumented)
|
||||
getDashboardPullRequests(
|
||||
|
||||
@@ -29,277 +29,510 @@ import {
|
||||
GitPullRequest,
|
||||
GitRepository,
|
||||
} from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import { mappedPullRequest, mappedRepoBuild } from './AzureDevOpsApi';
|
||||
import {
|
||||
mappedBuildRun,
|
||||
mappedPullRequest,
|
||||
mappedRepoBuild,
|
||||
} from './AzureDevOpsApi';
|
||||
|
||||
import { IdentityRef } from 'azure-devops-node-api/interfaces/common/VSSInterfaces';
|
||||
|
||||
describe('AzureDevOpsApi', () => {
|
||||
describe('mappedRepoBuild', () => {
|
||||
it('should return RepoBuild from Build', () => {
|
||||
const inputBuildDefinition: DefinitionReference = {
|
||||
name: 'My Build Definition',
|
||||
};
|
||||
describe('mappedRepoBuild happy path', () => {
|
||||
it('should return RepoBuild from Build', () => {
|
||||
const inputBuildDefinition: DefinitionReference = {
|
||||
name: 'My Build Definition',
|
||||
};
|
||||
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: inputBuildDefinition,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: inputBuildDefinition,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with no Build definition name', () => {
|
||||
it('should return RepoBuild with only Build Number for title', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
describe('mappedRepoBuild with no Build definition name', () => {
|
||||
it('should return RepoBuild with only Build Number for title', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with undefined status', () => {
|
||||
it('should return BuildStatus of None for status', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
describe('mappedRepoBuild with undefined status', () => {
|
||||
it('should return BuildStatus of None for status', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: undefined,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: undefined,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.None,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.None,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with undefined result', () => {
|
||||
it('should return BuildResult of None for result', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
describe('mappedRepoBuild with undefined result', () => {
|
||||
it('should return BuildResult of None for result', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with undefined link', () => {
|
||||
it('should return empty string for link', () => {
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
describe('mappedRepoBuild with undefined link', () => {
|
||||
it('should return empty string for link', () => {
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: undefined,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: undefined,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: '',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: '',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedPullRequest', () => {
|
||||
it('should return PullRequest from GitPullRequest', () => {
|
||||
const inputGitRepository: GitRepository = {
|
||||
name: 'super-feature-repo',
|
||||
};
|
||||
describe('mappedPullRequest happy path', () => {
|
||||
it('should return PullRequest from GitPullRequest', () => {
|
||||
const inputGitRepository: GitRepository = {
|
||||
name: 'super-feature-repo',
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputPullRequest: GitPullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repository: inputGitRepository,
|
||||
title: 'My Awesome New Feature',
|
||||
createdBy: inputIdentityRef,
|
||||
creationDate: new Date('2020-09-12T06:10:23.932Z'),
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
};
|
||||
const inputPullRequest: GitPullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repository: inputGitRepository,
|
||||
title: 'My Awesome New Feature',
|
||||
createdBy: inputIdentityRef,
|
||||
creationDate: new Date('2020-09-12T06:10:23.932Z'),
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
};
|
||||
|
||||
const inputBaseUrl =
|
||||
'https://host.com/myOrg/_git/super-feature-repo/pullrequest';
|
||||
const inputBaseUrl =
|
||||
'https://host.com/myOrg/_git/super-feature-repo/pullrequest';
|
||||
|
||||
const outputPullRequest: PullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repoName: 'super-feature-repo',
|
||||
title: 'My Awesome New Feature',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
createdBy: 'Jane Doe',
|
||||
creationDate: '2020-09-12T06:10:23.932Z',
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
link: 'https://host.com/myOrg/_git/super-feature-repo/pullrequest/7181',
|
||||
};
|
||||
const outputPullRequest: PullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repoName: 'super-feature-repo',
|
||||
title: 'My Awesome New Feature',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
createdBy: 'Jane Doe',
|
||||
creationDate: '2020-09-12T06:10:23.932Z',
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
link: 'https://host.com/myOrg/_git/super-feature-repo/pullrequest/7181',
|
||||
};
|
||||
|
||||
expect(mappedPullRequest(inputPullRequest, inputBaseUrl)).toEqual(
|
||||
outputPullRequest,
|
||||
);
|
||||
expect(mappedPullRequest(inputPullRequest, inputBaseUrl)).toEqual(
|
||||
outputPullRequest,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun', () => {
|
||||
describe('mappedBuildRun happy path', () => {
|
||||
it('should return RepoBuild from Build', () => {
|
||||
const inputBuildDefinition: DefinitionReference = {
|
||||
name: 'My Build Definition',
|
||||
};
|
||||
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: inputBuildDefinition,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with no Build definition name', () => {
|
||||
it('should return RepoBuild with only Build Number for title', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with undefined status', () => {
|
||||
it('should return BuildStatus of None for status', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: undefined,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.None,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with undefined result', () => {
|
||||
it('should return BuildResult of None for result', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with undefined link', () => {
|
||||
it('should return empty string for link', () => {
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: undefined,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: '',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Build,
|
||||
BuildDefinitionReference,
|
||||
} from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import {
|
||||
BuildResult,
|
||||
BuildRun,
|
||||
BuildStatus,
|
||||
DashboardPullRequest,
|
||||
Policy,
|
||||
@@ -35,7 +40,6 @@ import {
|
||||
getArtifactId,
|
||||
} from '../utils';
|
||||
|
||||
import { Build, BuildDefinitionReference } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { Logger } from 'winston';
|
||||
import { PolicyEvaluationRecord } from 'azure-devops-node-api/interfaces/PolicyInterfaces';
|
||||
import { TeamMember } from 'azure-devops-node-api/interfaces/common/VSSInterfaces';
|
||||
@@ -60,46 +64,19 @@ export class AzureDevOpsApi {
|
||||
return client.getRepository(repoName, projectName);
|
||||
}
|
||||
|
||||
public async getBuildDefinitions(
|
||||
projectName: string,
|
||||
definitionName: string,
|
||||
): Promise<BuildDefinitionReference[]> {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting Build Definitions for ${definitionName} in Project ${projectName}`,
|
||||
);
|
||||
|
||||
const client = await this.webApi.getBuildApi();
|
||||
return client.getDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
|
||||
public async getBuildList(
|
||||
projectName: string,
|
||||
definitions?: number[],
|
||||
repoId?: string,
|
||||
top?: number,
|
||||
repoId: string,
|
||||
top: number,
|
||||
): Promise<Build[]> {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting up to ${top} Builds for Repository Id ${repoId} for Project ${projectName}`,
|
||||
);
|
||||
|
||||
const client = await this.webApi.getBuildApi();
|
||||
return client.getBuilds(
|
||||
projectName,
|
||||
definitions,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -118,7 +95,7 @@ export class AzureDevOpsApi {
|
||||
undefined,
|
||||
undefined,
|
||||
repoId,
|
||||
repoId ? 'TfsGit' : undefined,
|
||||
'TfsGit',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -134,7 +111,6 @@ export class AzureDevOpsApi {
|
||||
const gitRepository = await this.getGitRepository(projectName, repoName);
|
||||
const buildList = await this.getBuildList(
|
||||
projectName,
|
||||
undefined,
|
||||
gitRepository.id as string,
|
||||
top,
|
||||
);
|
||||
@@ -146,34 +122,6 @@ export class AzureDevOpsApi {
|
||||
return repoBuilds;
|
||||
}
|
||||
|
||||
public async getDefinitionBuilds(
|
||||
projectName: string,
|
||||
definitionName: string,
|
||||
top: number,
|
||||
) {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting up to ${top} Builds for ${definitionName} in Project ${projectName}`,
|
||||
);
|
||||
|
||||
const buildDefinitions = await this.getBuildDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
);
|
||||
const definitions = buildDefinitions.map(bd => bd.id) as number[];
|
||||
const buildList = await this.getBuildList(
|
||||
projectName,
|
||||
definitions,
|
||||
undefined,
|
||||
top,
|
||||
);
|
||||
|
||||
const repoBuilds: RepoBuild[] = buildList.map(build => {
|
||||
return mappedRepoBuild(build);
|
||||
});
|
||||
|
||||
return repoBuilds;
|
||||
}
|
||||
|
||||
public async getPullRequests(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
@@ -313,6 +261,101 @@ export class AzureDevOpsApi {
|
||||
return teamMembers
|
||||
.map(teamMember => teamMember.identity?.id)
|
||||
.filter((id): id is string => Boolean(id));
|
||||
public async getBuildDefinitions(
|
||||
projectName: string,
|
||||
definitionName: string,
|
||||
): Promise<BuildDefinitionReference[]> {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting Build Definitions for ${definitionName} in Project ${projectName}`,
|
||||
);
|
||||
|
||||
const client = await this.webApi.getBuildApi();
|
||||
return client.getDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
|
||||
public async getBuilds(
|
||||
projectName: string,
|
||||
top: number,
|
||||
repoId?: string,
|
||||
definitions?: number[],
|
||||
): Promise<Build[]> {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting up to ${top} Builds for Repository Id ${repoId} for Project ${projectName}`,
|
||||
);
|
||||
|
||||
const client = await this.webApi.getBuildApi();
|
||||
return client.getBuilds(
|
||||
projectName,
|
||||
definitions,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
top,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
repoId,
|
||||
repoId ? 'TfsGit' : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
public async getBuildRuns(
|
||||
projectName: string,
|
||||
top: number,
|
||||
repoName?: string,
|
||||
definitionName?: string,
|
||||
) {
|
||||
let repoId: string | undefined;
|
||||
let definitions: number[] | undefined;
|
||||
|
||||
if (repoName) {
|
||||
const gitRepository = await this.getGitRepository(projectName, repoName);
|
||||
repoId = gitRepository.id;
|
||||
}
|
||||
|
||||
if (definitionName) {
|
||||
const buildDefinitions = await this.getBuildDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
);
|
||||
definitions = buildDefinitions.map(bd => bd.id) as number[];
|
||||
}
|
||||
|
||||
const builds = await this.getBuilds(projectName, top, repoId, definitions);
|
||||
|
||||
const buildRuns: BuildRun[] = builds.map(build => {
|
||||
return mappedBuildRun(build);
|
||||
});
|
||||
|
||||
return buildRuns;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,3 +394,20 @@ export function mappedPullRequest(
|
||||
link: `${linkBaseUrl}/${pullRequest.pullRequestId}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function mappedBuildRun(build: Build): BuildRun {
|
||||
return {
|
||||
id: build.id,
|
||||
title: [build.definition?.name, build.buildNumber]
|
||||
.filter(Boolean)
|
||||
.join(' - '),
|
||||
link: build._links?.web.href ?? '',
|
||||
status: build.status ?? BuildStatus.None,
|
||||
result: build.result ?? BuildResult.None,
|
||||
queueTime: build.queueTime?.toISOString(),
|
||||
startTime: build.startTime?.toISOString(),
|
||||
finishTime: build.finishTime?.toISOString(),
|
||||
source: `${build.sourceBranch} (${build.sourceVersion?.substr(0, 8)})`,
|
||||
uniqueName: build.requestedFor?.uniqueName ?? 'N/A',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Build,
|
||||
BuildDefinitionReference,
|
||||
} from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import {
|
||||
BuildResult,
|
||||
BuildRun,
|
||||
BuildStatus,
|
||||
PullRequest,
|
||||
PullRequestStatus,
|
||||
@@ -23,7 +28,6 @@ import {
|
||||
} from '@backstage/plugin-azure-devops-common';
|
||||
|
||||
import { AzureDevOpsApi } from '../api';
|
||||
import { Build, BuildDefinitionReference } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { GitRepository } from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import { createRouter } from './router';
|
||||
@@ -43,6 +47,8 @@ describe('createRouter', () => {
|
||||
getRepoBuilds: jest.fn(),
|
||||
getDefinitionBuilds: jest.fn(),
|
||||
getPullRequests: jest.fn(),
|
||||
getBuilds: jest.fn(),
|
||||
getBuildRuns: jest.fn(),
|
||||
} as any;
|
||||
const router = await createRouter({
|
||||
azureDevOpsApi,
|
||||
@@ -138,7 +144,6 @@ describe('createRouter', () => {
|
||||
|
||||
expect(azureDevOpsApi.getBuildList).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
undefined,
|
||||
'af4ae3af-e747-4129-9bbc-d1329f6b0998',
|
||||
40,
|
||||
);
|
||||
@@ -147,32 +152,6 @@ describe('createRouter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /build-definitions/:projectName/:definitionName', () => {
|
||||
it('fetches a list of build definitions', async () => {
|
||||
const inputDefinition: BuildDefinitionReference = {
|
||||
id: 1,
|
||||
name: 'myBuildDefinition',
|
||||
};
|
||||
|
||||
const inputDefinitions: BuildDefinitionReference[] = [inputDefinition];
|
||||
|
||||
azureDevOpsApi.getBuildDefinitions.mockResolvedValueOnce(
|
||||
inputDefinitions,
|
||||
);
|
||||
|
||||
const response = await request(app).get(
|
||||
'/build-definitions/myProject/myBuildDefinition',
|
||||
);
|
||||
|
||||
expect(azureDevOpsApi.getBuildDefinitions).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
'myBuildDefinition',
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(inputDefinitions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /repo-builds/:projectName/:repoName', () => {
|
||||
it('fetches a list of repo builds', async () => {
|
||||
const firstRepoBuild: RepoBuild = {
|
||||
@@ -227,60 +206,6 @@ describe('createRouter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /definition-builds/:projectName/:definitionName', () => {
|
||||
it('fetches a list of repo builds', async () => {
|
||||
const firstRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build 1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.PartiallySucceeded,
|
||||
queueTime: undefined,
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
};
|
||||
|
||||
const secondRepoBuild: RepoBuild = {
|
||||
id: 2,
|
||||
title: 'My Build Definition - Build 2',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=2',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: undefined,
|
||||
source: 'refs/heads/develop (13c988d4)',
|
||||
};
|
||||
|
||||
const thirdRepoBuild: RepoBuild = {
|
||||
id: 3,
|
||||
title: 'My Build Definition - Build 3',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=3',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: undefined,
|
||||
source: 'refs/heads/develop (9bedf678)',
|
||||
};
|
||||
|
||||
const repoBuilds: RepoBuild[] = [
|
||||
firstRepoBuild,
|
||||
secondRepoBuild,
|
||||
thirdRepoBuild,
|
||||
];
|
||||
|
||||
azureDevOpsApi.getDefinitionBuilds.mockResolvedValueOnce(repoBuilds);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/definition-builds/myProject/myDefinition')
|
||||
.query({ top: '30' });
|
||||
|
||||
expect(azureDevOpsApi.getDefinitionBuilds).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
'myDefinition',
|
||||
30,
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(repoBuilds);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /pull-requests/:projectName/:repoName', () => {
|
||||
it('fetches a list of pull requests', async () => {
|
||||
const firstPullRequest: PullRequest = {
|
||||
@@ -343,4 +268,142 @@ describe('createRouter', () => {
|
||||
expect(response.body).toEqual(pullRequests);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /build-definitions/:projectName/:definitionName', () => {
|
||||
it('fetches a list of build definitions', async () => {
|
||||
const inputDefinition: BuildDefinitionReference = {
|
||||
id: 1,
|
||||
name: 'myBuildDefinition',
|
||||
};
|
||||
|
||||
const inputDefinitions: BuildDefinitionReference[] = [inputDefinition];
|
||||
|
||||
azureDevOpsApi.getBuildDefinitions.mockResolvedValueOnce(
|
||||
inputDefinitions,
|
||||
);
|
||||
|
||||
const response = await request(app).get(
|
||||
'/build-definitions/myProject/myBuildDefinition',
|
||||
);
|
||||
|
||||
expect(azureDevOpsApi.getBuildDefinitions).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
'myBuildDefinition',
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(inputDefinitions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /builds/:projectName', () => {
|
||||
describe('GET /builds/:projectName with repoName', () => {
|
||||
it('fetches a list of build runs using repoName', async () => {
|
||||
const firstBuildRun: BuildRun = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build 1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.PartiallySucceeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
};
|
||||
|
||||
const secondBuildRun: BuildRun = {
|
||||
id: 2,
|
||||
title: 'My Build Definition - Build 2',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=2',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (13c988d4)',
|
||||
};
|
||||
|
||||
const thirdBuildRun: BuildRun = {
|
||||
id: 3,
|
||||
title: 'My Build Definition - Build 3',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=3',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (9bedf678)',
|
||||
};
|
||||
|
||||
const buildRuns: BuildRun[] = [
|
||||
firstBuildRun,
|
||||
secondBuildRun,
|
||||
thirdBuildRun,
|
||||
];
|
||||
|
||||
azureDevOpsApi.getBuildRuns.mockResolvedValueOnce(buildRuns);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/builds/myProject')
|
||||
.query({ top: '50', repoName: 'myRepo' });
|
||||
|
||||
expect(azureDevOpsApi.getBuildRuns).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
50,
|
||||
'myRepo',
|
||||
undefined,
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(buildRuns);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /builds/:projectName with definitionName', () => {
|
||||
it('fetches a list of build runs using definitionName', async () => {
|
||||
const firstBuildRun: BuildRun = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build 1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.PartiallySucceeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
};
|
||||
|
||||
const secondBuildRun: BuildRun = {
|
||||
id: 2,
|
||||
title: 'My Build Definition - Build 2',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=2',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (13c988d4)',
|
||||
};
|
||||
|
||||
const thirdBuildRun: BuildRun = {
|
||||
id: 3,
|
||||
title: 'My Build Definition - Build 3',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=3',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (9bedf678)',
|
||||
};
|
||||
|
||||
const buildRuns: BuildRun[] = [
|
||||
firstBuildRun,
|
||||
secondBuildRun,
|
||||
thirdBuildRun,
|
||||
];
|
||||
|
||||
azureDevOpsApi.getBuildRuns.mockResolvedValueOnce(buildRuns);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/builds/myProject')
|
||||
.query({ top: '50', definitionName: 'myDefinition' });
|
||||
|
||||
expect(azureDevOpsApi.getBuildRuns).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
50,
|
||||
undefined,
|
||||
'myDefinition',
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(buildRuns);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -73,25 +73,12 @@ export async function createRouter(
|
||||
const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP;
|
||||
const buildList = await azureDevOpsApi.getBuildList(
|
||||
projectName,
|
||||
undefined,
|
||||
repoId,
|
||||
top,
|
||||
);
|
||||
res.status(200).json(buildList);
|
||||
});
|
||||
|
||||
router.get(
|
||||
'/build-definitions/:projectName/:definitionName',
|
||||
async (req, res) => {
|
||||
const { projectName, definitionName } = req.params;
|
||||
const buildDefinitionList = await azureDevOpsApi.getBuildDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
);
|
||||
res.status(200).json(buildDefinitionList);
|
||||
},
|
||||
);
|
||||
|
||||
router.get('/repo-builds/:projectName/:repoName', async (req, res) => {
|
||||
const { projectName, repoName } = req.params;
|
||||
|
||||
@@ -106,20 +93,6 @@ export async function createRouter(
|
||||
res.status(200).json(gitRepository);
|
||||
});
|
||||
|
||||
router.get(
|
||||
'/definition-builds/:projectName/:definitionName',
|
||||
async (req, res) => {
|
||||
const { projectName, definitionName } = req.params;
|
||||
const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP;
|
||||
const gitRepository = await azureDevOpsApi.getDefinitionBuilds(
|
||||
projectName,
|
||||
definitionName,
|
||||
top,
|
||||
);
|
||||
res.status(200).json(gitRepository);
|
||||
},
|
||||
);
|
||||
|
||||
router.get('/pull-requests/:projectName/:repoName', async (req, res) => {
|
||||
const { projectName, repoName } = req.params;
|
||||
|
||||
@@ -171,6 +144,32 @@ export async function createRouter(
|
||||
res.status(200).json(allTeams);
|
||||
});
|
||||
|
||||
router.get(
|
||||
'/build-definitions/:projectName/:definitionName',
|
||||
async (req, res) => {
|
||||
const { projectName, definitionName } = req.params;
|
||||
const buildDefinitionList = await azureDevOpsApi.getBuildDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
);
|
||||
res.status(200).json(buildDefinitionList);
|
||||
},
|
||||
);
|
||||
|
||||
router.get('/builds/:projectName', async (req, res) => {
|
||||
const { projectName } = req.params;
|
||||
const repoName = req.query.repoName?.toString();
|
||||
const definitionName = req.query.definitionName?.toString();
|
||||
const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP;
|
||||
const builds = await azureDevOpsApi.getBuildRuns(
|
||||
projectName,
|
||||
top,
|
||||
repoName,
|
||||
definitionName,
|
||||
);
|
||||
res.status(200).json(builds);
|
||||
});
|
||||
|
||||
router.use(errorHandler());
|
||||
return router;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user