diff --git a/.changeset/gorgeous-pugs-deliver.md b/.changeset/gorgeous-pugs-deliver.md new file mode 100644 index 0000000000..82820baa67 --- /dev/null +++ b/.changeset/gorgeous-pugs-deliver.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Set the default TZ (Timezone) env for the test command to be UTC so any date related tests are consistent across timezones. diff --git a/.changeset/wicked-jars-move.md b/.changeset/wicked-jars-move.md new file mode 100644 index 0000000000..d2e9bc5446 --- /dev/null +++ b/.changeset/wicked-jars-move.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-cloudbuild': patch +--- + +- Swaps over the plugin CloudBuild from using MomentJS to using Luxon for date formatting. +- Fixes some React warnings generated by nested

elements. diff --git a/packages/cli/src/commands/testCommand.ts b/packages/cli/src/commands/testCommand.ts index d885e1aec9..24a4e06f9e 100644 --- a/packages/cli/src/commands/testCommand.ts +++ b/packages/cli/src/commands/testCommand.ts @@ -63,6 +63,13 @@ export default async (cmd: Command) => { (process.env as any).NODE_ENV = 'test'; } + // This is to have a consistent timezone for when running tests that involve checking + // the formatting of date/times. + // https://stackoverflow.com/questions/56261381/how-do-i-set-a-timezone-in-my-jest-config + if (!process.env.TZ) { + process.env.TZ = 'UTC'; + } + // eslint-disable-next-line jest/no-jest-import await require('jest').run(args); }; diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index d45542a082..6ae81ba6e4 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -38,7 +38,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", - "moment": "^2.27.0", + "luxon": "^2.0.2", "qs": "^6.9.4", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx new file mode 100644 index 0000000000..ac28c5bedf --- /dev/null +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx @@ -0,0 +1,103 @@ +/* + * Copyright 2020 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 { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; +import { WorkflowRunsTableView } from './WorkflowRunsTable'; +import { WorkflowRun } from '../useWorkflowRuns'; + +describe('', () => { + let runs: WorkflowRun[] = []; + + beforeEach(() => { + runs = [ + { + id: 'run_id_1', + message: 'A workflow message', + rerun: jest.fn(), + url: 'https://cloudbuild.run/', + googleUrl: 'https://google.com', + status: 'success', + substitutions: { + COMMIT_SHA: 'e3adasd2e3adasd2e3adasd2', + SHORT_SHA: 'f12j1231', + BRANCH_NAME: 'main', + REPO_NAME: 'backstage', + REVISION_ID: 'g123123', + }, + createTime: '2014-10-02T15:01:23.045123456Z', + }, + ]; + }); + + it('row has a link to the run', async () => { + const { getByTestId } = await renderInTestApp( + , + ); + + expect(getByTestId('cell-source')).toHaveAttribute('href', '/run_id_1'); + }); + + it('row has the time it was created', async () => { + const { getByTestId } = await renderInTestApp( + , + ); + + expect(getByTestId('cell-created')).toHaveTextContent( + '02-10-2014 03:01:23', + ); + }); + + it('row with an action to rerun', async () => { + const { getByTestId } = await renderInTestApp( + , + ); + + const rerunActionElement = getByTestId('action-rerun'); + rerunActionElement.click(); + expect(runs[0].rerun).toHaveBeenCalled(); + }); +}); diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index 8fbf89cdce..0d00347183 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -24,7 +24,7 @@ import SyncIcon from '@material-ui/icons/Sync'; import { useProjectName } from '../useProjectName'; import { Entity } from '@backstage/catalog-model'; import { buildRouteRef } from '../../routes'; -import moment from 'moment'; +import { DateTime } from 'luxon'; import { Table, TableColumn } from '@backstage/core-components'; const generatedColumns: TableColumn[] = [ @@ -45,7 +45,7 @@ const generatedColumns: TableColumn[] = [ width: '150px', render: (row: Partial) => ( -

{row.id?.substring(0, 8)}

+ {row.id?.substring(0, 8)} ), }, @@ -57,6 +57,7 @@ const generatedColumns: TableColumn[] = [ render: (row: Partial) => ( {row.message} @@ -67,7 +68,7 @@ const generatedColumns: TableColumn[] = [ title: 'Ref', render: (row: Partial) => ( -

{row.substitutions?.BRANCH_NAME}

+ {row.substitutions?.BRANCH_NAME}
), }, @@ -75,15 +76,17 @@ const generatedColumns: TableColumn[] = [ title: 'Commit', render: (row: Partial) => ( -

{row.substitutions?.SHORT_SHA}

+ {row.substitutions?.SHORT_SHA}
), }, { title: 'Created', render: (row: Partial) => ( - -

{moment(row.createTime).format('DD-MM-YYYY hh:mm:ss')}

+ + {DateTime.fromISO(row.createTime ?? DateTime.now().toISO()).toFormat( + 'dd-MM-yyyy hh:mm:ss', + )} ), }, @@ -91,7 +94,7 @@ const generatedColumns: TableColumn[] = [ title: 'Actions', render: (row: Partial) => ( - +