diff --git a/plugins/git-release-manager/src/api/GitReleaseApiClient.ts b/plugins/git-release-manager/src/api/GitReleaseApiClient.ts index 33a89fe36e..49c0d056ed 100644 --- a/plugins/git-release-manager/src/api/GitReleaseApiClient.ts +++ b/plugins/git-release-manager/src/api/GitReleaseApiClient.ts @@ -205,7 +205,7 @@ export class GitReleaseApiClient implements GitReleaseApi { getCommit: GitReleaseApi['getCommit'] = async ({ owner, repo, ref }) => { const { octokit } = await this.getOctokit(); - const { data: latestCommit } = await octokit.repos.getCommit({ + const { data: commit } = await octokit.repos.getCommit({ owner, repo, ref, @@ -214,12 +214,12 @@ export class GitReleaseApiClient implements GitReleaseApi { return { commit: { - sha: latestCommit.sha, - htmlUrl: latestCommit.html_url, + sha: commit.sha, + htmlUrl: commit.html_url, commit: { - message: latestCommit.commit.message, + message: commit.commit.message, }, - createdAt: latestCommit.commit.committer?.date, + createdAt: commit.commit.committer?.date, }, }; }; @@ -789,9 +789,7 @@ export type GetLatestReleaseResult = UnboxReturnedPromise< export type GetRepositoryResult = UnboxReturnedPromise< GitReleaseApi['getRepository'] >; -export type GetLatestCommitResult = UnboxReturnedPromise< - GitReleaseApi['getCommit'] ->; +export type GetCommitResult = UnboxReturnedPromise; export type GetBranchResult = UnboxReturnedPromise; export type CreateRefResult = UnboxReturnedPromise; export type GetComparisonResult = UnboxReturnedPromise< diff --git a/plugins/git-release-manager/src/features/Stats/helpers/getTagDates.test.ts b/plugins/git-release-manager/src/features/Stats/helpers/getTagDates.test.ts new file mode 100644 index 0000000000..e02aac9551 --- /dev/null +++ b/plugins/git-release-manager/src/features/Stats/helpers/getTagDates.test.ts @@ -0,0 +1,165 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createMockCommit, + createMockTag, + mockApiClient, + mockSemverProject, +} from '../../../test-helpers/test-helpers'; +import { getTagDates } from './getTagDates'; + +describe('getTagDates', () => { + beforeEach(jest.clearAllMocks); + + it('should get tag dates when startTag & endTag both are of type tag', async () => { + (mockApiClient.getTag as jest.Mock) + .mockResolvedValueOnce(createMockTag({ date: 'TAG-START' })) + .mockResolvedValueOnce(createMockTag({ date: 'TAG-END' })); + + const result = await getTagDates({ + pluginApiClient: mockApiClient, + project: mockSemverProject, + startTag: { + tagSha: 'sha-start', + tagType: 'tag', + }, + endTag: { + tagSha: 'sha-end', + tagType: 'tag', + }, + }); + + expect(result).toMatchInlineSnapshot(` + Object { + "endDate": "TAG-END", + "startDate": "TAG-START", + } + `); + }); + + it('should get commit createdAt when startTag & endTag both are of type commit', async () => { + (mockApiClient.getCommit as jest.Mock) + .mockResolvedValueOnce(createMockCommit({ createdAt: 'COMMIT_START' })) + .mockResolvedValueOnce(createMockCommit({ createdAt: 'COMMIT_END' })); + + const result = await getTagDates({ + pluginApiClient: mockApiClient, + project: mockSemverProject, + startTag: { + tagSha: 'sha-start', + tagType: 'commit', + }, + endTag: { + tagSha: 'sha-end', + tagType: 'commit', + }, + }); + + expect(result).toMatchInlineSnapshot(` + Object { + "endDate": "COMMIT_END", + "startDate": "COMMIT_START", + } + `); + }); + + it('should get commit createdAt when startTag is of type tag but endTag is of type commit', async () => { + (mockApiClient.getTag as jest.Mock).mockResolvedValueOnce( + createMockTag({ objectSha: 'OBJECT_SHA_START' }), + ); + (mockApiClient.getCommit as jest.Mock).mockResolvedValueOnce( + createMockCommit({ createdAt: 'COMMIT_START' }), + ); + + (mockApiClient.getCommit as jest.Mock).mockResolvedValueOnce( + createMockCommit({ createdAt: 'COMMIT_END' }), + ); + + const result = await getTagDates({ + pluginApiClient: mockApiClient, + project: mockSemverProject, + startTag: { + tagSha: 'sha-start', + tagType: 'tag', + }, + endTag: { + tagSha: 'sha-end', + tagType: 'commit', + }, + }); + + const { owner, repo } = mockSemverProject; + expect(mockApiClient.getTag).toHaveBeenCalledWith({ + owner, + repo, + tagSha: 'sha-start', + }); + expect((mockApiClient.getCommit as jest.Mock).mock.calls).toEqual([ + [{ owner, ref: 'sha-end', repo }], + [{ owner, ref: 'OBJECT_SHA_START', repo }], + ]); + expect(result).toMatchInlineSnapshot(` + Object { + "endDate": "COMMIT_START", + "startDate": "COMMIT_END", + } + `); + }); + + it('should get commit createdAt when endTag is of type tag but startTag is of type commit', async () => { + (mockApiClient.getCommit as jest.Mock).mockResolvedValueOnce( + createMockCommit({ createdAt: 'COMMIT_START' }), + ); + + (mockApiClient.getTag as jest.Mock).mockResolvedValueOnce( + createMockTag({ objectSha: 'OBJECT_SHA_END' }), + ); + (mockApiClient.getCommit as jest.Mock).mockResolvedValueOnce( + createMockCommit({ createdAt: 'COMMIT_END' }), + ); + + const result = await getTagDates({ + pluginApiClient: mockApiClient, + project: mockSemverProject, + startTag: { + tagSha: 'sha-start', + tagType: 'commit', + }, + endTag: { + tagSha: 'sha-end', + tagType: 'tag', + }, + }); + + const { owner, repo } = mockSemverProject; + expect(mockApiClient.getTag).toHaveBeenCalledWith({ + owner, + repo, + tagSha: 'sha-end', + }); + expect((mockApiClient.getCommit as jest.Mock).mock.calls).toEqual([ + [{ owner, ref: 'sha-start', repo }], + [{ owner, ref: 'OBJECT_SHA_END', repo }], + ]); + expect(result).toMatchInlineSnapshot(` + Object { + "endDate": "COMMIT_END", + "startDate": "COMMIT_START", + } + `); + }); +}); diff --git a/plugins/git-release-manager/src/test-helpers/test-helpers.ts b/plugins/git-release-manager/src/test-helpers/test-helpers.ts index 4fcbee65a1..c39f0a49b0 100644 --- a/plugins/git-release-manager/src/test-helpers/test-helpers.ts +++ b/plugins/git-release-manager/src/test-helpers/test-helpers.ts @@ -18,12 +18,15 @@ import { GetBranchResult, GetLatestReleaseResult, GetRecentCommitsResultSingle, + GetTagResult, GitReleaseApi, + GetCommitResult, } from '../api/GitReleaseApiClient'; import { CalverTagParts } from '../helpers/tagParts/getCalverTagParts'; import { Project } from '../contexts/ProjectContext'; import { getReleaseCandidateGitInfo } from '../helpers/getReleaseCandidateGitInfo'; +const mockUsername = 'mock_username'; const mockEmail = 'mock_email'; const mockOwner = 'mock_owner'; const mockRepo = 'mock_repo'; @@ -40,8 +43,34 @@ const MOCK_RELEASE_BRANCH_NAME_SEMVER = `rc/${A_SEMVER_VERSION}`; const MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER = `rc-${A_SEMVER_VERSION}`; const MOCK_RELEASE_VERSION_TAG_NAME_SEMVER = `version-${A_SEMVER_VERSION}`; +export const createMockTag = ( + overrides: Partial, +): GetTagResult => ({ + tag: { + date: '2000-01-01T10:00:00.000Z', + objectSha: 'mock_tag_object_sha', + userEmail: mockEmail, + username: mockUsername, + ...overrides, + }, +}); + +export const createMockCommit = ( + overrides: Partial, +): GetCommitResult => ({ + commit: { + commit: { + message: 'mock_commit_commit_message', + }, + htmlUrl: 'mock_commit_html_url', + sha: 'mock_commit_sha', + createdAt: '2000-01-01T10:00:00.000Z', + ...overrides, + }, +}); + export const mockUser = { - username: mockOwner, + username: mockUsername, email: mockEmail, };