From 9ad8b8fe88e923f68c1bcf2a8195a6b982b4f2d4 Mon Sep 17 00:00:00 2001 From: Oleksii Kurinnyi Date: Wed, 29 Nov 2023 15:36:55 +0200 Subject: [PATCH 1/3] test(backend): add missing unit tests Signed-off-by: Oleksii Kurinnyi --- packages/dashboard-backend/jest.config.js | 1 + .../src/models/__tests__/index.spec.ts | 20 +++++ .../src/models/__tests__/restParams.spec.ts | 20 +++++ .../services/__tests__/ObjectsWatcher.spec.ts | 80 +++++++++++++++++ .../__tests__/SubscriptionManager.spec.ts | 58 ++++++++++++ .../src/services/__tests__/helpers.spec.ts | 88 +++++++++++++++++++ .../helpers/__tests__/index.spec.ts | 46 ++++++++++ .../src/services/kubeclient/helpers/index.ts | 2 +- .../{__mock__ => __mocks__}/index.ts | 0 .../services/types/__tests__/Observer.spec.ts | 20 +++++ 10 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 packages/dashboard-backend/src/models/__tests__/index.spec.ts create mode 100644 packages/dashboard-backend/src/models/__tests__/restParams.spec.ts create mode 100644 packages/dashboard-backend/src/services/__tests__/ObjectsWatcher.spec.ts create mode 100644 packages/dashboard-backend/src/services/__tests__/SubscriptionManager.spec.ts create mode 100644 packages/dashboard-backend/src/services/__tests__/helpers.spec.ts create mode 100644 packages/dashboard-backend/src/services/kubeclient/helpers/__tests__/index.spec.ts rename packages/dashboard-backend/src/services/logWatcher/{__mock__ => __mocks__}/index.ts (100%) create mode 100644 packages/dashboard-backend/src/services/types/__tests__/Observer.spec.ts diff --git a/packages/dashboard-backend/jest.config.js b/packages/dashboard-backend/jest.config.js index 0469ae0e2..7fe296e05 100644 --- a/packages/dashboard-backend/jest.config.js +++ b/packages/dashboard-backend/jest.config.js @@ -28,6 +28,7 @@ module.exports = { '!src/localRun/**', '!src/utils/**', '!src/server.ts', + '!src/**/*.d.ts', ], testEnvironment: 'node', setupFilesAfterEnv: ['./jest.setup.js'], diff --git a/packages/dashboard-backend/src/models/__tests__/index.spec.ts b/packages/dashboard-backend/src/models/__tests__/index.spec.ts new file mode 100644 index 000000000..f472a6891 --- /dev/null +++ b/packages/dashboard-backend/src/models/__tests__/index.spec.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2023 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 * as models from '@/models'; + +describe('models', () => { + it('should export models', () => { + // this makes the coverage tool happy + expect(models).toBeDefined(); + }); +}); diff --git a/packages/dashboard-backend/src/models/__tests__/restParams.spec.ts b/packages/dashboard-backend/src/models/__tests__/restParams.spec.ts new file mode 100644 index 000000000..99844f036 --- /dev/null +++ b/packages/dashboard-backend/src/models/__tests__/restParams.spec.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2023 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 * as restParams from '@/models/restParams'; + +describe('restParams', () => { + it('should export restParams', () => { + // this makes the coverage tool happy + expect(restParams).toBeDefined(); + }); +}); diff --git a/packages/dashboard-backend/src/services/__tests__/ObjectsWatcher.spec.ts b/packages/dashboard-backend/src/services/__tests__/ObjectsWatcher.spec.ts new file mode 100644 index 000000000..4431be948 --- /dev/null +++ b/packages/dashboard-backend/src/services/__tests__/ObjectsWatcher.spec.ts @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018-2023 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 { api } from '@eclipse-che/common'; + +import { IWatcherService } from '@/devworkspaceClient'; +import { ObjectsWatcher } from '@/services/ObjectsWatcher'; + +describe('ObjectsWatcher', () => { + const message = 'message'; + const channel = api.webSocket.Channel.DEV_WORKSPACE; + + const mockListener = jest.fn(); + const mockParams = { param: 'value' }; + + const mockStopWatching = jest.fn(); + const mockWatchInNamespace = jest + .fn() + .mockImplementation(listener => Promise.resolve(listener(message))); + + let objectsWatcher: ObjectsWatcher; + + beforeEach(() => { + const apiService = { + stopWatching: () => mockStopWatching(), + watchInNamespace: (...args) => mockWatchInNamespace(...args), + } as IWatcherService; + objectsWatcher = new ObjectsWatcher(apiService, channel); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('start watching w/o observer', async () => { + await objectsWatcher.start('test', mockParams); + + expect(mockWatchInNamespace).toHaveBeenCalledWith(expect.any(Function), mockParams); + }); + + test('watch changes with observer', async () => { + const observer = { + update: mockListener, + }; + objectsWatcher.attach(observer); + + await objectsWatcher.start('test', mockParams); + + expect(mockListener).toHaveBeenCalledWith(channel, 'message'); + expect(mockWatchInNamespace).toHaveBeenCalledWith(expect.any(Function), mockParams); + }); + + test('detach observer', async () => { + const observer = { + update: mockListener, + }; + objectsWatcher.attach(observer); + objectsWatcher.detach(); + + await objectsWatcher.start('test', mockParams); + + expect(mockListener).not.toHaveBeenCalled(); + expect(mockWatchInNamespace).toHaveBeenCalledWith(expect.any(Function), mockParams); + }); + + test('stop watching', async () => { + objectsWatcher.stop(); + + expect(mockStopWatching).toHaveBeenCalled(); + }); +}); diff --git a/packages/dashboard-backend/src/services/__tests__/SubscriptionManager.spec.ts b/packages/dashboard-backend/src/services/__tests__/SubscriptionManager.spec.ts new file mode 100644 index 000000000..d69a1a722 --- /dev/null +++ b/packages/dashboard-backend/src/services/__tests__/SubscriptionManager.spec.ts @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018-2023 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 { api } from '@eclipse-che/common'; +import MockWebSocket from 'jest-websocket-mock'; +import WS from 'ws'; + +import { SubscriptionManager } from '@/services/SubscriptionManager'; +import { NotificationMessage } from '@/services/types/Observer'; + +describe('SubscriptionManager', () => { + const channel = api.webSocket.Channel.DEV_WORKSPACE; + + const ws = new MockWebSocket('ws://localhost') as unknown as WS; + const spyWsSend = jest.spyOn(ws, 'send'); + + let subscriptionManager: SubscriptionManager; + + beforeEach(() => { + subscriptionManager = new SubscriptionManager(ws); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('subscribe and update', () => { + subscriptionManager.subscribe(channel); + + const message = { + eventPhase: api.webSocket.EventPhase.ADDED, + } as NotificationMessage; + subscriptionManager.update(channel, message); + + expect(spyWsSend).toHaveBeenCalled(); + }); + + test('unsubscribe all channels', () => { + subscriptionManager.subscribe(channel); + subscriptionManager.unsubscribeAll(); + + const message = { + eventPhase: api.webSocket.EventPhase.ADDED, + } as NotificationMessage; + subscriptionManager.update(channel, message); + + expect(spyWsSend).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/dashboard-backend/src/services/__tests__/helpers.spec.ts b/packages/dashboard-backend/src/services/__tests__/helpers.spec.ts new file mode 100644 index 000000000..d596e4a09 --- /dev/null +++ b/packages/dashboard-backend/src/services/__tests__/helpers.spec.ts @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018-2023 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 { authenticationHeaderSchema } from '@/constants/schemas'; +import * as helpers from '@/services/helpers'; + +describe('helpers', () => { + test('delay', async () => { + jest.useFakeTimers(); + + const mockCallback = jest.fn(); + const promise = helpers.delay(1000).then(mockCallback); + + await jest.advanceTimersByTimeAsync(500); + expect(mockCallback).not.toHaveBeenCalled(); + + await jest.advanceTimersByTimeAsync(500); + expect(promise).resolves.toBeUndefined(); + expect(mockCallback).toHaveBeenCalled(); + + jest.useRealTimers(); + }); + + test('getSchema', () => { + const schema = helpers.getSchema({ + tags: ['test'], + namespacedSchema: { + type: 'object', + properties: { + namespace: { + type: 'string', + }, + }, + }, + body: { + type: 'object', + properties: { + name: { + type: 'string', + }, + }, + }, + }); + + expect(schema).toEqual({ + schema: { + headers: authenticationHeaderSchema, + namespacedSchema: { + properties: { + namespace: { + type: 'string', + }, + }, + type: 'object', + }, + security: [ + { + Authorization: '', + }, + ], + tags: ['test'], + body: { + type: 'object', + properties: { + name: { + type: 'string', + }, + }, + }, + }, + }); + }); + + test('createFastifyError', () => { + const error = helpers.createFastifyError('test', '500'); + expect(error).toBeInstanceOf(Error); + expect(error.statusCode).toEqual(500); + }); +}); diff --git a/packages/dashboard-backend/src/services/kubeclient/helpers/__tests__/index.spec.ts b/packages/dashboard-backend/src/services/kubeclient/helpers/__tests__/index.spec.ts new file mode 100644 index 000000000..133eeee33 --- /dev/null +++ b/packages/dashboard-backend/src/services/kubeclient/helpers/__tests__/index.spec.ts @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018-2023 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 * as k8s from '@kubernetes/client-node'; + +import { isOpenShift } from '@/services/kubeclient/helpers'; + +const mockFindApi = jest.fn(); +jest.mock('@/helpers/findApi', () => ({ + findApi: jest.fn().mockImplementation(() => mockFindApi()), +})); + +describe('isOpenShift', () => { + it('should return true if project.openshift.io API is available', async () => { + mockFindApi.mockResolvedValue(true); + + const res = await isOpenShift({} as k8s.ApisApi); + + expect(res).toBe(true); + }); + + it('should return false if project.openshift.io API is not available', async () => { + mockFindApi.mockResolvedValue(false); + + const res = await isOpenShift({} as k8s.ApisApi); + + expect(res).toBe(false); + }); + + it('should throw an error if findApi throws an error', async () => { + mockFindApi.mockRejectedValue(new Error('find-api-error')); + + await expect(isOpenShift({} as k8s.ApisApi)).rejects.toThrow( + `Can't evaluate target platform: find-api-error`, + ); + }); +}); diff --git a/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts b/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts index 6102d04dd..adf9c9c0d 100644 --- a/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts +++ b/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts @@ -19,7 +19,7 @@ const projectApiGroup = 'project.openshift.io'; export async function isOpenShift(apisApi: k8s.ApisApi): Promise { try { - return findApi(apisApi, projectApiGroup); + return await findApi(apisApi, projectApiGroup); } catch (e) { throw new Error(`Can't evaluate target platform: ${helpers.errors.getMessage(e)}`); } diff --git a/packages/dashboard-backend/src/services/logWatcher/__mock__/index.ts b/packages/dashboard-backend/src/services/logWatcher/__mocks__/index.ts similarity index 100% rename from packages/dashboard-backend/src/services/logWatcher/__mock__/index.ts rename to packages/dashboard-backend/src/services/logWatcher/__mocks__/index.ts diff --git a/packages/dashboard-backend/src/services/types/__tests__/Observer.spec.ts b/packages/dashboard-backend/src/services/types/__tests__/Observer.spec.ts new file mode 100644 index 000000000..15affba3f --- /dev/null +++ b/packages/dashboard-backend/src/services/types/__tests__/Observer.spec.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2023 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 * as Observer from '@/services/types/Observer'; + +describe('Observer', () => { + it('should export Subject', () => { + // this makes the coverage tool happy + expect(Observer).toBeDefined(); + }); +}); From ba3d44149c1cb8d3259bc8d1233e8c7d405be85d Mon Sep 17 00:00:00 2001 From: Oleksii Kurinnyi Date: Fri, 1 Dec 2023 16:54:54 +0200 Subject: [PATCH 2/3] test(frontend): add missing unit tests Signed-off-by: Oleksii Kurinnyi --- packages/dashboard-frontend/jest.config.js | 1 + .../Layout/ErrorBoundary/__mocks__/index.tsx | 29 +++++ .../src/Layout/ErrorBoundary/index.tsx | 2 +- .../src/Layout/Header/__mocks__/index.tsx | 27 +++++ .../src/Layout/Header/index.tsx | 2 +- .../src/Layout/Navigation/__mocks__/index.tsx | 19 ++++ .../src/Layout/Sidebar/__mocks__/index.tsx | 27 +++++ .../__snapshots__/index.spec.tsx.snap | 17 +++ .../Layout/Sidebar/__tests__/index.spec.tsx | 32 ++++++ .../Layout/{Sidebar.tsx => Sidebar/index.tsx} | 2 +- .../StoreErrorsAlert/__mocks__/index.tsx | 19 ++++ .../__snapshots__/index.spec.tsx.snap | 56 +++++++++ .../src/Layout/__tests__/index.spec.tsx | 107 ++++++++++++++++++ .../dashboard-frontend/src/Layout/index.tsx | 8 +- .../BannerAlert/Branding/__mocks__/index.tsx | 19 ++++ .../BannerAlert/Custom/__mocks__/index.tsx | 19 ++++ .../NotSupportedBrowser/__mocks__/index.tsx | 19 ++++ .../BannerAlert/WebSocket/__mocks__/index.tsx | 19 ++++ .../BannerAlert/__mocks__/index.tsx | 19 ++++ .../__snapshots__/index.spec.tsx.snap | 21 ++++ .../BannerAlert/__tests__/index.spec.tsx | 33 ++++++ .../__tests__/index.spec.ts | 20 ++++ .../__tests__/metadata.spec.ts | 20 ++++ .../devfileApi/devWorkspaceTemplate/index.ts | 4 - .../devfile/__tests__/index.spec.ts | 20 ++++ .../devfile/__tests__/metadata.spec.ts | 20 ++++ 26 files changed, 571 insertions(+), 10 deletions(-) create mode 100644 packages/dashboard-frontend/src/Layout/ErrorBoundary/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/Layout/Header/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/Layout/Navigation/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/Layout/Sidebar/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/Layout/Sidebar/__tests__/__snapshots__/index.spec.tsx.snap create mode 100644 packages/dashboard-frontend/src/Layout/Sidebar/__tests__/index.spec.tsx rename packages/dashboard-frontend/src/Layout/{Sidebar.tsx => Sidebar/index.tsx} (97%) create mode 100644 packages/dashboard-frontend/src/Layout/StoreErrorsAlert/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/Layout/__tests__/__snapshots__/index.spec.tsx.snap create mode 100644 packages/dashboard-frontend/src/Layout/__tests__/index.spec.tsx create mode 100644 packages/dashboard-frontend/src/components/BannerAlert/Branding/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/components/BannerAlert/Custom/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/components/BannerAlert/NotSupportedBrowser/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/components/BannerAlert/WebSocket/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/components/BannerAlert/__mocks__/index.tsx create mode 100644 packages/dashboard-frontend/src/components/BannerAlert/__tests__/__snapshots__/index.spec.tsx.snap create mode 100644 packages/dashboard-frontend/src/components/BannerAlert/__tests__/index.spec.tsx create mode 100644 packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/index.spec.ts create mode 100644 packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/metadata.spec.ts create mode 100644 packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/index.spec.ts create mode 100644 packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/metadata.spec.ts diff --git a/packages/dashboard-frontend/jest.config.js b/packages/dashboard-frontend/jest.config.js index 89d202df5..12a702399 100644 --- a/packages/dashboard-frontend/jest.config.js +++ b/packages/dashboard-frontend/jest.config.js @@ -46,6 +46,7 @@ module.exports = { '!src/index.tsx', '!src/App.tsx', '!src/Routes.tsx', + '!src/service-worker.ts', ], coverageThreshold: { global: { diff --git a/packages/dashboard-frontend/src/Layout/ErrorBoundary/__mocks__/index.tsx b/packages/dashboard-frontend/src/Layout/ErrorBoundary/__mocks__/index.tsx new file mode 100644 index 000000000..812c3170d --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/ErrorBoundary/__mocks__/index.tsx @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018-2023 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 { Props } from '@/Layout/ErrorBoundary'; + +export const errorMessage = 'Error Boundary Message'; + +export class ErrorBoundary extends React.PureComponent { + public render(): React.ReactElement { + return ( +
+ Mock ErrorBoundary component + + {this.props.children} +
+ ); + } +} diff --git a/packages/dashboard-frontend/src/Layout/ErrorBoundary/index.tsx b/packages/dashboard-frontend/src/Layout/ErrorBoundary/index.tsx index 4c6284787..9a1dbdb7b 100644 --- a/packages/dashboard-frontend/src/Layout/ErrorBoundary/index.tsx +++ b/packages/dashboard-frontend/src/Layout/ErrorBoundary/index.tsx @@ -29,7 +29,7 @@ export const STORAGE_KEY_RELOAD_NUMBER = 'UD:ErrorBoundary:reloaded'; const RELOAD_TIMEOUT_SEC = 30; const RELOADS_FOR_EXTENDED_MESSAGE = 2; -type Props = PropsWithChildren & { +export type Props = PropsWithChildren & { onError: (error?: string) => void; }; type State = { diff --git a/packages/dashboard-frontend/src/Layout/Header/__mocks__/index.tsx b/packages/dashboard-frontend/src/Layout/Header/__mocks__/index.tsx new file mode 100644 index 000000000..f9f2ea818 --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/Header/__mocks__/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2023 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 { Props } from '@/Layout/Header'; + +export default class Header extends React.PureComponent { + public render(): React.ReactElement { + return ( +
+ Mock Header component + + +
+ ); + } +} diff --git a/packages/dashboard-frontend/src/Layout/Header/index.tsx b/packages/dashboard-frontend/src/Layout/Header/index.tsx index 9ddfef457..46c2ae410 100644 --- a/packages/dashboard-frontend/src/Layout/Header/index.tsx +++ b/packages/dashboard-frontend/src/Layout/Header/index.tsx @@ -16,7 +16,7 @@ import React from 'react'; import HeaderTools from '@/Layout/Header/Tools'; -type Props = { +export type Props = { history: History; isVisible: boolean; logo: React.ReactNode; diff --git a/packages/dashboard-frontend/src/Layout/Navigation/__mocks__/index.tsx b/packages/dashboard-frontend/src/Layout/Navigation/__mocks__/index.tsx new file mode 100644 index 000000000..4427ada4c --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/Navigation/__mocks__/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-2023 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'; + +export default class Navigation extends React.PureComponent { + public render(): React.ReactElement { + return
Mock Navigation component
; + } +} diff --git a/packages/dashboard-frontend/src/Layout/Sidebar/__mocks__/index.tsx b/packages/dashboard-frontend/src/Layout/Sidebar/__mocks__/index.tsx new file mode 100644 index 000000000..bc5d0a764 --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/Sidebar/__mocks__/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2023 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 { Props } from '@/Layout/Sidebar'; + +export default class Sidebar extends React.PureComponent { + public render(): React.ReactElement { + return ( +
+ Mock Sidebar component + {this.props.isManaged ? 'true' : 'false'} + {this.props.isNavOpen ? 'true' : 'false'} +
+ ); + } +} diff --git a/packages/dashboard-frontend/src/Layout/Sidebar/__tests__/__snapshots__/index.spec.tsx.snap b/packages/dashboard-frontend/src/Layout/Sidebar/__tests__/__snapshots__/index.spec.tsx.snap new file mode 100644 index 000000000..7f85cac85 --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/Sidebar/__tests__/__snapshots__/index.spec.tsx.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Sidebar snapshot 1`] = ` +
+
+
+ Mock Navigation component +
+
+
+`; diff --git a/packages/dashboard-frontend/src/Layout/Sidebar/__tests__/index.spec.tsx b/packages/dashboard-frontend/src/Layout/Sidebar/__tests__/index.spec.tsx new file mode 100644 index 000000000..ae4b07e33 --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/Sidebar/__tests__/index.spec.tsx @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018-2023 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 { createMemoryHistory } from 'history'; +import React from 'react'; + +import Sidebar from '@/Layout/Sidebar'; +import getComponentRenderer from '@/services/__mocks__/getComponentRenderer'; + +jest.mock('@/Layout/Navigation'); + +const { createSnapshot } = getComponentRenderer(getComponent); + +describe('Sidebar', () => { + test('snapshot', () => { + expect(createSnapshot(false, true).toJSON()).toMatchSnapshot(); + }); +}); + +function getComponent(isManaged: boolean, isNavOpen: boolean): React.ReactElement { + const history = createMemoryHistory(); + return ; +} diff --git a/packages/dashboard-frontend/src/Layout/Sidebar.tsx b/packages/dashboard-frontend/src/Layout/Sidebar/index.tsx similarity index 97% rename from packages/dashboard-frontend/src/Layout/Sidebar.tsx rename to packages/dashboard-frontend/src/Layout/Sidebar/index.tsx index 93db22e07..3b2e944df 100644 --- a/packages/dashboard-frontend/src/Layout/Sidebar.tsx +++ b/packages/dashboard-frontend/src/Layout/Sidebar/index.tsx @@ -16,7 +16,7 @@ import React from 'react'; import Navigation from '@/Layout/Navigation'; -type Props = { +export type Props = { isManaged: boolean; isNavOpen: boolean; history: History; diff --git a/packages/dashboard-frontend/src/Layout/StoreErrorsAlert/__mocks__/index.tsx b/packages/dashboard-frontend/src/Layout/StoreErrorsAlert/__mocks__/index.tsx new file mode 100644 index 000000000..3f47199f9 --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/StoreErrorsAlert/__mocks__/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-2023 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'; + +export default class StoreErrorsAlert extends React.PureComponent { + public render(): React.ReactElement { + return
Mock StoreErrorsAlert component
; + } +} diff --git a/packages/dashboard-frontend/src/Layout/__tests__/__snapshots__/index.spec.tsx.snap b/packages/dashboard-frontend/src/Layout/__tests__/__snapshots__/index.spec.tsx.snap new file mode 100644 index 000000000..b810b4c08 --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/__tests__/__snapshots__/index.spec.tsx.snap @@ -0,0 +1,56 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Layout component snapshot 1`] = ` +
+
+ Mock Header component + + +
+
+ Mock Sidebar component + + false + + + true + +
+
+
+ Mock ErrorBoundary component + +
+ Mock StoreErrorsAlert component +
+
+ Mock BannerAlert component +
+
+ Test +
+
+
+
+`; diff --git a/packages/dashboard-frontend/src/Layout/__tests__/index.spec.tsx b/packages/dashboard-frontend/src/Layout/__tests__/index.spec.tsx new file mode 100644 index 000000000..28c5cddf9 --- /dev/null +++ b/packages/dashboard-frontend/src/Layout/__tests__/index.spec.tsx @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018-2023 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 userEvent from '@testing-library/user-event'; +import { createMemoryHistory } from 'history'; +import React from 'react'; +import { Provider } from 'react-redux'; +import { Store } from 'redux'; + +import Layout from '@/Layout'; +import getComponentRenderer, { screen } from '@/services/__mocks__/getComponentRenderer'; +import { BrandingData } from '@/services/bootstrap/branding.constant'; +import { FakeStoreBuilder } from '@/store/__mocks__/storeBuilder'; +import * as SanityCheckStore from '@/store/SanityCheck'; + +jest.mock('@/Layout/ErrorBoundary'); +jest.mock('@/Layout/Header'); +jest.mock('@/Layout/Sidebar'); +jest.mock('@/Layout/StoreErrorsAlert'); +jest.mock('@/components/BannerAlert'); +jest.mock('@/contexts/ToggleBars'); + +const mockLogout = jest.fn().mockResolvedValue(undefined); +jest.mock('@/services/helpers/login.ts', () => ({ + signOut: () => mockLogout(), +})); + +const mockTestBackends = jest.fn(); +jest.mock('@/store/SanityCheck/index', () => ({ + ...jest.requireActual('@/store/SanityCheck/index'), + actionCreators: { + testBackends: () => async () => mockTestBackends(), + } as SanityCheckStore.ActionCreators, +})); + +const { createSnapshot, renderComponent } = getComponentRenderer(getComponent); + +describe('Layout component', () => { + let store: Store; + + beforeEach(() => { + store = new FakeStoreBuilder() + .withBranding({ + logoFile: 'logo-File', + } as BrandingData) + .build(); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('snapshot', () => { + const snapshot = createSnapshot(store); + expect(snapshot).toMatchSnapshot(); + }); + + test('logout', () => { + renderComponent(store); + const logoutButton = screen.getByRole('button', { name: 'logout' }); + userEvent.click(logoutButton); + + expect(mockLogout).toHaveBeenCalledTimes(1); + }); + + test('toggleNav', () => { + renderComponent(store); + + expect(screen.getByTestId('isNavOpen')).toHaveTextContent('true'); + + const toggleNavButton = screen.getByRole('button', { name: 'toggleNav' }); + userEvent.click(toggleNavButton); + + expect(screen.getByTestId('isNavOpen')).toHaveTextContent('false'); + }); + + test('onError', () => { + mockTestBackends.mockResolvedValue(undefined); + + renderComponent(store); + + const btn = screen.getByRole('button', { name: 'onError' }); + userEvent.click(btn); + + expect(mockTestBackends).toHaveBeenCalled(); + }); +}); + +function getComponent(store: Store) { + const history = createMemoryHistory(); + return ( + + +
Test
+
+
+ ); +} diff --git a/packages/dashboard-frontend/src/Layout/index.tsx b/packages/dashboard-frontend/src/Layout/index.tsx index b8fd2a9f9..078536e96 100644 --- a/packages/dashboard-frontend/src/Layout/index.tsx +++ b/packages/dashboard-frontend/src/Layout/index.tsx @@ -89,13 +89,15 @@ export class Layout extends React.PureComponent { this.hideAllBars(); } } - private testBackends(error?: string): void { - this.props.testBackends().catch(() => { + private async testBackends(error?: string): Promise { + try { + await this.props.testBackends(); + } catch (e) { if (error) { console.error(error); } console.error('Error testing backends:', this.props.sanityCheckError); - }); + } } public render(): React.ReactElement { diff --git a/packages/dashboard-frontend/src/components/BannerAlert/Branding/__mocks__/index.tsx b/packages/dashboard-frontend/src/components/BannerAlert/Branding/__mocks__/index.tsx new file mode 100644 index 000000000..192c734cd --- /dev/null +++ b/packages/dashboard-frontend/src/components/BannerAlert/Branding/__mocks__/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-2023 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'; + +export default class BannerAlertBranding extends React.PureComponent { + public render(): React.ReactElement { + return
Mock BannerAlertBranding component
; + } +} diff --git a/packages/dashboard-frontend/src/components/BannerAlert/Custom/__mocks__/index.tsx b/packages/dashboard-frontend/src/components/BannerAlert/Custom/__mocks__/index.tsx new file mode 100644 index 000000000..285e8aeeb --- /dev/null +++ b/packages/dashboard-frontend/src/components/BannerAlert/Custom/__mocks__/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-2023 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'; + +export default class BannerAlertCustomWarning extends React.PureComponent { + public render(): React.ReactElement { + return
Mock BannerAlertCustomWarning component
; + } +} diff --git a/packages/dashboard-frontend/src/components/BannerAlert/NotSupportedBrowser/__mocks__/index.tsx b/packages/dashboard-frontend/src/components/BannerAlert/NotSupportedBrowser/__mocks__/index.tsx new file mode 100644 index 000000000..e9f2aadc1 --- /dev/null +++ b/packages/dashboard-frontend/src/components/BannerAlert/NotSupportedBrowser/__mocks__/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-2023 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'; + +export default class BannerAlertNotSupportedBrowser extends React.PureComponent { + public render(): React.ReactElement { + return
Mock BannerAlertNotSupportedBrowser component
; + } +} diff --git a/packages/dashboard-frontend/src/components/BannerAlert/WebSocket/__mocks__/index.tsx b/packages/dashboard-frontend/src/components/BannerAlert/WebSocket/__mocks__/index.tsx new file mode 100644 index 000000000..b29196bf1 --- /dev/null +++ b/packages/dashboard-frontend/src/components/BannerAlert/WebSocket/__mocks__/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-2023 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'; + +export default class BannerAlertWebSocket extends React.PureComponent { + public render(): React.ReactElement { + return
Mock BannerAlertWebSocket component
; + } +} diff --git a/packages/dashboard-frontend/src/components/BannerAlert/__mocks__/index.tsx b/packages/dashboard-frontend/src/components/BannerAlert/__mocks__/index.tsx new file mode 100644 index 000000000..f6e606c9e --- /dev/null +++ b/packages/dashboard-frontend/src/components/BannerAlert/__mocks__/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-2023 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'; + +export class BannerAlert extends React.PureComponent { + public render(): React.ReactElement { + return
Mock BannerAlert component
; + } +} diff --git a/packages/dashboard-frontend/src/components/BannerAlert/__tests__/__snapshots__/index.spec.tsx.snap b/packages/dashboard-frontend/src/components/BannerAlert/__tests__/__snapshots__/index.spec.tsx.snap new file mode 100644 index 000000000..059d03ff7 --- /dev/null +++ b/packages/dashboard-frontend/src/components/BannerAlert/__tests__/__snapshots__/index.spec.tsx.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BannerAlert snapshot 1`] = ` +
+
+
+ Mock BannerAlertWebSocket component +
+
+
+
+ Mock BannerAlertBranding component +
+
+
+
+ Mock BannerAlertCustomWarning component +
+
+
+`; diff --git a/packages/dashboard-frontend/src/components/BannerAlert/__tests__/index.spec.tsx b/packages/dashboard-frontend/src/components/BannerAlert/__tests__/index.spec.tsx new file mode 100644 index 000000000..a1da2f38c --- /dev/null +++ b/packages/dashboard-frontend/src/components/BannerAlert/__tests__/index.spec.tsx @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-2023 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 { BannerAlert } from '@/components/BannerAlert'; +import getComponentRenderer from '@/services/__mocks__/getComponentRenderer'; + +jest.mock('@/components/BannerAlert/Branding'); +jest.mock('@/components/BannerAlert/Custom'); +jest.mock('@/components/BannerAlert/NotSupportedBrowser'); +jest.mock('@/components/BannerAlert/WebSocket'); + +const { createSnapshot } = getComponentRenderer(getComponent); + +describe('BannerAlert', () => { + test('snapshot', () => { + expect(createSnapshot().toJSON()).toMatchSnapshot(); + }); +}); + +function getComponent() { + return ; +} diff --git a/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/index.spec.ts b/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/index.spec.ts new file mode 100644 index 000000000..2c2b31265 --- /dev/null +++ b/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/index.spec.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2023 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 * as DWT from '@/services/devfileApi/devWorkspaceTemplate'; + +describe('devWorkspaceTemplate', () => { + // this makes the coverage tool happy + test('should export devWorkspaceTemplate', () => { + expect(DWT).toBeDefined(); + }); +}); diff --git a/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/metadata.spec.ts b/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/metadata.spec.ts new file mode 100644 index 000000000..f8cb7b32a --- /dev/null +++ b/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/__tests__/metadata.spec.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2023 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 * as DWTMetadata from '@/services/devfileApi/devWorkspaceTemplate/metadata'; + +describe('devWorkspaceTemplate', () => { + // this makes the coverage tool happy + test('should export devWorkspaceTemplate', () => { + expect(DWTMetadata).toBeDefined(); + }); +}); diff --git a/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/index.ts b/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/index.ts index 6a56a657a..d64d2aef1 100644 --- a/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/index.ts +++ b/packages/dashboard-frontend/src/services/devfileApi/devWorkspaceTemplate/index.ts @@ -21,10 +21,6 @@ type DevWorkspaceTemplateRequired = Pick< V1alpha2DevWorkspaceTemplate, 'apiVersion' | 'kind' | 'metadata' >; -type DevWorkspaceTemplateRequiredField = keyof DevWorkspaceTemplateRequired; - -export const devWorkspaceTemplateRequiredFields: `${DevWorkspaceTemplateRequiredField} | ${DevWorkspaceTemplateRequiredField} | ${DevWorkspaceTemplateRequiredField}` = - 'apiVersion | kind | metadata'; export type DevWorkspaceTemplate = V1alpha2DevWorkspaceTemplate & Required & { diff --git a/packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/index.spec.ts b/packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/index.spec.ts new file mode 100644 index 000000000..b271c9f78 --- /dev/null +++ b/packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/index.spec.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2023 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 * as devfile from '@/services/devfileApi/devfile'; + +describe('devfile', () => { + // this makes the coverage tool happy + test('should export devfile', () => { + expect(devfile).toBeDefined(); + }); +}); diff --git a/packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/metadata.spec.ts b/packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/metadata.spec.ts new file mode 100644 index 000000000..25bed2092 --- /dev/null +++ b/packages/dashboard-frontend/src/services/devfileApi/devfile/__tests__/metadata.spec.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2023 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 * as devfileMetadata from '@/services/devfileApi/devfile/metadata'; + +describe('devfile', () => { + // this makes the coverage tool happy + test('should export devfile', () => { + expect(devfileMetadata).toBeDefined(); + }); +}); From c40d3c4af9ef231d069371275b239e94c441868e Mon Sep 17 00:00:00 2001 From: Oleksii Kurinnyi Date: Mon, 4 Dec 2023 08:52:27 +0200 Subject: [PATCH 3/3] test: remove codecov flag --- .github/workflows/codecov.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index e241c7ecf..2ca49d851 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -43,4 +43,3 @@ jobs: uses: codecov/codecov-action@v3 with: files: ./packages/dashboard-frontend/coverage/lcov.info,./packages/dashboard-backend/coverage/lcov.info,./packages/common/coverage/lcov.info - flags: unittests