From 46dffeadefbbd580e97d6fb3509b94cc3d83d0ba Mon Sep 17 00:00:00 2001 From: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:26:06 +0200 Subject: [PATCH] Adding storybook tests on meta-types/display/components (#1862) * working on a story for MoneyFieldDisplay * Write test on MoneyDisplayField --- .../modules/ui/field/contexts/FieldContext.ts | 2 +- .../FieldDisplayContextProvider.tsx | 35 ++++++ .../__stories__/MoneyFieldDisplay.stories.tsx | 112 ++++++++++++++++++ .../src/testing/ComponentStorybookLayout.tsx | 14 ++- .../testing/decorators/CatalogDecorator.tsx | 54 +++++---- .../testing/decorators/ComponentDecorator.tsx | 14 ++- 6 files changed, 196 insertions(+), 35 deletions(-) create mode 100644 front/src/modules/ui/field/meta-types/display/components/__stories__/FieldDisplayContextProvider.tsx create mode 100644 front/src/modules/ui/field/meta-types/display/components/__stories__/MoneyFieldDisplay.stories.tsx diff --git a/front/src/modules/ui/field/contexts/FieldContext.ts b/front/src/modules/ui/field/contexts/FieldContext.ts index cc11d549a..ebd651efa 100644 --- a/front/src/modules/ui/field/contexts/FieldContext.ts +++ b/front/src/modules/ui/field/contexts/FieldContext.ts @@ -3,7 +3,7 @@ import { createContext } from 'react'; import { FieldDefinition } from '../types/FieldDefinition'; import { FieldMetadata } from '../types/FieldMetadata'; -type GenericFieldContextType = { +export type GenericFieldContextType = { fieldDefinition: FieldDefinition; // TODO: add better typing for mutation hook useUpdateEntityMutation: () => [(params: any) => void, any]; diff --git a/front/src/modules/ui/field/meta-types/display/components/__stories__/FieldDisplayContextProvider.tsx b/front/src/modules/ui/field/meta-types/display/components/__stories__/FieldDisplayContextProvider.tsx new file mode 100644 index 000000000..4e06f2bf2 --- /dev/null +++ b/front/src/modules/ui/field/meta-types/display/components/__stories__/FieldDisplayContextProvider.tsx @@ -0,0 +1,35 @@ +import { + FieldContext, + GenericFieldContextType, +} from '@/ui/field/contexts/FieldContext'; + +type FieldDisplayContextProviderProps = { + children: React.ReactNode; + fieldDefinition: GenericFieldContextType['fieldDefinition']; + entityId?: string; +}; + +export const FieldDisplayContextProvider = ({ + children, + fieldDefinition, + entityId, +}: FieldDisplayContextProviderProps) => { + return ( + [ + () => { + return; + }, + {}, + ], + }} + > + {children} + + ); +}; diff --git a/front/src/modules/ui/field/meta-types/display/components/__stories__/MoneyFieldDisplay.stories.tsx b/front/src/modules/ui/field/meta-types/display/components/__stories__/MoneyFieldDisplay.stories.tsx new file mode 100644 index 000000000..b9a1a1af0 --- /dev/null +++ b/front/src/modules/ui/field/meta-types/display/components/__stories__/MoneyFieldDisplay.stories.tsx @@ -0,0 +1,112 @@ +import { useEffect } from 'react'; +import { Meta, StoryObj } from '@storybook/react'; +import { v4 } from 'uuid'; + +import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator'; +import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; +import { CatalogStory } from '~/testing/types'; + +import { useMoneyField } from '../../../hooks/useMoneyField'; +import { MoneyFieldDisplay } from '../MoneyFieldDisplay'; + +import { FieldDisplayContextProvider } from './FieldDisplayContextProvider'; + +const MoneyFieldValueSetterEffect = ({ value }: { value: number }) => { + const { setFieldValue } = useMoneyField(); + + useEffect(() => { + setFieldValue(value); + }, [setFieldValue, value]); + + return <>; +}; + +type MoneyFieldDisplayWithContextProps = { + value: number; + entityId?: string; +}; + +const MoneyFieldDisplayWithContext = ({ + value, + entityId, +}: MoneyFieldDisplayWithContextProps) => { + return ( + + + + + ); +}; + +const meta: Meta = { + title: 'UI/Field/MoneyFieldDisplay', + component: MoneyFieldDisplayWithContext, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + value: 100, + }, +}; + +export const Elipsis: Story = { + args: { + value: 1e100, + }, + argTypes: { + value: { control: false }, + }, + parameters: { + container: { + width: 100, + }, + }, + decorators: [ComponentDecorator], +}; + +export const Catalog: CatalogStory = + { + argTypes: { + value: { control: false }, + }, + parameters: { + catalog: { + dimensions: [ + { + name: 'currency', + values: ['$'] satisfies string[], + props: (_value: string) => ({}), + }, + { + name: 'value', + values: [ + 100, 1000, -1000, 1e10, 1.357802, -1.283, 0, + ] satisfies number[], + props: (value: number) => ({ value, entityId: v4() }), + }, + ], + options: { + elementContainer: { + width: 100, + }, + }, + }, + }, + decorators: [CatalogDecorator], + }; diff --git a/front/src/testing/ComponentStorybookLayout.tsx b/front/src/testing/ComponentStorybookLayout.tsx index 984099497..91b6b390d 100644 --- a/front/src/testing/ComponentStorybookLayout.tsx +++ b/front/src/testing/ComponentStorybookLayout.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; -const StyledLayout = styled.div` +const StyledLayout = styled.div<{ width?: number }>` background: ${({ theme }) => theme.background.primary}; border: 1px solid ${({ theme }) => theme.border.color.light}; border-radius: 5px; @@ -12,13 +12,17 @@ const StyledLayout = styled.div` max-width: calc(100% - 40px); min-width: 300px; padding: 20px; - width: fit-content; + width: ${({ width }) => (width ? width + 'px' : 'fit-content')}; `; -type OwnProps = { +type ComponentStorybookLayoutProps = { + width?: number; children: JSX.Element; }; -export const ComponentStorybookLayout = ({ children }: OwnProps) => ( - {children} +export const ComponentStorybookLayout = ({ + width, + children, +}: ComponentStorybookLayoutProps) => ( + {children} ); diff --git a/front/src/testing/decorators/CatalogDecorator.tsx b/front/src/testing/decorators/CatalogDecorator.tsx index 9f98e8ce6..b510c36f9 100644 --- a/front/src/testing/decorators/CatalogDecorator.tsx +++ b/front/src/testing/decorators/CatalogDecorator.tsx @@ -108,41 +108,47 @@ export const CatalogDecorator: Decorator = (Story, context) => { {dimension4.labels?.(value4) ?? - (typeof value4 === 'string' ? value4 : '')} + (['string', 'number'].includes(typeof value4) ? value4 : '')} {dimension3.values.map((value3: any) => ( {dimension3.labels?.(value3) ?? - (typeof value3 === 'string' ? value3 : '')} + (['string', 'number'].includes(typeof value3) ? value3 : '')} {dimension2.values.map((value2: any) => ( {dimension2.labels?.(value2) ?? - (typeof value2 === 'string' ? value2 : '')} + (['string', 'number'].includes(typeof value2) + ? value2 + : '')} - {dimension1.values.map((value1: any) => ( - - - {dimension1.labels?.(value1) ?? - (typeof value1 === 'string' ? value1 : '')} - - - - - - ))} + {dimension1.values.map((value1: any) => { + return ( + + + {dimension1.labels?.(value1) ?? + (['string', 'number'].includes(typeof value1) + ? value1 + : '')} + + + + + + ); + })} ))} diff --git a/front/src/testing/decorators/ComponentDecorator.tsx b/front/src/testing/decorators/ComponentDecorator.tsx index df87f484d..70fa9051a 100644 --- a/front/src/testing/decorators/ComponentDecorator.tsx +++ b/front/src/testing/decorators/ComponentDecorator.tsx @@ -2,8 +2,12 @@ import { Decorator } from '@storybook/react'; import { ComponentStorybookLayout } from '../ComponentStorybookLayout'; -export const ComponentDecorator: Decorator = (Story) => ( - - - -); +export const ComponentDecorator: Decorator = (Story, context) => { + const { container } = context.parameters; + + return ( + + + + ); +};