Add tests on companies page (#155)
This commit is contained in:
7
.github/workflows/ci.yaml
vendored
7
.github/workflows/ci.yaml
vendored
@ -38,8 +38,11 @@ jobs:
|
|||||||
run: cd front && npm run lint
|
run: cd front && npm run lint
|
||||||
- name: Build Storybook
|
- name: Build Storybook
|
||||||
run: cd front && npm run build-storybook --quiet
|
run: cd front && npm run build-storybook --quiet
|
||||||
- name: Serve Storybook and run tests
|
- name: Serve Storybook and run storybook tests
|
||||||
run: |
|
run: |
|
||||||
cd front && npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
|
cd front && npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
|
||||||
"npx http-server storybook-static --silent --port 6006" \
|
"npx http-server storybook-static --silent --port 6006" \
|
||||||
"npm run coverage"
|
"npm run coverage"
|
||||||
|
- name: run jest tests
|
||||||
|
run: |
|
||||||
|
cd front && npm run test
|
||||||
@ -33,7 +33,7 @@
|
|||||||
"storybook": "storybook dev -p 6006 -s ../public",
|
"storybook": "storybook dev -p 6006 -s ../public",
|
||||||
"test-storybook": "test-storybook",
|
"test-storybook": "test-storybook",
|
||||||
"build-storybook": "storybook build -s public",
|
"build-storybook": "storybook build -s public",
|
||||||
"coverage": "test-storybook --coverage && npx nyc report --reporter=lcov -t coverage/storybook --report-dir coverage/storybook --check-coverage --lines 50",
|
"coverage": "test-storybook --coverage && npx nyc report --reporter=lcov -t coverage/storybook --report-dir coverage/storybook --check-coverage",
|
||||||
"graphql:generate": "REACT_APP_GRAPHQL_ADMIN_SECRET=$REACT_APP_GRAPHQL_ADMIN_SECRET graphql-codegen --config codegen.js"
|
"graphql:generate": "REACT_APP_GRAPHQL_ADMIN_SECRET=$REACT_APP_GRAPHQL_ADMIN_SECRET graphql-codegen --config codegen.js"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
@ -122,5 +122,9 @@
|
|||||||
},
|
},
|
||||||
"msw": {
|
"msw": {
|
||||||
"workerDirectory": "public"
|
"workerDirectory": "public"
|
||||||
|
},
|
||||||
|
"nyc": {
|
||||||
|
"lines": 60,
|
||||||
|
"statements": 60
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,7 +60,7 @@ function SortAndFilterBar<SortField, TData extends FilterableFieldsType>({
|
|||||||
key={sort.key}
|
key={sort.key}
|
||||||
labelValue={sort.label}
|
labelValue={sort.label}
|
||||||
id={sort.key}
|
id={sort.key}
|
||||||
icon={sort.order === 'asc' ? <FaArrowDown /> : <FaArrowUp />}
|
icon={sort.order === 'desc' ? <FaArrowDown /> : <FaArrowUp />}
|
||||||
onRemove={() => onRemoveSort(sort.key)}
|
onRemove={() => onRemoveSort(sort.key)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export type GraphqlMutationUser = {
|
|||||||
id: string;
|
id: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
workspaceMember_id?: string;
|
workspaceMemberId?: string;
|
||||||
__typename: string;
|
__typename: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,6 +42,6 @@ export const mapToGqlUser = (user: User): GraphqlMutationUser => ({
|
|||||||
id: user.id,
|
id: user.id,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
displayName: user.displayName,
|
displayName: user.displayName,
|
||||||
workspaceMember_id: user.workspaceMember?.id,
|
workspaceMemberId: user.workspaceMember?.id,
|
||||||
__typename: 'users',
|
__typename: 'users',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,74 @@
|
|||||||
|
import { expect } from '@storybook/jest';
|
||||||
|
import type { Meta } from '@storybook/react';
|
||||||
|
import { userEvent, within } from '@storybook/testing-library';
|
||||||
|
|
||||||
|
import Companies from '../Companies';
|
||||||
|
import { Story } from './Companies.stories';
|
||||||
|
import { mocks, render } from './shared';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Companies> = {
|
||||||
|
title: 'Pages/Companies',
|
||||||
|
component: Companies,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export const FilterByName: Story = {
|
||||||
|
render,
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const filterButton = canvas.getByText('Filter');
|
||||||
|
await userEvent.click(filterButton);
|
||||||
|
|
||||||
|
const nameFilterButton = canvas.getByText('Name', { selector: 'li' });
|
||||||
|
await userEvent.click(nameFilterButton);
|
||||||
|
|
||||||
|
const nameInput = canvas.getByPlaceholderText('Name');
|
||||||
|
await userEvent.type(nameInput, 'Air', {
|
||||||
|
delay: 200,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Airbnb')).toBeInTheDocument();
|
||||||
|
expect(await canvas.findByText('Aircall')).toBeInTheDocument();
|
||||||
|
await expect(canvas.queryAllByText('Qonto')).toStrictEqual([]);
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Name:')).toBeInTheDocument();
|
||||||
|
expect(await canvas.findByText('Contains Air')).toBeInTheDocument();
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
msw: mocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FilterByAccountOwner: Story = {
|
||||||
|
render,
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const filterButton = canvas.getByText('Filter');
|
||||||
|
await userEvent.click(filterButton);
|
||||||
|
|
||||||
|
const accountOwnerFilterButton = canvas.getByText('Account Owner', {
|
||||||
|
selector: 'li',
|
||||||
|
});
|
||||||
|
await userEvent.click(accountOwnerFilterButton);
|
||||||
|
|
||||||
|
const accountOwnerNameInput = canvas.getByPlaceholderText('Account Owner');
|
||||||
|
await userEvent.type(accountOwnerNameInput, 'Char', {
|
||||||
|
delay: 200,
|
||||||
|
});
|
||||||
|
|
||||||
|
const charlesChip = canvas.getByText('Charles Test', { selector: 'li' });
|
||||||
|
await userEvent.click(charlesChip);
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Airbnb')).toBeInTheDocument();
|
||||||
|
await expect(canvas.queryAllByText('Qonto')).toStrictEqual([]);
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Account Owner:')).toBeInTheDocument();
|
||||||
|
expect(await canvas.findByText('Is Charles Test')).toBeInTheDocument();
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
msw: mocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
11
front/src/pages/companies/__stories__/Companies.mdx
Normal file
11
front/src/pages/companies/__stories__/Companies.mdx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{ /* Companies.mdx */ }
|
||||||
|
|
||||||
|
import { Canvas, Meta } from '@storybook/blocks';
|
||||||
|
|
||||||
|
import * as Companies from './Companies.stories';
|
||||||
|
|
||||||
|
<Meta of={Companies} />
|
||||||
|
|
||||||
|
# Companies View
|
||||||
|
|
||||||
|
<Canvas of={Companies.Default} />
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
import { expect } from '@storybook/jest';
|
||||||
|
import type { Meta } from '@storybook/react';
|
||||||
|
import { userEvent, within } from '@storybook/testing-library';
|
||||||
|
|
||||||
|
import Companies from '../Companies';
|
||||||
|
import { Story } from './Companies.stories';
|
||||||
|
import { mocks, render } from './shared';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Companies> = {
|
||||||
|
title: 'Pages/Companies',
|
||||||
|
component: Companies,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export const SortByName: Story = {
|
||||||
|
render,
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const sortButton = canvas.getByText('Sort');
|
||||||
|
await userEvent.click(sortButton);
|
||||||
|
|
||||||
|
const nameSortButton = canvas.getByText('Name', { selector: 'li' });
|
||||||
|
await userEvent.click(nameSortButton);
|
||||||
|
|
||||||
|
expect(await canvas.getByTestId('remove-icon-name')).toBeInTheDocument();
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Airbnb')).toBeInTheDocument();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
(await canvas.findAllByRole('checkbox')).map((item) => {
|
||||||
|
return item.getAttribute('id');
|
||||||
|
})[1],
|
||||||
|
).toStrictEqual('company-selected-89bb825c-171e-4bcc-9cf7-43448d6fb278');
|
||||||
|
|
||||||
|
const cancelButton = canvas.getByText('Cancel');
|
||||||
|
await userEvent.click(cancelButton);
|
||||||
|
|
||||||
|
await expect(canvas.queryAllByTestId('remove-icon-name')).toStrictEqual([]);
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
msw: mocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
21
front/src/pages/companies/__stories__/Companies.stories.tsx
Normal file
21
front/src/pages/companies/__stories__/Companies.stories.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
|
import Companies from '../Companies';
|
||||||
|
|
||||||
|
import { render, mocks } from './shared';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Companies> = {
|
||||||
|
title: 'Pages/Companies',
|
||||||
|
component: Companies,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export type Story = StoryObj<typeof Companies>;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
render,
|
||||||
|
parameters: {
|
||||||
|
msw: mocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
61
front/src/pages/companies/__stories__/shared.tsx
Normal file
61
front/src/pages/companies/__stories__/shared.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
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 { mockedCompaniesData } from '../../../testing/mock-data/companies';
|
||||||
|
import { GraphqlQueryCompany } from '../../../interfaces/entities/company.interface';
|
||||||
|
|
||||||
|
import { lightTheme } from '../../../layout/styles/themes';
|
||||||
|
import { FullHeightStorybookLayout } from '../../../testing/FullHeightStorybookLayout';
|
||||||
|
import { mockedClient } from '../../../testing/mockedClient';
|
||||||
|
import Companies from '../Companies';
|
||||||
|
import { GraphqlQueryUser } from '../../../interfaces/entities/user.interface';
|
||||||
|
import { mockedUsersData } from '../../../testing/mock-data/users';
|
||||||
|
|
||||||
|
export const mocks = [
|
||||||
|
graphql.query('GetCompanies', (req, res, ctx) => {
|
||||||
|
const returnedMockedData = filterAndSortData<GraphqlQueryCompany>(
|
||||||
|
mockedCompaniesData,
|
||||||
|
req.variables.where,
|
||||||
|
req.variables.orderBy,
|
||||||
|
req.variables.limit,
|
||||||
|
);
|
||||||
|
return res(
|
||||||
|
ctx.data({
|
||||||
|
companies: returnedMockedData,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
graphql.query('SearchUserQuery', (req, res, ctx) => {
|
||||||
|
const returnedMockedData = filterAndSortData<GraphqlQueryUser>(
|
||||||
|
mockedUsersData,
|
||||||
|
req.variables.where,
|
||||||
|
req.variables.orderBy,
|
||||||
|
req.variables.limit,
|
||||||
|
);
|
||||||
|
return res(
|
||||||
|
ctx.data({
|
||||||
|
searchResults: returnedMockedData,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
export function render() {
|
||||||
|
return (
|
||||||
|
<RecoilRoot>
|
||||||
|
<ApolloProvider client={mockedClient}>
|
||||||
|
<ThemeProvider theme={lightTheme}>
|
||||||
|
<MemoryRouter>
|
||||||
|
<FullHeightStorybookLayout>
|
||||||
|
<Companies />
|
||||||
|
</FullHeightStorybookLayout>
|
||||||
|
</MemoryRouter>
|
||||||
|
</ThemeProvider>
|
||||||
|
</ApolloProvider>
|
||||||
|
</RecoilRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -14,7 +14,7 @@ import { QueryMode } from '../../generated/graphql';
|
|||||||
|
|
||||||
export const nameFilter = {
|
export const nameFilter = {
|
||||||
key: 'name',
|
key: 'name',
|
||||||
label: 'Company',
|
label: 'Name',
|
||||||
icon: <TbBuilding size={16} />,
|
icon: <TbBuilding size={16} />,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
operands: [
|
operands: [
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
import { expect } from '@storybook/jest';
|
||||||
|
import type { Meta } from '@storybook/react';
|
||||||
|
import { userEvent, within } from '@storybook/testing-library';
|
||||||
|
|
||||||
|
import People from '../People';
|
||||||
|
import { Story } from './People.stories';
|
||||||
|
import { mocks, render } from './shared';
|
||||||
|
|
||||||
|
const meta: Meta<typeof People> = {
|
||||||
|
title: 'Pages/People',
|
||||||
|
component: People,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export const FilterByEmail: Story = {
|
||||||
|
render,
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const filterButton = canvas.getByText('Filter');
|
||||||
|
await userEvent.click(filterButton);
|
||||||
|
|
||||||
|
const emailFilterButton = canvas.getByText('Email', { selector: 'li' });
|
||||||
|
await userEvent.click(emailFilterButton);
|
||||||
|
|
||||||
|
const emailInput = canvas.getByPlaceholderText('Email');
|
||||||
|
await userEvent.type(emailInput, 'al', {
|
||||||
|
delay: 200,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Alexandre Prot')).toBeInTheDocument();
|
||||||
|
await expect(canvas.queryAllByText('John Doe')).toStrictEqual([]);
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Email:')).toBeInTheDocument();
|
||||||
|
expect(await canvas.findByText('Contains al')).toBeInTheDocument();
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
msw: mocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FilterByCompanyName: Story = {
|
||||||
|
render,
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const filterButton = canvas.getByText('Filter');
|
||||||
|
await userEvent.click(filterButton);
|
||||||
|
|
||||||
|
const companyFilterButton = canvas.getByText('Company', { selector: 'li' });
|
||||||
|
await userEvent.click(companyFilterButton);
|
||||||
|
|
||||||
|
const companyNameInput = canvas.getByPlaceholderText('Company');
|
||||||
|
await userEvent.type(companyNameInput, 'Qon', {
|
||||||
|
delay: 200,
|
||||||
|
});
|
||||||
|
|
||||||
|
const qontoChip = canvas.getByText('Qonto', { selector: 'li' });
|
||||||
|
await userEvent.click(qontoChip);
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Alexandre Prot')).toBeInTheDocument();
|
||||||
|
await expect(canvas.queryAllByText('John Doe')).toStrictEqual([]);
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Company:')).toBeInTheDocument();
|
||||||
|
expect(await canvas.findByText('Is Qonto')).toBeInTheDocument();
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
msw: mocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
47
front/src/pages/people/__stories__/People.sortBy.stories.tsx
Normal file
47
front/src/pages/people/__stories__/People.sortBy.stories.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { expect } from '@storybook/jest';
|
||||||
|
import type { Meta } from '@storybook/react';
|
||||||
|
import { userEvent, within } from '@storybook/testing-library';
|
||||||
|
|
||||||
|
import People from '../People';
|
||||||
|
import { Story } from './People.stories';
|
||||||
|
import { mocks, render } from './shared';
|
||||||
|
|
||||||
|
const meta: Meta<typeof People> = {
|
||||||
|
title: 'Pages/People',
|
||||||
|
component: People,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export const SortByEmail: 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();
|
||||||
|
|
||||||
|
expect(await canvas.findByText('Alexandre Prot')).toBeInTheDocument();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
(await canvas.findAllByRole('checkbox')).map((item) => {
|
||||||
|
return item.getAttribute('id');
|
||||||
|
})[1],
|
||||||
|
).toStrictEqual('person-selected-7dfbc3f7-6e5e-4128-957e-8d86808cdf6b');
|
||||||
|
|
||||||
|
const cancelButton = canvas.getByText('Cancel');
|
||||||
|
await userEvent.click(cancelButton);
|
||||||
|
|
||||||
|
await expect(canvas.queryAllByTestId('remove-icon-email')).toStrictEqual(
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
msw: mocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -1,113 +1,21 @@
|
|||||||
import { expect } from '@storybook/jest';
|
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
import { RecoilRoot } from 'recoil';
|
|
||||||
import { ThemeProvider } from '@emotion/react';
|
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
|
||||||
import { graphql } from 'msw';
|
|
||||||
import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
|
|
||||||
import { userEvent, within } from '@storybook/testing-library';
|
|
||||||
|
|
||||||
import People from '../People';
|
import People from '../People';
|
||||||
import { lightTheme } from '../../../layout/styles/themes';
|
|
||||||
import { FullHeightStorybookLayout } from '../../../testing/FullHeightStorybookLayout';
|
import { render, mocks } from './shared';
|
||||||
import { filterAndSortData } from '../../../testing/mock-data';
|
|
||||||
import { GraphqlQueryPerson } from '../../../interfaces/entities/person.interface';
|
|
||||||
import { mockedPeopleData } from '../../../testing/mock-data/people';
|
|
||||||
import { GraphqlQueryCompany } from '../../../interfaces/entities/company.interface';
|
|
||||||
import { mockCompaniesData } from '../../../testing/mock-data/companies';
|
|
||||||
|
|
||||||
const meta: Meta<typeof People> = {
|
const meta: Meta<typeof People> = {
|
||||||
title: 'Pages/People',
|
title: 'Pages/People',
|
||||||
component: People,
|
component: People,
|
||||||
};
|
};
|
||||||
|
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof People>;
|
|
||||||
|
|
||||||
const render = () => (
|
export type Story = StoryObj<typeof People>;
|
||||||
<RecoilRoot>
|
|
||||||
<ApolloProvider client={mockedClient}>
|
|
||||||
<ThemeProvider theme={lightTheme}>
|
|
||||||
<MemoryRouter>
|
|
||||||
<FullHeightStorybookLayout>
|
|
||||||
<People />
|
|
||||||
</FullHeightStorybookLayout>
|
|
||||||
</MemoryRouter>
|
|
||||||
</ThemeProvider>
|
|
||||||
</ApolloProvider>
|
|
||||||
</RecoilRoot>
|
|
||||||
);
|
|
||||||
|
|
||||||
const defaultMocks = [
|
|
||||||
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('SearchQuery', (req, res, ctx) => {
|
|
||||||
const returnedMockedData = filterAndSortData<GraphqlQueryCompany>(
|
|
||||||
mockCompaniesData,
|
|
||||||
req.variables.where,
|
|
||||||
req.variables.orderBy,
|
|
||||||
req.variables.limit,
|
|
||||||
);
|
|
||||||
return res(
|
|
||||||
ctx.data({
|
|
||||||
searchResults: returnedMockedData,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
|
|
||||||
export const Default: Story = {
|
export const Default: Story = {
|
||||||
render,
|
render,
|
||||||
parameters: {
|
parameters: {
|
||||||
msw: defaultMocks,
|
msw: mocks,
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const FilterByEmail: Story = {
|
|
||||||
render,
|
|
||||||
play: async ({ canvasElement }) => {
|
|
||||||
const canvas = within(canvasElement);
|
|
||||||
|
|
||||||
const filterButton = canvas.getByText('Filter');
|
|
||||||
await userEvent.click(filterButton);
|
|
||||||
|
|
||||||
const emailFilterButton = canvas.getByText('Email', { selector: 'li' });
|
|
||||||
await userEvent.click(emailFilterButton);
|
|
||||||
|
|
||||||
const emailInput = canvas.getByPlaceholderText('Email');
|
|
||||||
await userEvent.type(emailInput, 'al', {
|
|
||||||
delay: 200,
|
|
||||||
});
|
|
||||||
|
|
||||||
await expect(canvas.queryAllByText('John')).toStrictEqual([]);
|
|
||||||
},
|
|
||||||
parameters: {
|
|
||||||
msw: defaultMocks,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
61
front/src/pages/people/__stories__/shared.tsx
Normal file
61
front/src/pages/people/__stories__/shared.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
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>
|
||||||
|
<ApolloProvider client={mockedClient}>
|
||||||
|
<ThemeProvider theme={lightTheme}>
|
||||||
|
<MemoryRouter>
|
||||||
|
<FullHeightStorybookLayout>
|
||||||
|
<People />
|
||||||
|
</FullHeightStorybookLayout>
|
||||||
|
</MemoryRouter>
|
||||||
|
</ThemeProvider>
|
||||||
|
</ApolloProvider>
|
||||||
|
</RecoilRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -40,7 +40,7 @@ export const EMPTY_QUERY = gql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const SEARCH_COMPANY_QUERY = gql`
|
export const SEARCH_COMPANY_QUERY = gql`
|
||||||
query SearchQuery($where: CompanyWhereInput, $limit: Int) {
|
query SearchCompanyQuery($where: CompanyWhereInput, $limit: Int) {
|
||||||
searchResults: companies(where: $where, take: $limit) {
|
searchResults: companies(where: $where, take: $limit) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { GraphqlQueryCompany } from '../../interfaces/entities/company.interface';
|
import { GraphqlQueryCompany } from '../../interfaces/entities/company.interface';
|
||||||
|
|
||||||
export const mockCompaniesData: Array<GraphqlQueryCompany> = [
|
export const mockedCompaniesData: Array<GraphqlQueryCompany> = [
|
||||||
{
|
{
|
||||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb278',
|
id: '89bb825c-171e-4bcc-9cf7-43448d6fb278',
|
||||||
domainName: 'airbnb.com',
|
domainName: 'airbnb.com',
|
||||||
@ -8,7 +8,12 @@ export const mockCompaniesData: Array<GraphqlQueryCompany> = [
|
|||||||
createdAt: '2023-04-26T10:08:54.724515+00:00',
|
createdAt: '2023-04-26T10:08:54.724515+00:00',
|
||||||
address: '17 rue de clignancourt',
|
address: '17 rue de clignancourt',
|
||||||
employees: 12,
|
employees: 12,
|
||||||
accountOwner: null,
|
accountOwner: {
|
||||||
|
email: 'charles@test.com',
|
||||||
|
displayName: 'Charles Test',
|
||||||
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||||
|
__typename: 'users',
|
||||||
|
},
|
||||||
__typename: 'companies',
|
__typename: 'companies',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,7 +23,10 @@ function filterData<DataT>(
|
|||||||
|
|
||||||
if (filterElement.is) {
|
if (filterElement.is) {
|
||||||
const nestedKey = Object.keys(filterElement.is)[0] as string;
|
const nestedKey = Object.keys(filterElement.is)[0] as string;
|
||||||
if (typeof item[key as keyof typeof item] === 'object') {
|
if (
|
||||||
|
item[key as keyof typeof item] &&
|
||||||
|
typeof item[key as keyof typeof item] === 'object'
|
||||||
|
) {
|
||||||
const nestedItem = item[key as keyof typeof item];
|
const nestedItem = item[key as keyof typeof item];
|
||||||
return (
|
return (
|
||||||
nestedItem[nestedKey as keyof typeof nestedItem] ===
|
nestedItem[nestedKey as keyof typeof nestedItem] ===
|
||||||
@ -71,6 +74,7 @@ export function filterAndSortData<DataT>(
|
|||||||
limit: number,
|
limit: number,
|
||||||
): Array<DataT> {
|
): Array<DataT> {
|
||||||
let filteredData = filterData<DataT>(data, where);
|
let filteredData = filterData<DataT>(data, where);
|
||||||
|
console.log(filteredData);
|
||||||
|
|
||||||
if (orderBy) {
|
if (orderBy) {
|
||||||
const firstOrderBy = orderBy[0];
|
const firstOrderBy = orderBy[0];
|
||||||
@ -84,8 +88,12 @@ export function filterAndSortData<DataT>(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sortDirection =
|
||||||
|
firstOrderBy[key as unknown as keyof typeof firstOrderBy];
|
||||||
if (typeof itemAValue === 'string' && typeof itemBValue === 'string') {
|
if (typeof itemAValue === 'string' && typeof itemBValue === 'string') {
|
||||||
return itemBValue.localeCompare(itemAValue);
|
return sortDirection === 'desc'
|
||||||
|
? itemBValue.localeCompare(itemAValue)
|
||||||
|
: -itemBValue.localeCompare(itemAValue);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|||||||
16
front/src/testing/mock-data/users.ts
Normal file
16
front/src/testing/mock-data/users.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { GraphqlQueryUser } from '../../interfaces/entities/user.interface';
|
||||||
|
|
||||||
|
export const mockedUsersData: Array<GraphqlQueryUser> = [
|
||||||
|
{
|
||||||
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||||
|
__typename: 'User',
|
||||||
|
email: 'charles@test.com',
|
||||||
|
displayName: 'Charles Test',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6c',
|
||||||
|
__typename: 'User',
|
||||||
|
email: 'felix@test.com',
|
||||||
|
displayName: 'Felix Test',
|
||||||
|
},
|
||||||
|
];
|
||||||
16
front/src/testing/mockedClient.ts
Normal file
16
front/src/testing/mockedClient.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user