From a6186361809188cf7b0d9a9ac97af19841aa3392 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 2 Jun 2023 16:48:44 +0200 Subject: [PATCH] Add tests on Editable relation (#188) --- front/package.json | 4 +- .../__stories__/People.filterBy.stories.tsx | 13 ++-- .../__stories__/People.inputs.stories.tsx | 74 +++++++++++++++++-- .../__stories__/People.sortBy.stories.tsx | 27 ++++++- .../people/__stories__/People.stories.tsx | 5 +- front/src/pages/people/__stories__/shared.tsx | 36 --------- front/src/testing/graphqlMocks.ts | 14 +++- front/src/testing/mock-data/index.ts | 19 +++++ front/src/testing/mockedClient.ts | 10 --- 9 files changed, 133 insertions(+), 69 deletions(-) diff --git a/front/package.json b/front/package.json index b6dbe5530..ce4bef350 100644 --- a/front/package.json +++ b/front/package.json @@ -130,7 +130,7 @@ "workerDirectory": "public" }, "nyc": { - "lines": 60, - "statements": 60 + "lines": 65, + "statements": 65 } } diff --git a/front/src/pages/people/__stories__/People.filterBy.stories.tsx b/front/src/pages/people/__stories__/People.filterBy.stories.tsx index 3f72bba26..c1463c293 100644 --- a/front/src/pages/people/__stories__/People.filterBy.stories.tsx +++ b/front/src/pages/people/__stories__/People.filterBy.stories.tsx @@ -4,16 +4,17 @@ import { userEvent, within } from '@storybook/testing-library'; import People from '../People'; import { Story } from './People.stories'; -import { mocks, render } from './shared'; +import { render } from './shared'; +import { graphqlMocks } from '../../../testing/graphqlMocks'; const meta: Meta = { - title: 'Pages/People', + title: 'Pages/People/FilterBy', component: People, }; export default meta; -export const FilterByEmail: Story = { +export const Email: Story = { render, play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -36,11 +37,11 @@ export const FilterByEmail: Story = { expect(await canvas.findByText('Contains al')).toBeInTheDocument(); }, parameters: { - msw: mocks, + msw: graphqlMocks, }, }; -export const FilterByCompanyName: Story = { +export const CompanyName: Story = { render, play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -66,6 +67,6 @@ export const FilterByCompanyName: Story = { expect(await canvas.findByText('Is Qonto')).toBeInTheDocument(); }, parameters: { - msw: mocks, + msw: graphqlMocks, }, }; diff --git a/front/src/pages/people/__stories__/People.inputs.stories.tsx b/front/src/pages/people/__stories__/People.inputs.stories.tsx index d308fd777..68278c5b7 100644 --- a/front/src/pages/people/__stories__/People.inputs.stories.tsx +++ b/front/src/pages/people/__stories__/People.inputs.stories.tsx @@ -4,18 +4,22 @@ import { userEvent, within } from '@storybook/testing-library'; import People from '../People'; import { Story } from './People.stories'; -import { mocks, render } from './shared'; +import { render } from './shared'; import { mockedPeopleData } from '../../../testing/mock-data/people'; import { sleep } from '../../../testing/sleep'; +import { graphqlMocks } from '../../../testing/graphqlMocks'; +import { graphql } from 'msw'; +import { fetchOneFromData } from '../../../testing/mock-data'; +import { GraphqlQueryCompany } from '../../../interfaces/entities/company.interface'; const meta: Meta = { - title: 'Pages/People', + title: 'Pages/People/Input', component: People, }; export default meta; -export const ChangeEmail: Story = { +export const InteractWithManyRows: Story = { render, play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -55,16 +59,16 @@ export const ChangeEmail: Story = { ).toBeInTheDocument(); }, parameters: { - msw: mocks, + msw: graphqlMocks, }, }; -export const Checkbox: Story = { +export const CheckCheckboxes: Story = { render, play: async ({ canvasElement }) => { const canvas = within(canvasElement); - await sleep(500); + await canvas.findByText(mockedPeopleData[0].email); const inputCheckboxContainers = await canvas.findAllByTestId( 'input-checkbox-cell-container', @@ -86,6 +90,62 @@ export const Checkbox: Story = { expect(secondCheckbox.checked).toBe(false); }, parameters: { - msw: mocks, + msw: graphqlMocks, + }, +}; + +export const EditRelation: Story = { + render, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + const secondRowCompanyCell = await canvas.findByText( + mockedPeopleData[1].company.name, + ); + + await userEvent.click(secondRowCompanyCell); + + const relationInput = await canvas.findByPlaceholderText('Company'); + + await userEvent.type(relationInput, 'Air', { + delay: 200, + }); + + const airbnbChip = await canvas.findByText('Airbnb', { + selector: 'div > span', + }); + + await userEvent.click(airbnbChip); + + const newSecondRowCompanyCell = await canvas.findByText('Airbnb'); + + await userEvent.click(newSecondRowCompanyCell); + }, + parameters: { + actions: {}, + msw: [ + ...graphqlMocks.filter((graphqlMock) => { + return graphqlMock.info.operationName !== 'UpdatePeople'; + }), + ...[ + graphql.mutation('UpdatePeople', (req, res, ctx) => { + return res( + ctx.data({ + updateOnePerson: { + ...fetchOneFromData(mockedPeopleData, req.variables.id), + ...{ + company: { + id: req.variables.companyId, + name: 'Airbnb', + domainName: 'airbnb.com', + __typename: 'Company', + } satisfies GraphqlQueryCompany, + }, + }, + }), + ); + }), + ], + ], }, }; diff --git a/front/src/pages/people/__stories__/People.sortBy.stories.tsx b/front/src/pages/people/__stories__/People.sortBy.stories.tsx index ecfef9e56..065707af8 100644 --- a/front/src/pages/people/__stories__/People.sortBy.stories.tsx +++ b/front/src/pages/people/__stories__/People.sortBy.stories.tsx @@ -4,16 +4,17 @@ import { userEvent, within } from '@storybook/testing-library'; import People from '../People'; import { Story } from './People.stories'; -import { mocks, render } from './shared'; +import { render } from './shared'; +import { graphqlMocks } from '../../../testing/graphqlMocks'; const meta: Meta = { - title: 'Pages/People', + title: 'Pages/People/SortBy', component: People, }; export default meta; -export const SortByEmail: Story = { +export const Email: Story = { render, play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -33,6 +34,24 @@ export const SortByEmail: Story = { return item.getAttribute('id'); })[1], ).toStrictEqual('person-selected-7dfbc3f7-6e5e-4128-957e-8d86808cdf6b'); + }, + parameters: { + msw: graphqlMocks, + }, +}; + +export const Cancel: Story = { + render, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + const sortButton = canvas.getByText('Sort'); + await userEvent.click(sortButton); + + const emailSortButton = canvas.getByText('Email', { selector: 'li' }); + await userEvent.click(emailSortButton); + + expect(await canvas.getByTestId('remove-icon-email')).toBeInTheDocument(); const cancelButton = canvas.getByText('Cancel'); await userEvent.click(cancelButton); @@ -42,6 +61,6 @@ export const SortByEmail: Story = { ); }, parameters: { - msw: mocks, + msw: graphqlMocks, }, }; diff --git a/front/src/pages/people/__stories__/People.stories.tsx b/front/src/pages/people/__stories__/People.stories.tsx index 89bf61da3..ef9158703 100644 --- a/front/src/pages/people/__stories__/People.stories.tsx +++ b/front/src/pages/people/__stories__/People.stories.tsx @@ -2,7 +2,8 @@ import type { Meta, StoryObj } from '@storybook/react'; import People from '../People'; -import { render, mocks } from './shared'; +import { render } from './shared'; +import { graphqlMocks } from '../../../testing/graphqlMocks'; const meta: Meta = { title: 'Pages/People', @@ -16,6 +17,6 @@ export type Story = StoryObj; export const Default: Story = { render, parameters: { - msw: mocks, + msw: graphqlMocks, }, }; diff --git a/front/src/pages/people/__stories__/shared.tsx b/front/src/pages/people/__stories__/shared.tsx index 71cb1f462..9545a15cd 100644 --- a/front/src/pages/people/__stories__/shared.tsx +++ b/front/src/pages/people/__stories__/shared.tsx @@ -1,49 +1,13 @@ -import { graphql } from 'msw'; import { RecoilRoot } from 'recoil'; import { ThemeProvider } from '@emotion/react'; import { MemoryRouter } from 'react-router-dom'; import { ApolloProvider } from '@apollo/client'; -import { filterAndSortData } from '../../../testing/mock-data'; -import { mockedPeopleData } from '../../../testing/mock-data/people'; -import { mockedCompaniesData } from '../../../testing/mock-data/companies'; -import { GraphqlQueryCompany } from '../../../interfaces/entities/company.interface'; -import { GraphqlQueryPerson } from '../../../interfaces/entities/person.interface'; - import { lightTheme } from '../../../layout/styles/themes'; import { FullHeightStorybookLayout } from '../../../testing/FullHeightStorybookLayout'; import { mockedClient } from '../../../testing/mockedClient'; import People from '../People'; -export const mocks = [ - graphql.query('GetPeople', (req, res, ctx) => { - const returnedMockedData = filterAndSortData( - mockedPeopleData, - req.variables.where, - req.variables.orderBy, - req.variables.limit, - ); - return res( - ctx.data({ - people: returnedMockedData, - }), - ); - }), - graphql.query('SearchCompanyQuery', (req, res, ctx) => { - const returnedMockedData = filterAndSortData( - mockedCompaniesData, - req.variables.where, - req.variables.orderBy, - req.variables.limit, - ); - return res( - ctx.data({ - searchResults: returnedMockedData, - }), - ); - }), -]; - export function render() { return ( diff --git a/front/src/testing/graphqlMocks.ts b/front/src/testing/graphqlMocks.ts index 421cd5dc6..270d477b4 100644 --- a/front/src/testing/graphqlMocks.ts +++ b/front/src/testing/graphqlMocks.ts @@ -1,5 +1,5 @@ import { graphql } from 'msw'; -import { filterAndSortData } from './mock-data'; +import { filterAndSortData, updateOneFromData } from './mock-data'; import { GraphqlQueryCompany } from '../interfaces/entities/company.interface'; import { mockedCompaniesData } from './mock-data/companies'; import { GraphqlQueryUser } from '../interfaces/entities/user.interface'; @@ -61,7 +61,6 @@ export const graphqlMocks = [ req.variables.orderBy, req.variables.limit, ); - console.log({ returnedMockedData }); return res( ctx.data({ users: returnedMockedData, @@ -81,4 +80,15 @@ export const graphqlMocks = [ }), ); }), + graphql.mutation('UpdatePeople', (req, res, ctx) => { + return res( + ctx.data({ + updateOnePerson: updateOneFromData( + mockedPeopleData, + req.variables.id, + req.variables, + ), + }), + ); + }), ]; diff --git a/front/src/testing/mock-data/index.ts b/front/src/testing/mock-data/index.ts index a728a813c..358991f86 100644 --- a/front/src/testing/mock-data/index.ts +++ b/front/src/testing/mock-data/index.ts @@ -1,3 +1,4 @@ +import { GraphQLVariables } from 'msw'; import { CompanyOrderByWithRelationInput, PersonOrderByWithRelationInput, @@ -112,3 +113,21 @@ export function filterAndSortData( return filteredData; } + +export function fetchOneFromData( + data: Array, + id: string, +): DataT | undefined { + return data.filter((item) => item.id === id)[0]; +} + +export function updateOneFromData( + data: Array, + id: string, + payload: GraphQLVariables, +): DataT | undefined { + const object = data.filter((item) => item.id === id)[0]; + const newObject = Object.assign(object, payload); + + return newObject; +} diff --git a/front/src/testing/mockedClient.ts b/front/src/testing/mockedClient.ts index 10fafb6c1..64448ab47 100644 --- a/front/src/testing/mockedClient.ts +++ b/front/src/testing/mockedClient.ts @@ -3,14 +3,4 @@ import { ApolloClient, InMemoryCache } from '@apollo/client'; export const mockedClient = new ApolloClient({ uri: process.env.REACT_APP_API_URL, cache: new InMemoryCache(), - defaultOptions: { - watchQuery: { - fetchPolicy: 'no-cache', - errorPolicy: 'all', - }, - query: { - fetchPolicy: 'no-cache', - errorPolicy: 'all', - }, - }, });