4026 create storybook tests for blocklist components (#4185)

* Add SettingsAccountsEmailsBlocklistInput story

* Add SettingsAccountsEmailsBlocklistSection story

* Add SettingsAccountsEmailsBlocklistTable story

* Add SettingsAccountsEmailsBlocklistTableRow story

* wip

* add play

* add play

* add delete from blocklist test

* wip

* wip

* done
This commit is contained in:
bosiraphael
2024-02-26 21:54:29 +01:00
committed by GitHub
parent a7aebcd01d
commit 8b39e53e49
5 changed files with 237 additions and 0 deletions

View File

@ -0,0 +1,58 @@
import { Decorator, Meta, StoryObj } from '@storybook/react';
import { expect, fn, userEvent, within } from '@storybook/test';
import { SettingsAccountsEmailsBlocklistInput } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistInput';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
const updateBlockedEmailListJestFn = fn();
const ClearMocksDecorator: Decorator = (Story, context) => {
if (context.parameters.clearMocks) {
updateBlockedEmailListJestFn.mockClear();
}
return <Story />;
};
const meta: Meta<typeof SettingsAccountsEmailsBlocklistInput> = {
title:
'Modules/Settings/Accounts/Blocklist/SettingsAccountsEmailsBlocklistInput',
component: SettingsAccountsEmailsBlocklistInput,
decorators: [ComponentDecorator, ClearMocksDecorator],
args: {
updateBlockedEmailList: updateBlockedEmailListJestFn,
},
argTypes: {
updateBlockedEmailList: { control: false },
},
parameters: {
clearMocks: true,
},
};
export default meta;
type Story = StoryObj<typeof SettingsAccountsEmailsBlocklistInput>;
export const Default: Story = {};
export const AddToBlocklist: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(updateBlockedEmailListJestFn).toHaveBeenCalledTimes(0);
const addToBlocklistInput = canvas.getByRole('textbox');
await userEvent.type(addToBlocklistInput, 'test@twenty.com');
const addToBlocklistButton = canvas.getByRole('button', {
name: /add to blocklist/i,
});
await userEvent.click(addToBlocklistButton);
expect(updateBlockedEmailListJestFn).toHaveBeenCalledTimes(1);
expect(updateBlockedEmailListJestFn).toHaveBeenCalledWith(
'test@twenty.com',
);
},
};

View File

@ -0,0 +1,17 @@
import { Meta, StoryObj } from '@storybook/react';
import { SettingsAccountsEmailsBlocklistInput } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistInput';
import { SettingsAccountsEmailsBlocklistSection } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistSection';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
const meta: Meta<typeof SettingsAccountsEmailsBlocklistSection> = {
title:
'Modules/Settings/Accounts/Blocklist/SettingsAccountsEmailsBlocklistSection',
component: SettingsAccountsEmailsBlocklistInput,
decorators: [ComponentDecorator],
};
export default meta;
type Story = StoryObj<typeof SettingsAccountsEmailsBlocklistSection>;
export const Default: Story = {};

View File

