Skip to content

Commit

Permalink
chore: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
shleewhite committed Aug 22, 2022
1 parent ad26a73 commit 68d8755
Show file tree
Hide file tree
Showing 6 changed files with 390 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
import * as React from 'react';
import {act, fireEvent, render, screen, waitFor} from '@testing-library/react';
import {CustomizationProvider} from '@twilio-paste/customization';

import {
MinimizableDialog,
MinimizableDialogButton,
MinimizableDialogHeader,
MinimizableDialogContainer,
MinimizableDialogContent,
} from '../src';

const CustomizationWrapper: React.FC = ({children}) => (
<CustomizationProvider
baseTheme="default"
theme={TestTheme}
elements={{
MINIMIZABLE_DIALOG_BUTTON: {
backgroundColor: 'colorBackgroundDark',
},
MINIMIZABLE_DIALOG: {
backgroundColor: 'colorBackgroundPrimaryLighter',
},
MINIMIZABLE_DIALOG_CONTENT: {
margin: 'space0',
},
MINIMIZABLE_DIALOG_HEADER: {
padding: 'space80',
},
MINIMIZABLE_DIALOG_HEADER_HEADING: {
fontSize: 'fontSize50',
},
MINIMIZABLE_DIALOG_HEADER_CLOSE_BUTTON: {
backgroundColor: 'colorBackground',
},
MINIMIZABLE_DIALOG_HEADER_CLOSE_ICON: {
width: 'sizeIcon50',
},
MINIMIZABLE_DIALOG_HEADER_MINIMIZE_BUTTON: {
backgroundColor: 'colorBackground',
},
MINIMIZABLE_DIALOG_HEADER_MINIMIZE_ICON: {
width: 'sizeIcon50',
},
}}
>
{children}
</CustomizationProvider>
);

const MyCustomizationWrapper: React.FC = ({children}) => (
<CustomizationProvider
baseTheme="default"
theme={TestTheme}
elements={{
FOO_DIALOG_BUTTON: {
backgroundColor: 'colorBackgroundDark',
},
FOO_DIALOG: {
backgroundColor: 'colorBackgroundPrimaryLighter',
},
FOO_DIALOG_CONTENT: {
margin: 'space0',
},
FOO_DIALOG_HEADER: {
padding: 'space80',
},
FOO_DIALOG_HEADER_HEADING: {
fontSize: 'fontSize50',
},
FOO_DIALOG_HEADER_CLOSE_BUTTON: {
backgroundColor: 'colorBackground',
},
FOO_DIALOG_HEADER_CLOSE_ICON: {
width: 'sizeIcon50',
},
FOO_DIALOG_HEADER_MINIMIZE_BUTTON: {
backgroundColor: 'colorBackground',
},
FOO_DIALOG_HEADER_MINIMIZE_ICON: {
width: 'sizeIcon50',
},
}}
>
{children}
</CustomizationProvider>
);

