Skip to content

Commit

Permalink
test: added tests for toast (#38)
Browse files Browse the repository at this point in the history
* test: jest testing setup

* test: fixed jest typescript definitions

* fix: test script

* chore(deps): move deps to dev

* test: added tests for accordion

* test: added husky precommit test

* test: axe container test

* chore(infra): added github action test

* test: added tests for number input

* fix: a11y aria-valuetext issue with NumberInput

* test: added tests for Slider

* test: added tests for progress

* test: added tests for link

* test: added tests for breadcrumb

* test: added tests for pagination

* test: added tests for toast

* chore(deps): remove unused raf
  • Loading branch information
anuraghazra authored Sep 15, 2020
1 parent 76de250 commit 57ba567
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/toast/ToastProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { createContext } from "@chakra-ui/utils";

import { ToastStateReturn } from "./ToastState";
import { ToastController } from "./ToastController";
import useToastState, { IToast } from "./ToastState";
import { useToastState, IToast } from "./ToastState";

const DEFAULT_TIMEOUT = 5000;
const PLACEMENTS = {
Expand Down
4 changes: 1 addition & 3 deletions src/toast/ToastState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface ToastStateProps {
animationTimeout?: number;
}

const useToastState = ({ animationTimeout = 0 }: ToastStateProps) => {
export const useToastState = ({ animationTimeout = 0 }: ToastStateProps) => {
const [toasts, setToasts] = React.useState<ToastList>({});

// toggle can be used to just hide/show the toast instead of removing it.
Expand Down Expand Up @@ -140,5 +140,3 @@ const useToastState = ({ animationTimeout = 0 }: ToastStateProps) => {
};

export type ToastStateReturn = ReturnType<typeof useToastState>;

export default useToastState;
118 changes: 118 additions & 0 deletions src/toast/__tests__/Toast.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import * as React from "react";
import { axe } from "jest-axe";
import { render } from "reakit-test-utils";

import { useToast, ToastProvider } from "..";

const Demo = () => {
const { show } = useToast();

return (
<div>
<button
onClick={() => {
show({
type: "error",
content: "This is error",
});
}}
>
Error
</button>
<button
onClick={() => {
show({ type: "success", content: "This is success" });
}}
>
Success
</button>
<button
onClick={() => {
show({ type: "warning", content: "This is warning" });
}}
>
Warning
</button>
<button
onClick={() => {
show({
content: () => (
<p style={{ fontFamily: "Impact", color: "black" }}>
This is Custom
</p>
),
});
}}
>
Custom
</button>
</div>
);
};

const ToastComp: React.FC = () => {
return (
<ToastProvider
placement="bottom-center"
toastTypes={{
error: ({ remove, content, id }) => {
return (
<div className="toast" style={{ backgroundColor: "#f02c2d" }}>
{content} <button onClick={() => remove(id)}>x</button>
</div>
);
},
success: ({ remove, content, id }) => {
return (
<div className="toast" style={{ backgroundColor: "#01c24e" }}>
{content} <button onClick={() => remove(id)}>x</button>
</div>
);
},
warning: ({ remove, content, id }) => {
return (
<div className="toast" style={{ backgroundColor: "#ef5013" }}>
{content} <button onClick={() => remove(id)}>x</button>
</div>
);
},
}}
>
<Demo />
</ToastProvider>
);
};

describe("Toast", () => {
it("should render correctly", () => {
const { baseElement } = render(<ToastComp />);

expect(baseElement).toMatchInlineSnapshot(`
<body>
<div>
<div>
<button>
Error
</button>
<button>
Success
</button>
<button>
Warning
</button>
<button>
Custom
</button>
</div>
</div>
</body>
`);
});

test("Toast renders with no a11y violations", async () => {
const { container } = render(<ToastComp />);
const results = await axe(container);

expect(results).toHaveNoViolations();
});
});
174 changes: 174 additions & 0 deletions src/toast/__tests__/ToastState.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { wait } from "reakit-test-utils";
import { renderHook, act } from "@testing-library/react-hooks";

import { useToastState } from "..";

beforeEach(() => {
jest.useFakeTimers();
jest
.spyOn(window, "requestAnimationFrame")
.mockImplementation((cb: any) => cb());
});

afterEach(() => {
(window.requestAnimationFrame as any).mockRestore();
});

describe("ToastState", () => {
it("should render correctly", () => {
const state = renderHook(() => useToastState({})).result;

expect(state.current).toMatchInlineSnapshot(`
Object {
"getToastToRender": [Function],
"hide": [Function],
"remove": [Function],
"setToasts": [Function],
"show": [Function],
"toasts": Object {},
"toggle": [Function],
}
`);
});

it("should add a new toast", () => {
const { result } = renderHook(() => useToastState({}));

expect(result.current.toasts).toStrictEqual({});

act(() => {
result.current.show({ type: "primary", content: "Hello world" });
});
expect(Object.values(result.current.toasts)).toMatchObject([
{
autoDismiss: undefined,
content: "Hello world",
isVisible: true,
placement: undefined,
timeout: undefined,
type: "primary",
},
]);
});

it("should toggle toast", () => {
const { result } = renderHook(() => useToastState({}));

expect(result.current.toasts).toStrictEqual({});

act(() => {
result.current.show({ type: "primary", content: "Hello world" });
});

const id = Object.values(result.current.toasts)[0].id;

act(() => {
result.current.toggle({ id, isVisible: false });
});
expect(result.current.toasts[id]).toMatchObject({ isVisible: false });
});

it("should remove toast", () => {
const { result } = renderHook(() => useToastState({}));

expect(result.current.toasts).toStrictEqual({});

act(() => {
result.current.show({ type: "primary", content: "Hello world" });
});
expect(Object.values(result.current.toasts)).toHaveLength(1);
const id = Object.values(result.current.toasts)[0].id;

act(() => {
result.current.remove(id);
});
expect(result.current.toasts).toStrictEqual({});
});

it("should hide toast", () => {
const { result } = renderHook(() => useToastState({ animationTimeout: 5 }));
let id = "";

expect(result.current.toasts).toStrictEqual({});

act(() => {
result.current.show({ type: "primary", content: "Hello world" });
});
expect(Object.values(result.current.toasts)).toHaveLength(1);
id = Object.values(result.current.toasts)[0].id;

act(() => {
result.current.hide(id);
});
expect(Object.values(result.current.toasts)).toMatchObject([
{
autoDismiss: undefined,
content: "Hello world",
isVisible: false,
placement: undefined,
timeout: undefined,
type: "primary",
},
]);

// Wait for animation timeout and after that toast should be removed
wait(
() => {
expect(result.current.toasts).toStrictEqual({});
},
{ timeout: 5 },
);
});

it("should test getToastToRender", () => {
const { result } = renderHook(() => useToastState({}));

expect(result.current.toasts).toStrictEqual({});

act(() => {
result.current.show({
type: "primary",
placement: "top-center",
content: "Hello world 1",
});
result.current.show({
type: "primary",
placement: "bottom-center",
content: "Hello world 2",
});
result.current.show({
type: "primary",
placement: "bottom-left",
content: "Hello world 3",
});
result.current.show({
type: "primary",
placement: "bottom-left",
content: "Hello world 4",
});
result.current.show({
type: "primary",
placement: "top-right",
content: "Hello world 5",
});
});

const allPositions: any[] = [];
result.current.getToastToRender("bottom-center", (pos, toastList) => {
allPositions.push(toastList);
});
expect(allPositions[0]).toHaveLength(1);
expect(allPositions[1]).toHaveLength(1);
expect(allPositions[2]).toHaveLength(2);
expect(allPositions[3]).toHaveLength(1);

expect(allPositions[2][0]).toMatchObject({
content: "Hello world 3",
placement: "bottom-left",
});
expect(allPositions[2][1]).toMatchObject({
content: "Hello world 4",
placement: "bottom-left",
});
});
});
12 changes: 6 additions & 6 deletions src/toast/stories/Demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const PlacementDemo = () => {
onClick={() => {
show({
type: randomType(),
content: "This is error",
content: "This is top-left",
placement: "top-left",
});
}}
Expand All @@ -72,7 +72,7 @@ const PlacementDemo = () => {
onClick={() => {
show({
type: randomType(),
content: "This is error",
content: "This is top-right",
placement: "top-right",
});
}}
Expand All @@ -83,7 +83,7 @@ const PlacementDemo = () => {
onClick={() => {
show({
type: randomType(),
content: "This is error",
content: "This is top-center",
placement: "top-center",
});
}}
Expand All @@ -94,7 +94,7 @@ const PlacementDemo = () => {
onClick={() => {
show({
type: randomType(),
content: "This is error",
content: "This is bottom-left",
placement: "bottom-left",
});
}}
Expand All @@ -105,7 +105,7 @@ const PlacementDemo = () => {
onClick={() => {
show({
type: randomType(),
content: "This is error",
content: "This is bottom-right",
placement: "bottom-right",
});
}}
Expand All @@ -116,7 +116,7 @@ const PlacementDemo = () => {
onClick={() => {
show({
type: randomType(),
content: "This is error",
content: "This is bottom-center",
placement: "bottom-center",
});
}}
Expand Down

0 comments on commit 57ba567

Please sign in to comment.