@ -0,0 +1,67 @@
import { Decorator, Meta, StoryObj } from '@storybook/react';
import { expect, fn, userEvent, within } from '@storybook/test';
import { mockedBlocklist } from '@/settings/accounts/components/__stories__/mockedBlocklist';
import { SettingsAccountsEmailsBlocklistTable } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistTable';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { formatToHumanReadableDate } from '~/utils';
const handleBlockedEmailRemoveJestFn = fn();
const ClearMocksDecorator: Decorator = (Story, context) => {
if (context.parameters.clearMocks) {
handleBlockedEmailRemoveJestFn.mockClear();
}
return <Story />;
};
const meta: Meta<typeof SettingsAccountsEmailsBlocklistTable> = {
title:
'Modules/Settings/Accounts/Blocklist/SettingsAccountsEmailsBlocklistTable',
component: SettingsAccountsEmailsBlocklistTable,
decorators: [ComponentDecorator, ClearMocksDecorator],
args: {
blocklist: mockedBlocklist,
handleBlockedEmailRemove: handleBlockedEmailRemoveJestFn,
},
argTypes: {
blocklist: { control: false },
handleBlockedEmailRemove: { control: false },
},
parameters: {
clearMocks: true,
},
};
export default meta;
type Story = StoryObj<typeof SettingsAccountsEmailsBlocklistTable>;
export const Default: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
for (const blocklistItem of mockedBlocklist) {
expect(await canvas.findByText(blocklistItem.handle)).toBeInTheDocument();
expect(
await canvas.findByText(
formatToHumanReadableDate(blocklistItem.createdAt),
),
).toBeInTheDocument();
}
},
};
export const DeleteFirstElementFromBlocklist: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(handleBlockedEmailRemoveJestFn).toHaveBeenCalledTimes(0);
const removeFromBlocklistButton = canvas.getAllByRole('button')[0];
await userEvent.click(removeFromBlocklistButton);
expect(handleBlockedEmailRemoveJestFn).toHaveBeenCalledTimes(1);
expect(handleBlockedEmailRemoveJestFn).toHaveBeenCalledWith('1');
},
};

View File

@ -0,0 +1,67 @@
import { Decorator, Meta, StoryObj } from '@storybook/react';
import { expect, fn, userEvent, within } from '@storybook/test';
import { mockedBlocklist } from '@/settings/accounts/components/__stories__/mockedBlocklist';
import { SettingsAccountsEmailsBlocklistTableRow } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistTableRow';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { formatToHumanReadableDate } from '~/utils';
const onRemoveJestFn = fn();
const ClearMocksDecorator: Decorator = (Story, context) => {
if (context.parameters.clearMocks) {
onRemoveJestFn.mockClear();
}
return <Story />;
};
const meta: Meta<typeof SettingsAccountsEmailsBlocklistTableRow> = {
title:
'Modules/Settings/Accounts/Blocklist/SettingsAccountsEmailsBlocklistTableRow',
component: SettingsAccountsEmailsBlocklistTableRow,
decorators: [ComponentDecorator, ClearMocksDecorator],
args: {
blocklistItem: mockedBlocklist[0],
onRemove: onRemoveJestFn,
},
argTypes: {
blocklistItem: { control: false },
onRemove: { control: false },
},
parameters: {
clearMocks: true,
},
};
export default meta;
type Story = StoryObj<typeof SettingsAccountsEmailsBlocklistTableRow>;
export const Default: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(
await canvas.findByText(mockedBlocklist[0].handle),
).toBeInTheDocument();
expect(
await canvas.findByText(
formatToHumanReadableDate(mockedBlocklist[0].createdAt),
),
).toBeInTheDocument();
},
};
export const DeleteFirstElementFromBlocklist: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(onRemoveJestFn).toHaveBeenCalledTimes(0);
const removeFromBlocklistButton = canvas.getAllByRole('button')[0];
await userEvent.click(removeFromBlocklistButton);
expect(onRemoveJestFn).toHaveBeenCalledTimes(1);
expect(onRemoveJestFn).toHaveBeenCalledWith('1');
},
};

View File

@ -0,0 +1,28 @@
import { DateTime } from 'luxon';
export const mockedBlocklist = [
{
id: '1',
handle: 'test1@twenty.com',
workspaceMemberId: '1',
createdAt: DateTime.now().minus({ hours: 2 }).toISO() ?? '',
},
{
id: '2',
handle: 'test2@twenty.com',
workspaceMemberId: '1',
createdAt: DateTime.now().minus({ days: 2 }).toISO() ?? '',
},
{
id: '3',
handle: 'test3@twenty.com',
workspaceMemberId: '1',
createdAt: DateTime.now().minus({ days: 3 }).toISO() ?? '',
},
{
id: '4',
handle: '@twenty.com',
workspaceMemberId: '1',
createdAt: DateTime.now().minus({ days: 4 }).toISO() ?? '',
},
];