describe('Customization', () => {
it('should have default element data attributes', () => {
render(
<MinimizableDialogContainer>
<MinimizableDialogButton variant="primary">Button</MinimizableDialogButton>
<MinimizableDialog aria-label="My custom dialog">
<MinimizableDialogHeader data-testid="dialog-header">My custom dialog</MinimizableDialogHeader>
<MinimizableDialogContent data-testid="dialog-contents">This is a dialog.</MinimizableDialogContent>
</MinimizableDialog>
</MinimizableDialogContainer>
);

const dialogButton = screen.getByRole('button', {name: 'Button'});
const minimizeButton = screen.getByRole('button', {name: 'minimize', hidden: true});
const closeButton = screen.getByRole('button', {name: 'close', hidden: true});
const dialog = screen.getByRole('dialog', {hidden: true});
const dialogContents = screen.getByTestId('dialog-contents');
const dialogHeader = screen.getByTestId('dialog-header');
const dialogHeading = screen.getByText('My custom dialog');

expect(dialogButton.getAttribute('data-paste-element')).toEqual('MINIMIZABLE_DIALOG_BUTTON');
expect(minimizeButton.getAttribute('data-paste-element')).toEqual('MINIMIZABLE_DIALOG_HEADER_MINIMIZE_BUTTON');
expect(closeButton.getAttribute('data-paste-element')).toEqual('MINIMIZABLE_DIALOG_HEADER_CLOSE_BUTTON');
expect(dialogContents.getAttribute('data-paste-element')).toEqual('MINIMIZABLE_DIALOG_CONTENT');
expect(dialogHeader.getAttribute('data-paste-element')).toEqual('MINIMIZABLE_DIALOG_HEADER');
expect(dialogHeading.getAttribute('data-paste-element')).toEqual('MINIMIZABLE_DIALOG_HEADER_HEADING');

expect(dialog.querySelector('[data-paste-element="MINIMIZABLE_DIALOG"]')).toBeInTheDocument();
expect(
minimizeButton.querySelector('[data-paste-element="MINIMIZABLE_DIALOG_HEADER_MINIMIZE_ICON"]')
).toBeInTheDocument();
expect(
closeButton.querySelector('[data-paste-element="MINIMIZABLE_DIALOG_HEADER_CLOSE_ICON"]')
).toBeInTheDocument();
});

it('should add custom styles to components', async () => {
render(
<MinimizableDialogContainer>
<MinimizableDialogButton variant="primary">Button</MinimizableDialogButton>
<MinimizableDialog aria-label="My custom dialog">
<MinimizableDialogHeader data-testid="dialog-header">My custom dialog</MinimizableDialogHeader>
<MinimizableDialogContent data-testid="dialog-contents">This is a dialog.</MinimizableDialogContent>
</MinimizableDialog>
</MinimizableDialogContainer>,
{wrapper: CustomizationWrapper}
);

const dialogButton = screen.getByRole('button', {name: 'Button'});

await waitFor(() => {
fireEvent.click(dialogButton);
});

const minimizeButton = screen.getByRole('button', {name: 'minimize'});
const closeButton = screen.getByRole('button', {name: 'close'});
const dialog = screen.getByRole('dialog').querySelector('[data-paste-element="MINIMIZABLE_DIALOG"]');
const dialogContents = screen.getByTestId('dialog-contents');
const dialogHeader = screen.getByTestId('dialog-header');
const dialogHeading = screen.getByText('My custom dialog');
const minimizeIcon = minimizeButton.querySelector('[data-paste-element="MINIMIZABLE_DIALOG_HEADER_MINIMIZE_ICON"]');
const closeIcon = closeButton.querySelector('[data-paste-element="MINIMIZABLE_DIALOG_HEADER_CLOSE_ICON"]');

expect(dialogButton).toHaveStyleRule('background-color', 'rgb(225, 227, 234)');
expect(dialogHeader).toHaveStyleRule('padding-top', '0.75rem');
expect(dialogHeading).toHaveStyleRule('font-size', '1.125rem');
expect(dialogContents).toHaveStyleRule('margin', '0');
expect(dialog).toHaveStyleRule('background-color', 'rgb(204, 228, 255)');
expect(minimizeButton).toHaveStyleRule('background-color', 'rgb(244, 244, 246)');
expect(minimizeIcon).toHaveStyleRule('width', '1.75rem');
expect(closeButton).toHaveStyleRule('background-color', 'rgb(244, 244, 246)');
expect(closeIcon).toHaveStyleRule('width', '1.75rem');
});

it('should set custom element data attributes', () => {
render(
<MinimizableDialogContainer>
<MinimizableDialogButton variant="primary" element="FOO_DIALOG_BUTTON">
Button
</MinimizableDialogButton>
<MinimizableDialog aria-label="My custom dialog" element="FOO_DIALOG">
<MinimizableDialogHeader data-testid="dialog-header" element="FOO_DIALOG_HEADER">
My custom dialog
</MinimizableDialogHeader>
<MinimizableDialogContent data-testid="dialog-contents" element="FOO_DIALOG_CONTENT">
This is a dialog.
</MinimizableDialogContent>
</MinimizableDialog>
</MinimizableDialogContainer>
);

const dialogButton = screen.getByRole('button', {name: 'Button'});
const minimizeButton = screen.getByRole('button', {name: 'minimize', hidden: true});
const closeButton = screen.getByRole('button', {name: 'close', hidden: true});
const dialog = screen.getByRole('dialog', {hidden: true});
const dialogContents = screen.getByTestId('dialog-contents');
const dialogHeader = screen.getByTestId('dialog-header');
const dialogHeading = screen.getByText('My custom dialog');

expect(dialogButton.getAttribute('data-paste-element')).toEqual('FOO_DIALOG_BUTTON');
expect(minimizeButton.getAttribute('data-paste-element')).toEqual('FOO_DIALOG_HEADER_MINIMIZE_BUTTON');
expect(closeButton.getAttribute('data-paste-element')).toEqual('FOO_DIALOG_HEADER_CLOSE_BUTTON');
expect(dialogContents.getAttribute('data-paste-element')).toEqual('FOO_DIALOG_CONTENT');
expect(dialogHeader.getAttribute('data-paste-element')).toEqual('FOO_DIALOG_HEADER');
expect(dialogHeading.getAttribute('data-paste-element')).toEqual('FOO_DIALOG_HEADER_HEADING');

expect(dialog.querySelector('[data-paste-element="FOO_DIALOG"]')).toBeInTheDocument();
expect(minimizeButton.querySelector('[data-paste-element="FOO_DIALOG_HEADER_MINIMIZE_ICON"]')).toBeInTheDocument();
expect(closeButton.querySelector('[data-paste-element="FOO_DIALOG_HEADER_CLOSE_ICON"]')).toBeInTheDocument();
});

it('should add custom styles to components with custom element data attributes', async () => {
render(
<MinimizableDialogContainer>
<MinimizableDialogButton variant="primary" element="FOO_DIALOG_BUTTON">
Button
</MinimizableDialogButton>
<MinimizableDialog aria-label="My custom dialog" element="FOO_DIALOG">
<MinimizableDialogHeader data-testid="dialog-header" element="FOO_DIALOG_HEADER">
My custom dialog
</MinimizableDialogHeader>
<MinimizableDialogContent data-testid="dialog-contents" element="FOO_DIALOG_CONTENT">
This is a dialog.
</MinimizableDialogContent>
</MinimizableDialog>
</MinimizableDialogContainer>,
{wrapper: MyCustomizationWrapper}
);

const dialogButton = screen.getByRole('button', {name: 'Button'});

await waitFor(() => {
fireEvent.click(dialogButton);
});

const minimizeButton = screen.getByRole('button', {name: 'minimize'});
const closeButton = screen.getByRole('button', {name: 'close'});
const dialog = screen.getByRole('dialog').querySelector('[data-paste-element="FOO_DIALOG"]');
const dialogContents = screen.getByTestId('dialog-contents');
const dialogHeader = screen.getByTestId('dialog-header');
const dialogHeading = screen.getByText('My custom dialog');
const minimizeIcon = minimizeButton.querySelector('[data-paste-element="FOO_DIALOG_HEADER_MINIMIZE_ICON"]');
const closeIcon = closeButton.querySelector('[data-paste-element="FOO_DIALOG_HEADER_CLOSE_ICON"]');

expect(dialogButton).toHaveStyleRule('background-color', 'rgb(225, 227, 234)');
expect(dialogHeader).toHaveStyleRule('padding-top', '0.75rem');
expect(dialogHeading).toHaveStyleRule('font-size', '1.125rem');
expect(dialogContents).toHaveStyleRule('margin', '0');
expect(dialog).toHaveStyleRule('background-color', 'rgb(204, 228, 255)');
expect(minimizeButton).toHaveStyleRule('background-color', 'rgb(244, 244, 246)');
expect(minimizeIcon).toHaveStyleRule('width', '1.75rem');
expect(closeButton).toHaveStyleRule('background-color', 'rgb(244, 244, 246)');
expect(closeIcon).toHaveStyleRule('width', '1.75rem');
});
});
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
import * as React from 'react';
import {act, render, screen, fireEvent, waitFor} from '@testing-library/react';
import {render, screen, fireEvent, waitFor} from '@testing-library/react';

