Refactor Readme into hook
Signed-off-by: Andre Wanlin <awanlin@spotify.com>
This commit is contained in:
@@ -23,11 +23,9 @@ import {
|
||||
ErrorPanel,
|
||||
} from '@backstage/core-components';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import React from 'react';
|
||||
import { azureDevOpsApiRef } from '../../api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { getAnnotationValuesFromEntity } from '../../utils';
|
||||
|
||||
import { useReadme } from '../../hooks';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
readMe: {
|
||||
@@ -85,16 +83,9 @@ const ReadmeCardError = ({ error }: ErrorProps) => {
|
||||
|
||||
export const ReadmeCard = (props: Props) => {
|
||||
const classes = useStyles();
|
||||
const api = useApi(azureDevOpsApiRef);
|
||||
const { entity } = useEntity();
|
||||
const { project, repo } = getAnnotationValuesFromEntity(entity);
|
||||
|
||||
const { loading, error, value } = useAsync(async () => {
|
||||
if (repo) {
|
||||
return await api.getReadme({ project, repo });
|
||||
}
|
||||
return undefined;
|
||||
}, [api, project, repo, entity]);
|
||||
const { loading, error, item: value } = useReadme(entity);
|
||||
|
||||
if (loading) {
|
||||
return <Progress />;
|
||||
|
||||
@@ -20,3 +20,4 @@ export * from './usePullRequests';
|
||||
export * from './useRepoBuilds';
|
||||
export * from './useUserEmail';
|
||||
export * from './useUserTeamIds';
|
||||
export * from './useReadme';
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 { Readme } from '@backstage/plugin-azure-devops-common';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { AzureDevOpsApi, azureDevOpsApiRef } from '../api';
|
||||
import { useReadme } from './useReadme';
|
||||
|
||||
describe('useReadme', () => {
|
||||
const azureDevOpsApiMock = {
|
||||
getReadme: 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 a Readme', 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 readme: Readme = {
|
||||
url: 'https://dev.azure.com/org/project/repo',
|
||||
content: 'This is some fake README content',
|
||||
};
|
||||
azureDevOpsApiMock.getReadme.mockResolvedValue({
|
||||
item: readme,
|
||||
});
|
||||
const { result } = renderHook(() => useReadme(entity), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
|
||||
expect(result.current.loading).toEqual(true);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.item).toEqual({
|
||||
item: readme,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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(() => useReadme(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(() => useReadme(entity), {
|
||||
wrapper: Wrapper,
|
||||
}),
|
||||
).toThrow(
|
||||
'Invalid value for annotation "dev.azure.com/project-repo"; expected format is: <project-name>/<repo-name>, found: "fake"',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 { Readme } from '@backstage/plugin-azure-devops-common';
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { azureDevOpsApiRef } from '../api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { getAnnotationValuesFromEntity } from '../utils';
|
||||
|
||||
export function useReadme(entity: Entity): {
|
||||
item?: Readme;
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
} {
|
||||
const api = useApi(azureDevOpsApiRef);
|
||||
const { project, repo } = getAnnotationValuesFromEntity(entity);
|
||||
|
||||
const { value, loading, error } = useAsync(async () => {
|
||||
return await api.getReadme({ project, repo: repo as string });
|
||||
}, [api, project, repo]);
|
||||
|
||||
return {
|
||||
item: value,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user