feat: use refactored hooks in components and component tests for basic rendering of the plugin
Signed-off-by: Kamil Wolny <mrwolny@gmail.com>
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2022 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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import {
|
||||
EntityProvider,
|
||||
catalogApiRef,
|
||||
CatalogApi,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
|
||||
import { generateTestIssue } from '../../utils';
|
||||
import { GitHubIssuesApi, gitHubIssuesApiRef } from '../../api';
|
||||
|
||||
import { GitHubIssues } from './GitHubIssues';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
|
||||
jest
|
||||
.useFakeTimers()
|
||||
.setSystemTime(new Date('2020-04-20T08:15:47.614Z').getTime());
|
||||
|
||||
const entityComponent = {
|
||||
metadata: {
|
||||
annotations: {
|
||||
'github.com/project-slug': 'backstage/backstage',
|
||||
},
|
||||
name: 'backstage',
|
||||
},
|
||||
apiVersion: 'backstage.io/v1alpha1',
|
||||
kind: 'Component',
|
||||
} as unknown as Entity;
|
||||
|
||||
const mockCatalogApi = {
|
||||
getEntities: () => ({}),
|
||||
} as CatalogApi;
|
||||
|
||||
describe('GitHubIssues', () => {
|
||||
it('should render correctly when there are no issues in GitHub', async () => {
|
||||
const mockApi = {
|
||||
fetchIssuesByRepoFromGitHub: async () => ({
|
||||
backstage: {
|
||||
issues: {
|
||||
totalCount: 0,
|
||||
edges: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
} as GitHubIssuesApi;
|
||||
|
||||
const apis = [
|
||||
[gitHubIssuesApiRef, mockApi],
|
||||
[catalogApiRef, mockCatalogApi],
|
||||
] as const;
|
||||
|
||||
const { getByTestId } = await renderInTestApp(
|
||||
<TestApiProvider apis={apis}>
|
||||
<EntityProvider entity={entityComponent}>
|
||||
<GitHubIssues />
|
||||
</EntityProvider>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
expect(getByTestId('no-issues-msg')).toHaveTextContent(
|
||||
'Hurray! No Issues 🚀',
|
||||
);
|
||||
});
|
||||
|
||||
it('should render correctly', async () => {
|
||||
const testIssue = generateTestIssue({
|
||||
createdAt: '2020-04-19T10:15:47.614Z',
|
||||
updatedAt: '2020-04-20T00:15:47.614Z',
|
||||
});
|
||||
|
||||
const mockApi = {
|
||||
fetchIssuesByRepoFromGitHub: async () => ({
|
||||
backstage: {
|
||||
issues: {
|
||||
totalCount: 1,
|
||||
edges: [testIssue],
|
||||
},
|
||||
},
|
||||
}),
|
||||
} as GitHubIssuesApi;
|
||||
const apis = [
|
||||
[gitHubIssuesApiRef, mockApi],
|
||||
[catalogApiRef, mockCatalogApi],
|
||||
] as const;
|
||||
|
||||
const { getByText, getByTestId } = await renderInTestApp(
|
||||
<TestApiProvider apis={apis}>
|
||||
<EntityProvider entity={entityComponent}>
|
||||
<GitHubIssues />
|
||||
</EntityProvider>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
getByText('All repositories (1 Issue)');
|
||||
|
||||
expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent(
|
||||
testIssue.node.title,
|
||||
);
|
||||
|
||||
expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent(
|
||||
testIssue.node.repository.nameWithOwner,
|
||||
);
|
||||
|
||||
expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent(
|
||||
`Created at: 22 hours ago by ${testIssue.node.author.login}`,
|
||||
);
|
||||
|
||||
expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent(
|
||||
`Last update at: 8 hours ago`,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -20,12 +20,9 @@ import { InfoCard, Progress } from '@backstage/core-components';
|
||||
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||
|
||||
import { useEntityGitHubRepositories } from '../../hooks/useEntityGitHubRepositories';
|
||||
import {
|
||||
RepoIssues,
|
||||
useGetIssuesByRepoFromGitHub,
|
||||
} from '../../hooks/useGetIssuesByRepoFromGitHub';
|
||||
import { useGetIssuesByRepoFromGitHub } from '../../hooks/useGetIssuesByRepoFromGitHub';
|
||||
|
||||
import { IssueList } from './IssuesList';
|
||||
import { IssuesList } from './IssuesList';
|
||||
import { NoRepositoriesInfo } from './NoRepositoriesInfo';
|
||||
|
||||
/**
|
||||
@@ -39,29 +36,12 @@ export type GitHubIssuesProps = {
|
||||
export const GitHubIssues = (props: GitHubIssuesProps) => {
|
||||
const { itemsPerPage = 10, itemsPerRepo = 40 } = props;
|
||||
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
|
||||
const [issuesByRepository, setIssuesByRepository] =
|
||||
React.useState<Record<string, RepoIssues>>();
|
||||
|
||||
const { repositories } = useEntityGitHubRepositories();
|
||||
const getIssues = useGetIssuesByRepoFromGitHub();
|
||||
|
||||
const fetchGitHubIssues = React.useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
const issuesByRepo = await getIssues(repositories, itemsPerRepo);
|
||||
|
||||
setIssuesByRepository(issuesByRepo);
|
||||
setIsLoading(false);
|
||||
}, [itemsPerRepo, getIssues, repositories]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (repositories.length) {
|
||||
fetchGitHubIssues();
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [repositories.length, fetchGitHubIssues]);
|
||||
const {
|
||||
isLoading,
|
||||
gitHubIssuesByRepo: issuesByRepository,
|
||||
retry,
|
||||
} = useGetIssuesByRepoFromGitHub(repositories, itemsPerRepo);
|
||||
|
||||
if (!repositories.length) {
|
||||
return <NoRepositoriesInfo />;
|
||||
@@ -72,7 +52,7 @@ export const GitHubIssues = (props: GitHubIssuesProps) => {
|
||||
title={
|
||||
<Box display="flex" justifyContent="flex-start" alignItems="center">
|
||||
<Typography variant="h5">Open GitHub Issues</Typography>
|
||||
<IconButton color="secondary" onClick={fetchGitHubIssues}>
|
||||
<IconButton color="secondary" onClick={retry}>
|
||||
<RefreshIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
@@ -80,7 +60,7 @@ export const GitHubIssues = (props: GitHubIssuesProps) => {
|
||||
>
|
||||
{isLoading && <Progress />}
|
||||
|
||||
<IssueList
|
||||
<IssuesList
|
||||
issuesByRepository={issuesByRepository}
|
||||
itemsPerPage={itemsPerPage}
|
||||
/>
|
||||
|
||||
@@ -59,7 +59,7 @@ export const IssueCard = (props: IssueCardProps) => {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Box marginBottom={1}>
|
||||
<Box marginBottom={1} data-testid={`issue-${url}`}>
|
||||
<Paper variant="outlined">
|
||||
<CardActionArea href={url} target="_blank">
|
||||
<Box padding={1}>
|
||||
|
||||
@@ -19,14 +19,14 @@ import { Box } from '@material-ui/core';
|
||||
import { Pagination } from '@material-ui/lab';
|
||||
|
||||
import { IssueCard } from '../IssueCard';
|
||||
import { RepoIssues } from '../../../hooks/useGetIssuesByRepoFromGitHub';
|
||||
import { IssuesByRepo } from '../../../api';
|
||||
import { RepositoryFilters } from './Filters';
|
||||
|
||||
export type PluginMode = 'page' | 'card';
|
||||
|
||||
export type IssueListProps = {
|
||||
itemsPerPage?: number;
|
||||
issuesByRepository?: Record<string, RepoIssues>;
|
||||
issuesByRepository?: IssuesByRepo;
|
||||
};
|
||||
|
||||
const getIssuesCountForFilterLabel = (
|
||||
@@ -37,7 +37,7 @@ const getIssuesCountForFilterLabel = (
|
||||
issuesAvailable < totalIssues ? '*' : ''
|
||||
}`;
|
||||
|
||||
export const IssueList = ({
|
||||
export const IssuesList = ({
|
||||
itemsPerPage = 10,
|
||||
issuesByRepository,
|
||||
}: IssueListProps) => {
|
||||
@@ -140,6 +140,7 @@ export const IssueList = ({
|
||||
index,
|
||||
) => (
|
||||
<IssueCard
|
||||
key={url}
|
||||
even={Boolean(index % 2)}
|
||||
title={title}
|
||||
createdAt={createdAt}
|
||||
@@ -154,7 +155,7 @@ export const IssueList = ({
|
||||
),
|
||||
)
|
||||
) : (
|
||||
<h1>Hurray! No Issues 🚀</h1>
|
||||
<h1 data-testid="no-issues-msg">Hurray! No Issues 🚀</h1>
|
||||
)}
|
||||
{issues.length / itemsPerPage > 1 ? (
|
||||
<Pagination
|
||||
|
||||
Reference in New Issue
Block a user