import {
MinimizableDialog,
MinimizableDialogButton,
MinimizableDialogHeader,
MinimizableDialogContainer,
MinimizableDialogContent,
useMinimizableDialogState,
} from '../src';

import {StateHookExample} from '../stories/index.stories';

describe('MinimizableDialog', () => {
describe('Render', () => {
it('should render a dialog button with aria attributes', async () => {
act(() => {
render(
<MinimizableDialogContainer>
<MinimizableDialogButton variant="primary">Button</MinimizableDialogButton>
<MinimizableDialog aria-label="My custom dialog">
<MinimizableDialogHeader>My custom dialog</MinimizableDialogHeader>
<MinimizableDialogContent>This is a dialog.</MinimizableDialogContent>
</MinimizableDialog>
</MinimizableDialogContainer>
);
});
it('should render a dialog button and dialog with aria attributes', async () => {
render(
<MinimizableDialogContainer>
<MinimizableDialogButton variant="primary">Button</MinimizableDialogButton>
<MinimizableDialog aria-label="My custom dialog">
<MinimizableDialogHeader>My custom dialog</MinimizableDialogHeader>
<MinimizableDialogContent>This is a dialog.</MinimizableDialogContent>
</MinimizableDialog>
</MinimizableDialogContainer>
);

const dialogButton = screen.getByRole('button', {name: 'Chat'});
const dialog = screen.getByRole('dialog');
const dialogButton = screen.getByRole('button', {name: 'Button'});
const dialog = screen.getByRole('dialog', {hidden: true});

expect(dialogButton.getAttribute('aria-haspopup')).toEqual('dialog');
expect(dialogButton.getAttribute('aria-controls')).toEqual(dialog.id);
Expand All @@ -38,5 +37,60 @@ describe('MinimizableDialog', () => {
});
expect(dialog).toBeVisible();
});

it('should render a dialog and toggle visible and minimized with external buttons', async () => {
render(<StateHookExample />);

const showButton = screen.getByRole('button', {name: 'Open dialog'});
const closeButton = screen.getByRole('button', {name: 'Close dialog'});
const minimizeButton = screen.getByRole('button', {name: 'Minimize dialog'});
const expandButton = screen.getByRole('button', {name: 'Expand dialog'});
const dialog = screen.getByRole('dialog', {hidden: true});
const dialogContents = screen.getByTestId('dialog-contents');
const dialogHeader = screen.getByTestId('dialog-header');

expect(dialog).not.toBeVisible();
await waitFor(() => {
fireEvent.click(showButton);
});
expect(dialog).toBeVisible();

await waitFor(() => {
fireEvent.click(minimizeButton);
});
expect(dialogContents).not.toBeVisible();
expect(dialogHeader).toBeVisible();

await waitFor(() => {
fireEvent.click(expandButton);
});
expect(dialogContents).toBeVisible();
expect(dialogHeader).toBeVisible();

await waitFor(() => {
fireEvent.click(closeButton);
});
expect(dialog).not.toBeVisible();
});
});

describe('i18n', () => {
it('should have default dismiss and minimize button text', async () => {
render(
<MinimizableDialogContainer>
<MinimizableDialogButton variant="primary">Button</MinimizableDialogButton>
<MinimizableDialog aria-label="My custom dialog">
<MinimizableDialogHeader>My custom dialog</MinimizableDialogHeader>
<MinimizableDialogContent>This is a dialog.</MinimizableDialogContent>
</MinimizableDialog>
</MinimizableDialogContainer>
);

const dismissButton = screen.getByRole('button', {name: 'close', hidden: true});
expect(dismissButton).toBeDefined();

const minimizeButton = screen.getByRole('button', {name: 'minimize', hidden: true});
expect(minimizeButton).toBeDefined();
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import {Box} from '@twilio-paste/box';
import {Box, safelySpreadBoxProps} from '@twilio-paste/box';
import type {BoxProps} from '@twilio-paste/box';

import {MinimizableDialogContext} from './MinimizableDialogContext';
Expand All @@ -10,11 +10,12 @@ interface MinimizableDialogContentProps extends Pick<BoxProps, 'element'> {
}

const MinimizableDialogContent = React.forwardRef<HTMLDivElement, MinimizableDialogContentProps>(
({children, element = 'MINIMIZABLE_DIALOG_CONTENT'}, ref) => {
({children, element = 'MINIMIZABLE_DIALOG_CONTENT', ...props}, ref) => {
const {minimized} = React.useContext(MinimizableDialogContext);

return (
<Box
{...safelySpreadBoxProps(props)}
element={element}
ref={ref}
margin={minimized ? 'space0' : 'space70'}
Expand Down
Loading

0 comments on commit 68d8755

Please sign in to comment.