Add tests on Editable relation (#188)

This commit is contained in:
Charles Bochet 2023-06-02 16:48:44 +02:00 committed by GitHub
parent 97274db8b4
commit a618636180
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 133 additions and 69 deletions

View File

@ -130,7 +130,7 @@
"workerDirectory": "public"
},
"nyc": {
"lines": 60,
"statements": 60
"lines": 65,
"statements": 65
}
}

View File

@ -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<typeof People> = {
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,
},
};

View File

@ -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<typeof People> = {
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,
},
},
}),
);
}),
],
],
},
};

View File

@ -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<typeof People> = {
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,
},
};

View File

@ -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<typeof People> = {
title: 'Pages/People',
@ -16,6 +17,6 @@ export type Story = StoryObj<typeof People>;
export const Default: Story = {
render,
parameters: {
msw: mocks,
msw: graphqlMocks,
},
};

View File

@ -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<GraphqlQueryPerson>(
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<GraphqlQueryCompany>(
mockedCompaniesData,
req.variables.where,
req.variables.orderBy,
req.variables.limit,
);
return res(
ctx.data({
searchResults: returnedMockedData,
}),
);
}),
];
export function render() {
return (
<RecoilRoot>

View File

@ -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,
),
}),
);
}),
];

View File

@ -1,3 +1,4 @@
import { GraphQLVariables } from 'msw';
import {
CompanyOrderByWithRelationInput,
PersonOrderByWithRelationInput,
@ -112,3 +113,21 @@ export function filterAndSortData<DataT>(
return filteredData;
}
export function fetchOneFromData<DataT extends { id: string }>(
data: Array<DataT>,
id: string,
): DataT | undefined {
return data.filter((item) => item.id === id)[0];
}
export function updateOneFromData<DataT extends { id: string }>(
data: Array<DataT>,
id: string,
payload: GraphQLVariables,
): DataT | undefined {
const object = data.filter((item) => item.id === id)[0];
const newObject = Object.assign(object, payload);
return newObject;
}

View File

@ -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',
},
},
});