Added tests for changed hooks

Signed-off-by: Andre Wanlin <awanlin@spotify.com>
This commit is contained in:
Andre Wanlin
2023-10-21 12:14:10 -05:00
parent 0a7c9ede2e
commit 5578328e57
8 changed files with 392 additions and 16 deletions
@@ -0,0 +1,130 @@
/*
* Copyright 2021 The Backstage Authors
*
* 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 React from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import { useGitTags } from './useGitTags';
import { Entity } from '@backstage/catalog-model';
import { GitTag } from '@backstage/plugin-azure-devops-common';
import { TestApiProvider } from '@backstage/test-utils';
import { AzureDevOpsApi, azureDevOpsApiRef } from '../api';
describe('useGitTags', () => {
const azureDevOpsApiMock = {
getGitTags: jest.fn(),
};
const azureDevOpsApi =
azureDevOpsApiMock as Partial<AzureDevOpsApi> as AzureDevOpsApi;
const Wrapper = (props: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[azureDevOpsApiRef, azureDevOpsApi]]}>
{props.children}
</TestApiProvider>
);
it('should provide an array of GitTag', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
annotations: {
'dev.azure.com/project-repo': 'projectName/repoName',
},
},
};
const tags: GitTag[] = [
{
objectId: 'tag-1',
peeledObjectId: 'tag-1',
name: 'tag-1',
createdBy: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
commitLink: 'https://dev.azure.com/org/project/repo/commit-sha-1',
},
{
objectId: 'tag-2',
peeledObjectId: 'tag-2',
name: 'tag-2',
createdBy: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
commitLink: 'https://dev.azure.com/org/project/repo/commit-sha-2',
},
{
objectId: 'tag-3',
peeledObjectId: 'tag-3',
name: 'tag-3',
createdBy: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
commitLink: 'https://dev.azure.com/org/project/repo/commit-sha-3',
},
];
azureDevOpsApiMock.getGitTags.mockResolvedValue({ items: tags });
const { result } = renderHook(() => useGitTags(entity), {
wrapper: Wrapper,
});
expect(result.current.loading).toEqual(true);
await waitFor(() => {
expect(result.current).toEqual({
error: undefined,
items: tags,
loading: false,
});
});
});
it('should return throw when annotation missing', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
},
};
expect(() =>
renderHook(() => useGitTags(entity), {
wrapper: Wrapper,
}),
).toThrow('Value for annotation "dev.azure.com/project" was not found');
});
it('should return throw when annotation invalid', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
annotations: {
'dev.azure.com/project-repo': 'fake',
},
},
};
expect(() =>
renderHook(() => useGitTags(entity), {
wrapper: Wrapper,
}),
).toThrow(
'Invalid value for annotation "dev.azure.com/project-repo"; expected format is: <project-name>/<repo-name>, found: "fake"',
);
});
});
+1 -4
View File
@@ -31,10 +31,7 @@ export function useGitTags(entity: Entity): {
const { project, repo } = getAnnotationValuesFromEntity(entity);
const { value, loading, error } = useAsync(async () => {
if (repo) {
return await api.getGitTags(project, repo);
}
return undefined;
return await api.getGitTags(project, repo as string);
}, [api, project, repo]);
return {
@@ -0,0 +1,129 @@
/*
* Copyright 2021 The Backstage Authors
*
* 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 React from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import { Entity } from '@backstage/catalog-model';
import { PullRequest } from '@backstage/plugin-azure-devops-common';
import { TestApiProvider } from '@backstage/test-utils';
import { AzureDevOpsApi, azureDevOpsApiRef } from '../api';
import { usePullRequests } from './usePullRequests';
describe('usePullRequests', () => {
const azureDevOpsApiMock = {
getPullRequests: jest.fn(),
};
const azureDevOpsApi =
azureDevOpsApiMock as Partial<AzureDevOpsApi> as AzureDevOpsApi;
const Wrapper = (props: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[azureDevOpsApiRef, azureDevOpsApi]]}>
{props.children}
</TestApiProvider>
);
it('should provide an array of PullRequest', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
annotations: {
'dev.azure.com/project-repo': 'projectName/repoName',
},
},
};
const pullRequests: PullRequest[] = [
{
pullRequestId: 1,
repoName: 'repo',
title: 'title-1',
createdBy: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
},
{
pullRequestId: 2,
repoName: 'repo',
title: 'title-2',
createdBy: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
},
{
pullRequestId: 3,
repoName: 'repo',
title: 'title-3',
createdBy: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
},
];
azureDevOpsApiMock.getPullRequests.mockResolvedValue({
items: pullRequests,
});
const { result } = renderHook(() => usePullRequests(entity), {
wrapper: Wrapper,
});
expect(result.current.loading).toEqual(true);
await waitFor(() => {
expect(result.current).toEqual({
error: undefined,
items: pullRequests,
loading: false,
});
});
});
it('should return throw when annotation missing', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
},
};
expect(() =>
renderHook(() => usePullRequests(entity), {
wrapper: Wrapper,
}),
).toThrow('Value for annotation "dev.azure.com/project" was not found');
});
it('should return throw when annotation invalid', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
annotations: {
'dev.azure.com/project-repo': 'fake',
},
},
};
expect(() =>
renderHook(() => usePullRequests(entity), {
wrapper: Wrapper,
}),
).toThrow(
'Invalid value for annotation "dev.azure.com/project-repo"; expected format is: <project-name>/<repo-name>, found: "fake"',
);
});
});
@@ -47,10 +47,7 @@ export function usePullRequests(
const { project, repo } = getAnnotationValuesFromEntity(entity);
const { value, loading, error } = useAsync(async () => {
if (repo) {
return await api.getPullRequests(project, repo, options);
}
return undefined;
return await api.getPullRequests(project, repo as string, options);
}, [api, project, repo, top, status]);
return {
@@ -0,0 +1,126 @@
/*
* Copyright 2021 The Backstage Authors
*
* 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 React from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import { Entity } from '@backstage/catalog-model';
import { RepoBuild } from '@backstage/plugin-azure-devops-common';
import { TestApiProvider } from '@backstage/test-utils';
import { AzureDevOpsApi, azureDevOpsApiRef } from '../api';
import { useRepoBuilds } from './useRepoBuilds';
describe('useRepoBuilds', () => {
const azureDevOpsApiMock = {
getRepoBuilds: jest.fn(),
};
const azureDevOpsApi =
azureDevOpsApiMock as Partial<AzureDevOpsApi> as AzureDevOpsApi;
const Wrapper = (props: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[azureDevOpsApiRef, azureDevOpsApi]]}>
{props.children}
</TestApiProvider>
);
it('should provide an array of RepoBuild', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
annotations: {
'dev.azure.com/project-repo': 'projectName/repoName',
},
},
};
const repoBuilds: RepoBuild[] = [
{
id: 1,
title: 'title-1',
source: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
},
{
id: 2,
title: 'title-2',
source: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
},
{
id: 3,
title: 'title-3',
source: 'awanlin',
link: 'https://dev.azure.com/org/project/repo',
},
];
azureDevOpsApiMock.getRepoBuilds.mockResolvedValue({
items: repoBuilds,
});
const { result } = renderHook(() => useRepoBuilds(entity), {
wrapper: Wrapper,
});
expect(result.current.loading).toEqual(true);
await waitFor(() => {
expect(result.current).toEqual({
error: undefined,
items: repoBuilds,
loading: false,
});
});
});
it('should return throw when annotation missing', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
},
};
expect(() =>
renderHook(() => useRepoBuilds(entity), {
wrapper: Wrapper,
}),
).toThrow('Value for annotation "dev.azure.com/project" was not found');
});
it('should return throw when annotation invalid', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'project-repo',
annotations: {
'dev.azure.com/project-repo': 'fake',
},
},
};
expect(() =>
renderHook(() => useRepoBuilds(entity), {
wrapper: Wrapper,
}),
).toThrow(
'Invalid value for annotation "dev.azure.com/project-repo"; expected format is: <project-name>/<repo-name>, found: "fake"',
);
});
});
@@ -43,10 +43,7 @@ export function useRepoBuilds(
const { project, repo } = getAnnotationValuesFromEntity(entity);
const { value, loading, error } = useAsync(async () => {
if (repo) {
return await api.getRepoBuilds(project, repo, options);
}
return undefined;
return await api.getRepoBuilds(project, repo as string, options);
}, [api, project, repo, entity]);
return {
@@ -157,7 +157,7 @@ describe('getAnnotationValuesFromEntity', () => {
};
expect(test).toThrow(
'Value for annotation dev.azure.com/build-definition was not found',
'Value for annotation "dev.azure.com/build-definition" was not found',
);
});
});
@@ -180,7 +180,7 @@ describe('getAnnotationValuesFromEntity', () => {
};
expect(test).toThrow(
'Value for annotation dev.azure.com/project was not found',
'Value for annotation "dev.azure.com/project" was not found',
);
});
});
@@ -46,7 +46,7 @@ export function getAnnotationValuesFromEntity(entity: Entity): {
entity.metadata.annotations?.[AZURE_DEVOPS_PROJECT_ANNOTATION];
if (!project) {
throw new Error(
`Value for annotation ${AZURE_DEVOPS_PROJECT_ANNOTATION} was not found`,
`Value for annotation "${AZURE_DEVOPS_PROJECT_ANNOTATION}" was not found`,
);
}
@@ -54,7 +54,7 @@ export function getAnnotationValuesFromEntity(entity: Entity): {
entity.metadata.annotations?.[AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION];
if (!definition) {
throw new Error(
`Value for annotation ${AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION} was not found`,
`Value for annotation "${AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION}" was not found`,
);
}
return { project, definition, host, org };