From 77cb3aa02b51240135dfcebe377d0bc6e2b97368 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Tue, 24 Oct 2023 11:56:11 +0200 Subject: [PATCH 1/3] Make ChecksCatalog component storybookable --- .../ChecksCatalog/ChecksCatalog.jsx | 39 +++--------- .../ChecksCatalog/ChecksCatalog.test.jsx | 59 +++++++------------ .../ChecksCatalog/ChecksCatalogPage.jsx | 37 ++++++++++++ assets/js/components/ChecksCatalog/index.js | 4 +- assets/js/trento.jsx | 4 +- 5 files changed, 72 insertions(+), 71 deletions(-) create mode 100644 assets/js/components/ChecksCatalog/ChecksCatalogPage.jsx diff --git a/assets/js/components/ChecksCatalog/ChecksCatalog.jsx b/assets/js/components/ChecksCatalog/ChecksCatalog.jsx index 674ccab6f8..bb8770b47d 100644 --- a/assets/js/components/ChecksCatalog/ChecksCatalog.jsx +++ b/assets/js/components/ChecksCatalog/ChecksCatalog.jsx @@ -1,14 +1,7 @@ -/* eslint-disable react/no-array-index-key */ -import React, { useState, useEffect } from 'react'; -import { useSelector, useDispatch } from 'react-redux'; +import React, { useEffect, useState } from 'react'; import { groupBy } from 'lodash'; -import { getCatalog } from '@state/selectors/catalog'; -import { updateCatalog } from '@state/actions/catalog'; -import { - providerData, - checkProviderExists, -} from '@components/ProviderLabel/ProviderLabel'; +import { providerData } from '@components/ProviderLabel/ProviderLabel'; import PageHeader from '@components/PageHeader'; import Accordion from '@components/Accordion'; import CatalogContainer from './CatalogContainer'; @@ -22,27 +15,13 @@ const updatedProvider = { ...providerData, }; -const buildUpdateCatalogAction = (provider) => { - const payload = checkProviderExists(provider) - ? { provider, target_type: 'cluster' } - : {}; - return updateCatalog(payload); -}; - -// eslint-disable-next-line import/prefer-default-export -function ChecksCatalog() { - const dispatch = useDispatch(); +function ChecksCatalog({ catalogData, catalogError, loading, updateCatalog }) { const [selectedProvider, setProviderSelected] = useState(ALL_FILTER); - const { - data: catalogData, - error: catalogError, - loading, - } = useSelector(getCatalog()); - useEffect(() => { - dispatch(buildUpdateCatalogAction(selectedProvider)); - }, [dispatch, selectedProvider]); + updateCatalog(selectedProvider); + }, [selectedProvider]); + return ( <>
@@ -55,15 +34,15 @@ function ChecksCatalog() { />
dispatch(buildUpdateCatalogAction(selectedProvider))} + onRefresh={() => updateCatalog(selectedProvider)} isCatalogEmpty={catalogData.length === 0} catalogError={catalogError} loading={loading} >
{Object.entries(groupBy(catalogData, 'group')).map( - ([group, checks], idx) => ( -
    + ([group, checks]) => ( +
      { - it('should render the checks catalog with fetched data', async () => { + it('should render the checks catalog with fetched data', () => { const groupName1 = faker.string.uuid(); const groupName2 = faker.string.uuid(); const group1 = catalogCheckFactory.buildList(5, { group: groupName1 }); const group2 = catalogCheckFactory.buildList(5, { group: groupName2 }); + const catalogData = group1.concat(group2); - const initialState = { - catalog: { loading: false, data: [...group1, ...group2], error: null }, - }; - const [statefulCatalog, store] = withState(, initialState); + const mockUpdateCatalog = jest.fn(); - await act(async () => renderWithRouter(statefulCatalog)); + render( + + ); - const groups = await waitFor(() => screen.getAllByRole('list')); + const groups = screen.getAllByRole('list'); expect(groups.length).toBe(2); groups.forEach((group) => { @@ -33,28 +35,21 @@ describe('ChecksCatalog ChecksCatalog component', () => { expect(checks.length).toBe(5); }); - const actions = store.getActions(); - const expectedActions = [ - { - type: 'UPDATE_CATALOG', - payload: {}, - }, - ]; - expect(actions).toEqual(expectedActions); + expect(mockUpdateCatalog).toHaveBeenCalledWith('all'); }); it('should query the catalog with the correct provider', async () => { const user = userEvent.setup(); - const catalog = catalogCheckFactory.buildList(5); + const catalogData = catalogCheckFactory.buildList(5); + const mockUpdateCatalog = jest.fn(); - const initialState = { - catalog: { loading: false, data: catalog, error: null }, - }; - - const [statefulCatalog, store] = withState(, initialState); - - await act(async () => renderWithRouter(statefulCatalog, store)); + render( + + ); await user.click(screen.getByText('All')); @@ -62,17 +57,7 @@ describe('ChecksCatalog ChecksCatalog component', () => { await user.click(providerFilter); - const actions = store.getActions(); - const expectedActions = [ - { - type: 'UPDATE_CATALOG', - payload: {}, - }, - { - type: 'UPDATE_CATALOG', - payload: { provider: 'aws', target_type: 'cluster' }, - }, - ]; - expect(actions).toEqual(expectedActions); + expect(mockUpdateCatalog).toHaveBeenNthCalledWith(1, 'all'); + expect(mockUpdateCatalog).toHaveBeenNthCalledWith(2, 'aws'); }); }); diff --git a/assets/js/components/ChecksCatalog/ChecksCatalogPage.jsx b/assets/js/components/ChecksCatalog/ChecksCatalogPage.jsx new file mode 100644 index 0000000000..9fc55ed685 --- /dev/null +++ b/assets/js/components/ChecksCatalog/ChecksCatalogPage.jsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; + +import { getCatalog } from '@state/selectors/catalog'; +import { updateCatalog } from '@state/actions/catalog'; +import { checkProviderExists } from '@components/ProviderLabel/ProviderLabel'; +import ChecksCatalog from './ChecksCatalog'; + +const buildUpdateCatalogAction = (provider) => { + const payload = checkProviderExists(provider) + ? { provider, target_type: 'cluster' } + : {}; + return updateCatalog(payload); +}; + +function ChecksCatalogPage() { + const dispatch = useDispatch(); + + const { + data: catalogData, + error: catalogError, + loading, + } = useSelector(getCatalog()); + + return ( + + dispatch(buildUpdateCatalogAction(selectedProvider)) + } + /> + ); +} + +export default ChecksCatalogPage; diff --git a/assets/js/components/ChecksCatalog/index.js b/assets/js/components/ChecksCatalog/index.js index e2133b19cf..bb26e502c3 100644 --- a/assets/js/components/ChecksCatalog/index.js +++ b/assets/js/components/ChecksCatalog/index.js @@ -1,3 +1,3 @@ -import ChecksCatalog from './ChecksCatalog'; +import ChecksCatalogPage from './ChecksCatalogPage'; -export default ChecksCatalog; +export default ChecksCatalogPage; diff --git a/assets/js/trento.jsx b/assets/js/trento.jsx index 573e4120e8..f7b20fe4a7 100644 --- a/assets/js/trento.jsx +++ b/assets/js/trento.jsx @@ -19,7 +19,7 @@ import { ExecutionResultsPage } from '@components/ExecutionResults'; import SapSystemsOverviewPage from '@components/SapSystemsOverview'; import HostDetailsPage, { HostSettingsPage } from '@components/HostDetails'; import DatabasesOverviewPage from '@components/DatabasesOverview'; -import ChecksCatalog from '@components/ChecksCatalog'; +import ChecksCatalogPage from '@components/ChecksCatalog'; import NotFound from '@components/NotFound'; import SomethingWentWrong from '@components/SomethingWentWrong'; import SaptuneDetailsPage from '@components/SaptuneDetails'; @@ -75,7 +75,7 @@ function App() { element={} /> } /> - } /> + } /> } /> } /> } /> From 5d744ff6f7f7825d9f5d6c9e1262194e88d4526f Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Tue, 24 Oct 2023 11:56:32 +0200 Subject: [PATCH 2/3] Add ChecksCatalog stories --- .../ChecksCatalog/ChecksCatalog.stories.jsx | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx diff --git a/assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx b/assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx new file mode 100644 index 0000000000..5f4de86c0f --- /dev/null +++ b/assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx @@ -0,0 +1,82 @@ +import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { faker } from '@faker-js/faker'; + +import { catalogCheckFactory } from '@lib/test-utils/factories'; +import ChecksCatalog from './ChecksCatalog'; + +const groupName1 = faker.string.uuid(); +const groupName2 = faker.string.uuid(); +const groupName3 = faker.string.uuid(); +const group1 = catalogCheckFactory.buildList(5, { group: groupName1 }); +const group2 = catalogCheckFactory.buildList(5, { group: groupName2 }); +const group3 = catalogCheckFactory.buildList(5, { group: groupName3 }); +const catalogData = group1.concat(group2).concat(group3); + +function ContainerWrapper({ children }) { + return ( +
      {children}
      + ); +} + +export default { + title: 'Layouts/ChecksCatalog', + component: ChecksCatalog, + argTypes: { + catalogData: { + control: 'object', + description: 'Catalog content', + }, + catalogError: { + control: 'text', + description: 'Error message getting catalog data', + table: { + type: { summary: 'string' }, + }, + }, + loading: { + control: { type: 'boolean' }, + description: 'Catalog data is being loaded', + table: { + type: { summary: 'string' }, + defaultValue: { summary: false }, + }, + }, + updateCatalog: { + action: 'Update catalog', + description: 'Update catalog content', + }, + }, + decorators: [ + (Story) => ( + + + + ), + ], + render: (args) => ( + + + + ), +}; + +export const Default = { + args: { + catalogData, + }, +}; + +export const Loading = { + args: { + ...Default.args, + loading: true, + }, +}; + +export const Error = { + args: { + ...Default.args, + catalogError: 'Error loading catalog', + }, +}; From 1baa1dbdc3e631bbdc0f26eb32e1e6d28c292f25 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 25 Oct 2023 09:55:32 +0200 Subject: [PATCH 3/3] Use concat function properly --- assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx b/assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx index 5f4de86c0f..a94faddfc2 100644 --- a/assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx +++ b/assets/js/components/ChecksCatalog/ChecksCatalog.stories.jsx @@ -11,7 +11,7 @@ const groupName3 = faker.string.uuid(); const group1 = catalogCheckFactory.buildList(5, { group: groupName1 }); const group2 = catalogCheckFactory.buildList(5, { group: groupName2 }); const group3 = catalogCheckFactory.buildList(5, { group: groupName3 }); -const catalogData = group1.concat(group2).concat(group3); +const catalogData = group1.concat(group2, group3); function ContainerWrapper({ children }) { return (