diff --git a/packages/dashboard-frontend/src/components/Head/__tests__/__snapshots__/Head.spec.tsx.snap b/packages/dashboard-frontend/src/components/Head/__tests__/__snapshots__/index.spec.tsx.snap similarity index 100% rename from packages/dashboard-frontend/src/components/Head/__tests__/__snapshots__/Head.spec.tsx.snap rename to packages/dashboard-frontend/src/components/Head/__tests__/__snapshots__/index.spec.tsx.snap diff --git a/packages/dashboard-frontend/src/components/Head/__tests__/Head.spec.tsx b/packages/dashboard-frontend/src/components/Head/__tests__/index.spec.tsx similarity index 65% rename from packages/dashboard-frontend/src/components/Head/__tests__/Head.spec.tsx rename to packages/dashboard-frontend/src/components/Head/__tests__/index.spec.tsx index 8a5bf33a3..bad18cf7b 100644 --- a/packages/dashboard-frontend/src/components/Head/__tests__/Head.spec.tsx +++ b/packages/dashboard-frontend/src/components/Head/__tests__/index.spec.tsx @@ -12,12 +12,13 @@ import React from 'react'; import { Provider } from 'react-redux'; -import renderer from 'react-test-renderer'; +import Head from '@/components/Head'; +import getComponentRenderer from '@/services/__mocks__/getComponentRenderer'; import { BrandingData } from '@/services/bootstrap/branding.constant'; import { FakeStoreBuilder } from '@/store/__mocks__/storeBuilder'; -import Head from '..'; +const { createSnapshot } = getComponentRenderer(getComponent); jest.mock('react-helmet', () => { const Helmet = (props: { children: React.ReactElement[] }) => { @@ -28,27 +29,29 @@ jest.mock('react-helmet', () => { }); describe('The head component for setting document title', () => { - const store = new FakeStoreBuilder() - .withBranding({ title: 'Dummy product title' } as BrandingData) - .build(); + afterEach(() => { + jest.clearAllMocks(); + }); it('should render default title correctly', () => { - const element = ( - - - - ); - - expect(renderer.create(element).toJSON()).toMatchSnapshot(); + const snapshot = createSnapshot(); + expect(snapshot.toJSON()).toMatchSnapshot(); }); it('should render Quick Add page title correctly', () => { - const element = ( - - - - ); - - expect(renderer.create(element).toJSON()).toMatchSnapshot(); + const snapshot = createSnapshot('Quick Add'); + expect(snapshot.toJSON()).toMatchSnapshot(); }); }); + +function getComponent(pageName?: string): React.ReactElement { + const store = new FakeStoreBuilder() + .withBranding({ title: 'Dummy product title' } as BrandingData) + .build(); + + return ( + + + + ); +} diff --git a/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/PureSubCondition.tsx b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/PureSubCondition.tsx new file mode 100644 index 000000000..6cb0327b7 --- /dev/null +++ b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/PureSubCondition.tsx @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2024 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +import React from 'react'; + +import { ProgressStepTitle } from '@/components/WorkspaceProgress/StepTitle'; + +export type Props = { + distance: -1 | 0 | 1 | undefined; + title: string | undefined; +}; + +export class PureSubCondition extends React.PureComponent { + public render(): React.ReactElement { + const { distance, title } = this.props; + + if (!title) { + return <>; + } + + return ( +
    +
  1. +
    + {title} +
    +
  2. +
+ ); + } +} diff --git a/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/__tests__/PureSubCondition.spec.tsx b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/__tests__/PureSubCondition.spec.tsx new file mode 100644 index 000000000..f7da691c5 --- /dev/null +++ b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/__tests__/PureSubCondition.spec.tsx @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018-2024 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +import React from 'react'; + +import { PureSubCondition } from '@/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/PureSubCondition'; +import getComponentRenderer, { screen } from '@/services/__mocks__/getComponentRenderer'; + +const { createSnapshot, renderComponent } = getComponentRenderer(getComponent); + +jest.mock('@/components/WorkspaceProgress/StepTitle'); + +describe('Starting sub-steps, checking rendering', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + test('snapshot with no title', () => { + expect(createSnapshot(undefined)).toMatchSnapshot(); + }); + + test('snapshot with a title', () => { + expect(createSnapshot('sub-step test', 1)).toMatchSnapshot(); + }); + + it('should show the title and a proper icon(depends on the distance value)', () => { + let distanceElement: HTMLElement | null; + let stepTitle: HTMLElement | null; + + const { reRenderComponent } = renderComponent('sub-step test 1', -1); + + distanceElement = screen.queryByTestId('distance'); + expect(distanceElement).not.toBeNull(); + expect(distanceElement).toHaveTextContent('-1'); + + stepTitle = screen.queryByTestId('step-title'); + expect(stepTitle).not.toBeNull(); + expect(stepTitle).toHaveTextContent('sub-step test 1'); + + reRenderComponent('sub-step test 2', 0); + + distanceElement = screen.queryByTestId('distance'); + expect(distanceElement).not.toBeNull(); + expect(distanceElement).toHaveTextContent('0'); + + stepTitle = screen.queryByTestId('step-title'); + expect(stepTitle).not.toBeNull(); + expect(stepTitle).toHaveTextContent('sub-step test 2'); + + reRenderComponent('sub-step test 3', 1); + + distanceElement = screen.queryByTestId('distance'); + expect(distanceElement).not.toBeNull(); + expect(distanceElement).toHaveTextContent('1'); + + stepTitle = screen.queryByTestId('step-title'); + expect(stepTitle).not.toBeNull(); + expect(stepTitle).toHaveTextContent('sub-step test 3'); + + reRenderComponent(undefined, 1); + + distanceElement = screen.queryByTestId('distance'); + expect(distanceElement).toBeNull(); + + stepTitle = screen.queryByTestId('step-title'); + expect(stepTitle).toBeNull(); + }); +}); + +function getComponent(title: string | undefined, distance?: -1 | 0 | 1): React.ReactElement { + return ; +} diff --git a/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/__tests__/__snapshots__/PureSubCondition.spec.tsx.snap b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/__tests__/__snapshots__/PureSubCondition.spec.tsx.snap new file mode 100644 index 000000000..a1fd7c27a --- /dev/null +++ b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/__tests__/__snapshots__/PureSubCondition.spec.tsx.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Starting sub-steps, checking rendering snapshot with a title 1`] = ` +
    +
  1. +
    +
    +
    + 1 +
    + + sub-step test + +
    +
    +
  2. +
+`; + +exports[`Starting sub-steps, checking rendering snapshot with no title 1`] = `null`; diff --git a/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/index.tsx b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/index.tsx index a540693b9..2373b5d0d 100644 --- a/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/index.tsx +++ b/packages/dashboard-frontend/src/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/index.tsx @@ -21,6 +21,7 @@ import { ProgressStepState, } from '@/components/WorkspaceProgress/ProgressStep'; import styles from '@/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/index.module.css'; +import { PureSubCondition } from '@/components/WorkspaceProgress/StartingSteps/WorkspaceConditions/PureSubCondition'; import { ProgressStepTitle } from '@/components/WorkspaceProgress/StepTitle'; import { ConditionType, @@ -38,9 +39,12 @@ export type State = ProgressStepState & { isWarning: boolean; isReady: boolean; condition: ConditionType; + subConditionTitle: string; }; export default class StartingStepWorkspaceConditions extends ProgressStep { + private timerId: number | undefined; + constructor(props: Props) { super(props); @@ -56,10 +60,13 @@ export default class StartingStepWorkspaceConditions extends ProgressStep { + this.setState({ + subConditionTitle: + 'Downloading IDE binaries... (it can take a few minutes depending on your internet connection)', + }); + }, 20000); + } + } + public componentDidMount() { const state = this.buildState(this.props, undefined, this.state); this.setState(state); + + this.checkForSubCondition(state.condition); } public async componentDidUpdate(prevProps: Props) { const state = this.buildState(this.props, prevProps, this.state); this.setState(state); + + if (state.subConditionTitle === '') { + this.checkForSubCondition(state.condition); + } } public shouldComponentUpdate(nextProps: Props, nextState: State): boolean { - if (isEqual(this.props.condition, nextProps.condition) === false) { + if (!isEqual(this.props.condition, nextProps.condition)) { + return true; + } + + if (!isEqual(this.state.condition, nextState.condition)) { return true; } - if (isEqual(this.state.condition, nextState.condition) === false) { + if (this.state.subConditionTitle !== nextState.subConditionTitle) { return true; } @@ -123,8 +158,8 @@ export default class StartingStepWorkspaceConditions extends ProgressStep {this.name} + ); diff --git a/packages/dashboard-frontend/src/components/WorkspaceProgress/StepTitle/index.tsx b/packages/dashboard-frontend/src/components/WorkspaceProgress/StepTitle/index.tsx index a81c7abb8..200fd97b1 100644 --- a/packages/dashboard-frontend/src/components/WorkspaceProgress/StepTitle/index.tsx +++ b/packages/dashboard-frontend/src/components/WorkspaceProgress/StepTitle/index.tsx @@ -18,9 +18,9 @@ import styles from '@/components/WorkspaceProgress/StepTitle/index.module.css'; export type Props = PropsWithChildren<{ className?: string; distance: -1 | 0 | 1 | undefined; - hasChildren: boolean; - isError: boolean; - isWarning: boolean; + hasChildren?: boolean; + isError?: boolean; + isWarning?: boolean; }>; export class ProgressStepTitle extends React.Component { @@ -41,7 +41,11 @@ export class ProgressStepTitle extends React.Component { return ( <> - + {children} diff --git a/run/local-run.sh b/run/local-run.sh index 6b85f84a9..79c0ffb82 100755 --- a/run/local-run.sh +++ b/run/local-run.sh @@ -104,7 +104,7 @@ if [ ! -d $DASHBOARD_FRONTEND/lib/public/dashboard/devfile-registry ]; then -i "packages/devfile-registry/air-gap/index.json" if [ -s "$DASHBOARD_FRONTEND/lib/public/dashboard/devfile-registry/air-gap/index.json" ]; then - scripts/sed_in_place 's|CHE_DASHBOARD_INTERNAL_URL|http://localhost:8080|g' "$DASHBOARD_FRONTEND/lib/public/dashboard/devfile-registry/air-gap/index.json" + $(pwd)/scripts/sed_in_place.sh 's|CHE_DASHBOARD_INTERNAL_URL|http://localhost:8080|g' "$DASHBOARD_FRONTEND/lib/public/dashboard/devfile-registry/air-gap/index.json" fi fi