From 1da2c481d20cafd775fffe361aed34e3179bf389 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 26 Mar 2021 11:30:14 +0000 Subject: [PATCH] useEntity and more tests Signed-off-by: Andrew Johnson --- plugins/github-deployments/README.md | 10 +- plugins/github-deployments/package.json | 2 +- plugins/github-deployments/src/api/index.ts | 2 +- .../components/GithubDeploymentsCard.test.tsx | 35 +++++- .../src/components/GithubDeploymentsCard.tsx | 44 +++++--- .../GithubDeploymentsTable.tsx | 3 +- plugins/github-deployments/src/mocks/mocks.ts | 32 +++--- yarn.lock | 103 ++++++++++++++---- 8 files changed, 166 insertions(+), 65 deletions(-) diff --git a/plugins/github-deployments/README.md b/plugins/github-deployments/README.md index 2c4a4cb49a..c2c56b02e5 100644 --- a/plugins/github-deployments/README.md +++ b/plugins/github-deployments/README.md @@ -1,12 +1,12 @@ -# Github Deployments Plugin +# GitHub Deployments Plugin -The Github Deployments Plugin displays recent deployments from Github. +The GitHub Deployments Plugin displays recent deployments from GitHub. ![github-deployments-card](./docs/github-deployments-card.png) ## Getting Started -1. Install the Github Deployments Plugin +1. Install the GitHub Deployments Plugin ```bash # packages/app @@ -14,7 +14,7 @@ The Github Deployments Plugin displays recent deployments from Github. yarn add @backstage/plugin-github-deployments ``` -2. Add proxy and auth token for Github +2. Add proxy and auth token for GitHub ```yaml # app-config.yaml @@ -57,7 +57,7 @@ const OverviewContent = ({ entity }: { entity: Entity }) => ( ); ``` -5. Add the github.com/project-slug annotation to your catalog-info.yaml file: +5. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file: ```yaml apiVersion: backstage.io/v1alpha1 diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 99e171bb8a..d83b2c8abd 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -22,13 +22,13 @@ "dependencies": { "@backstage/catalog-model": "^0.7.4", "@backstage/core": "^0.7.2", + "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/theme": "^0.2.4", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", "@octokit/graphql": "^4.6.1", "moment": "^2.29.1", - "nock": "^13.0.11", "react": "^16.13.1", "react-dom": "^16.13.1", "react-use": "^15.3.3" diff --git a/plugins/github-deployments/src/api/index.ts b/plugins/github-deployments/src/api/index.ts index 15ba3e542c..4198776b57 100644 --- a/plugins/github-deployments/src/api/index.ts +++ b/plugins/github-deployments/src/api/index.ts @@ -36,7 +36,7 @@ export interface GithubDeploymentsApi { export const githubDeploymentsApiRef = createApiRef({ id: 'plugin.github-deployments.service', - description: 'Used by the Github Deployments plugin to make requests', + description: 'Used by the GitHub Deployments plugin to make requests', }); export type Options = { diff --git a/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx index 2dc1b57ad2..e933592355 100644 --- a/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx +++ b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx @@ -30,7 +30,14 @@ import { GithubDeploymentsApiClient, githubDeploymentsApiRef } from '../api'; import { githubDeploymentsPlugin } from '../plugin'; import { GithubDeploymentsCard } from './GithubDeploymentsCard'; -import { entityStub, responseStub } from '../mocks/mocks'; +import { entityStub, noDataResponseStub, responseStub } from '../mocks/mocks'; +import { wrapInTestApp } from '@backstage/test-utils'; + +jest.mock('@backstage/plugin-catalog-react', () => ({ + useEntity: () => { + return entityStub; + }, +})); const discoveryApi = UrlPatternDiscovery.compile('http://exampleapi.com'); const errorApiMock = { post: jest.fn(), error$: jest.fn() }; @@ -62,9 +69,11 @@ describe('github-deployments', () => { worker.use(rest.post('*', (_, res, ctx) => res(ctx.json(responseStub)))); const rendered = render( - - - , + wrapInTestApp( + + + , + ), ); expect(await rendered.findByText('active')).toBeInTheDocument(); @@ -81,5 +90,23 @@ describe('github-deployments', () => { 'https://exampleapi.com/543212345', ); }); + + it('should display empty state when no data', async () => { + worker.use( + rest.post('*', (_, res, ctx) => res(ctx.json(noDataResponseStub))), + ); + + const rendered = render( + wrapInTestApp( + + + , + ), + ); + + expect( + await rendered.findByText('No GitHub deployments available.'), + ).toBeInTheDocument(); + }); }); }); diff --git a/plugins/github-deployments/src/components/GithubDeploymentsCard.tsx b/plugins/github-deployments/src/components/GithubDeploymentsCard.tsx index 5f6e072bfc..7425370fe7 100644 --- a/plugins/github-deployments/src/components/GithubDeploymentsCard.tsx +++ b/plugins/github-deployments/src/components/GithubDeploymentsCard.tsx @@ -16,10 +16,16 @@ import React from 'react'; import { LinearProgress } from '@material-ui/core'; import { Entity } from '@backstage/catalog-model'; -import { InfoCard, MissingAnnotationEmptyState, useApi } from '@backstage/core'; +import { + EmptyState, + InfoCard, + MissingAnnotationEmptyState, + useApi, +} from '@backstage/core'; import { useAsync } from 'react-use'; import { githubDeploymentsApiRef } from '../api'; import GithubDeploymentsTable from './GithubDeploymentsTable/GithubDeploymentsTable'; +import { useEntity } from '@backstage/plugin-catalog-react'; export const GITHUB_PROJECT_SLUG_ANNOTATION = 'github.com/project-slug'; @@ -27,16 +33,14 @@ export const isGithubDeploymentsAvailable = (entity: Entity) => Boolean(entity?.metadata.annotations?.[GITHUB_PROJECT_SLUG_ANNOTATION]); const GithubDeploymentsComponent = ({ - entity, + projectSlug, last, }: { - entity: Entity; + projectSlug: string; last: number; }) => { const api = useApi(githubDeploymentsApiRef); - const annotation = - entity.metadata.annotations?.[GITHUB_PROJECT_SLUG_ANNOTATION] ?? ''; - const [owner, repo] = annotation.split('/'); + const [owner, repo] = projectSlug.split('/'); const { loading, value, error } = useAsync( async () => await api.listDeployments({ owner, repo, last }), @@ -44,32 +48,38 @@ const GithubDeploymentsComponent = ({ if (loading) { return ( - + ); } if (error) { return ( - - Error occurred while fetching data. + + Error occured while fetching Data ); } + if (!value || value.length === 0) { + return ( + + ); + } return ; }; -export const GithubDeploymentsCard = ({ - entity, - last, -}: { - entity: Entity; - last?: number; -}) => { +export const GithubDeploymentsCard = ({ last }: { last?: number }) => { + const { entity } = useEntity(); + return !isGithubDeploymentsAvailable(entity) ? ( ) : ( - + ); }; diff --git a/plugins/github-deployments/src/components/GithubDeploymentsTable/GithubDeploymentsTable.tsx b/plugins/github-deployments/src/components/GithubDeploymentsTable/GithubDeploymentsTable.tsx index 1d57fc6ea6..a7b1c5bf9e 100644 --- a/plugins/github-deployments/src/components/GithubDeploymentsTable/GithubDeploymentsTable.tsx +++ b/plugins/github-deployments/src/components/GithubDeploymentsTable/GithubDeploymentsTable.tsx @@ -53,7 +53,6 @@ const columns: TableColumn[] = [ }, { title: 'Status', - field: 'environment', render: (row: any): React.ReactNode => , }, { @@ -81,7 +80,7 @@ const GithubDeploymentsTable = ({ ); diff --git a/plugins/github-deployments/src/mocks/mocks.ts b/plugins/github-deployments/src/mocks/mocks.ts index 35c87a1f6b..6547c8ef4a 100644 --- a/plugins/github-deployments/src/mocks/mocks.ts +++ b/plugins/github-deployments/src/mocks/mocks.ts @@ -14,23 +14,25 @@ * limitations under the License. */ export const entityStub = { - metadata: { - namespace: 'default', - annotations: { - 'github.com/project-slug': 'org/repo', + entity: { + metadata: { + namespace: 'default', + annotations: { + 'github.com/project-slug': 'org/repo', + }, + name: 'sample-service', + description: 'Sample service', + uid: 'g0h33dd9-56h7-835b-b63v-7x5da3j64851', + generation: 1, }, - name: 'sample-service', - description: 'Sample service', - uid: 'g0h33dd9-56h7-835b-b63v-7x5da3j64851', - generation: 1, + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + spec: { + type: 'service', + lifecycle: 'experimental', + }, + relations: [], }, - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'experimental', - }, - relations: [], }; export const responseStub = { diff --git a/yarn.lock b/yarn.lock index 9c608c113d..94b4d959f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1846,6 +1846,23 @@ uuid "^8.0.0" yup "^0.29.3" +"@backstage/core-api@^0.2.15": + version "0.2.15" + resolved "https://registry.npmjs.org/@backstage/core-api/-/core-api-0.2.15.tgz#24c3e4b1fe0bdee36de26c50b8757f41bb266109" + integrity sha512-OQTmvCGM3hkaLV0+JPF85dZk/X1SXoIFkXZi9pO/DzBPZ1Psuptia9xNXrhnEeYJaCazlCnOCTXS/kdoT1zBVg== + dependencies: + "@backstage/config" "^0.1.4" + "@backstage/theme" "^0.2.5" + "@material-ui/core" "^4.11.0" + "@material-ui/icons" "^4.9.1" + "@types/prop-types" "^15.7.3" + "@types/react" "^16.9" + prop-types "^15.7.2" + react "^16.12.0" + react-router-dom "6.0.0-beta.0" + react-use "^15.3.3" + zen-observable "^0.8.15" + "@backstage/core@^0.3.0": version "0.7.3" dependencies: @@ -1972,6 +1989,65 @@ remark-gfm "^1.0.0" zen-observable "^0.8.15" +"@backstage/core@^0.7.3": + version "0.7.3" + resolved "https://registry.npmjs.org/@backstage/core/-/core-0.7.3.tgz#a55f094f0aceab4102ea08a75832c2ec5a70e226" + integrity sha512-uKTCYYAYVtmdOiJrNKe00N0AKeEhxZ+y3qQVY+H96WN9QDql/56XTmoiyPjDU7wK4nDj+yGV4j+xM5uxSXaOCg== + dependencies: + "@backstage/config" "^0.1.4" + "@backstage/core-api" "^0.2.15" + "@backstage/errors" "^0.1.1" + "@backstage/theme" "^0.2.5" + "@material-ui/core" "^4.11.0" + "@material-ui/icons" "^4.9.1" + "@material-ui/lab" "4.0.0-alpha.45" + "@testing-library/react-hooks" "^3.4.2" + "@types/dagre" "^0.7.44" + "@types/prop-types" "^15.7.3" + "@types/react" "^16.9" + "@types/react-sparklines" "^1.7.0" + "@types/react-text-truncate" "^0.14.0" + classnames "^2.2.6" + clsx "^1.1.0" + d3-selection "^2.0.0" + d3-shape "^2.0.0" + d3-zoom "^2.0.0" + dagre "^0.8.5" + immer "^8.0.1" + lodash "^4.17.15" + material-table "^1.69.1" + prop-types "^15.7.2" + qs "^6.9.4" + rc-progress "^3.0.0" + react "^16.12.0" + react-dom "^16.12.0" + react-helmet "6.1.0" + react-hook-form "^6.6.0" + react-markdown "^5.0.2" + react-router "6.0.0-beta.0" + react-router-dom "6.0.0-beta.0" + react-sparklines "^1.7.0" + react-syntax-highlighter "^15.4.3" + react-text-truncate "^0.16.0" + react-use "^15.3.3" + remark-gfm "^1.0.0" + zen-observable "^0.8.15" + +"@backstage/plugin-catalog-react@^0.1.3": + version "0.1.3" + resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.1.3.tgz#e4cc6c40616976737893cc91d7e373b9397618d1" + integrity sha512-nNIz+tc72UtwB66L++xA9drv5VV0SxMPh0BNLOFAHAllcR2RMQyvWpDq4uBupUXx/lr6bzihngkW9Jqr4rfz/Q== + dependencies: + "@backstage/catalog-client" "^0.3.8" + "@backstage/catalog-model" "^0.7.3" + "@backstage/core" "^0.7.3" + "@material-ui/core" "^4.11.0" + "@types/react" "^16.9" + react "^16.13.1" + react-router "6.0.0-beta.0" + react-router-dom "6.0.0-beta.0" + react-use "^15.3.3" + "@backstage/plugin-catalog@^0.2.1": version "0.5.1" dependencies: @@ -2020,6 +2096,13 @@ react-use "^15.3.3" swr "^0.3.0" +"@backstage/theme@^0.2.5": + version "0.2.5" + resolved "https://registry.npmjs.org/@backstage/theme/-/theme-0.2.5.tgz#657e2ceaaede1b4dbe8abeafa6e168671a27b6da" + integrity sha512-GT7Ok9QSiZWXkxka+vcpweMrOg1lgDkRRjh7aSU97Mcoiq77szdO45o0hZtQChz8qay60vCRlu57ADvUn4QxZw== + dependencies: + "@material-ui/core" "^4.11.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -17949,11 +18032,6 @@ lodash.once@^4.0.0, lodash.once@^4.1.1: resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash.set@^4.3.2: - version "4.3.2" - resolved "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" - integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -19292,16 +19370,6 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -nock@^13.0.11: - version "13.0.11" - resolved "https://registry.npmjs.org/nock/-/nock-13.0.11.tgz#ba733252e720897ca50033205c39db0c7470f331" - integrity sha512-sKZltNkkWblkqqPAsjYW0bm3s9DcHRPiMOyKO/PkfJ+ANHZ2+LA2PLe22r4lLrKgXaiSaDQwW3qGsJFtIpQIeQ== - dependencies: - debug "^4.1.0" - json-stringify-safe "^5.0.1" - lodash.set "^4.3.2" - propagate "^2.0.0" - node-abi@^2.7.0: version "2.19.3" resolved "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz#252f5dcab12dad1b5503b2d27eddd4733930282d" @@ -21672,11 +21740,6 @@ prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, object-assign "^4.1.1" react-is "^16.8.1" -propagate@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" - integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== - property-expr@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/property-expr/-/property-expr-2.0.2.tgz#fff2a43919135553a3bc2fdd94bdb841965b2330"