diff --git a/src/components/toast/toast.test.tsx b/src/components/toast/toast.test.tsx index 9794f6be29..a779dde73e 100644 --- a/src/components/toast/toast.test.tsx +++ b/src/components/toast/toast.test.tsx @@ -1,13 +1,9 @@ import React from "react"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; - -import guid from "../../__internal__/utils/helpers/guid"; import Toast, { ToastProps } from "./toast.component"; import ModalManager from "../modal/__internal__/modal-manager"; -jest.mock("../../__internal__/utils/helpers/guid"); - const MockToast = ({ open = false, onDismiss, @@ -47,41 +43,39 @@ const MockToast = ({ ); }; -describe("Toast component", () => { - (guid as jest.MockedFunction).mockImplementation( - () => "guid-12345" - ); +test("should be added to modal manager when it mounts", () => { + jest.spyOn(ModalManager, "addModal"); + render( {}}>foobar); - beforeEach(() => { - jest.useFakeTimers(); - }); + const toast = screen.getByTestId("toast-wrapper"); - afterEach(() => { - jest.useRealTimers(); - }); + expect(ModalManager.addModal).toHaveBeenCalledWith(toast, undefined, true); +}); - it("should be added to modal manager when it mounts", () => { - jest.spyOn(ModalManager, "addModal"); - render( {}}>foobar); +test("should be removed from modal manager when it unmounts", () => { + const removeModalSpy = jest.spyOn(ModalManager, "removeModal"); + removeModalSpy.mockClear(); + const { unmount } = render( {}}>foobar); - const toast = screen.getByTestId("toast-wrapper"); - expect(ModalManager.addModal).toHaveBeenCalledWith(toast, undefined, true); - }); + const toast = screen.getByTestId("toast-wrapper"); + unmount(); - it("should be removed from modal manager when it unmounts", () => { - const removeModalSpy = jest.spyOn(ModalManager, "removeModal"); - removeModalSpy.mockClear(); - const { unmount } = render( {}}>foobar); + expect(ModalManager.removeModal).toHaveBeenCalledWith(toast, true); +}); - const toast = screen.getByTestId("toast-wrapper"); - unmount(); - expect(ModalManager.removeModal).toHaveBeenCalledWith(toast, true); - }); +test("should not unmount the toast wrapper when the closed", () => { + render(); - it("should not unmount the toast wrapper when the closed", () => { - render(); + expect(screen.getByTestId("toast-wrapper")).toBeInTheDocument(); +}); - expect(screen.getByTestId("toast-wrapper")).toBeInTheDocument(); +describe("Event tests", () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); }); it("should not call `onDismiss` when 'Escape' key pressed and `open` prop is false", async () => { @@ -89,7 +83,7 @@ describe("Toast component", () => { const onDismissMock = jest.fn(); render(); - const button = await screen.findByRole("button", { name: "Show toast" }); + const button = screen.getByRole("button", { name: "Show toast" }); await user.click(button); await user.keyboard("{Escape}"); @@ -187,90 +181,6 @@ describe("Toast component", () => { expect(onDismissMock).not.toHaveBeenCalled(); }); - it("should not render close icon when no `onDismiss` prop is set", () => { - render(foobar); - - const closeButton = screen.queryByRole("button", { name: "Close" }); - - expect(closeButton).not.toBeInTheDocument(); - }); - - it("should render close icon when `onDismiss` prop is set", () => { - render( - {}}> - foobar - - ); - - const closeButton = screen.getByRole("button", { name: "Close" }); - - expect(closeButton).toBeInTheDocument(); - }); - - it("should render with any custom classes passed via the `className` prop", () => { - render( - - foobar - - ); - - expect(screen.getByTestId("toast")).toHaveClass("exampleClass"); - }); - - it("should render with correct custom ids passed via `id` prop", () => { - render( - - foobar - - ); - - expect(screen.getByTestId("toast")).toHaveAttribute("id", "exampleId"); - }); - - it("should render any child content passed via the `children` prop", () => { - render( - - foobar - - ); - - expect(screen.getByText("foobar")).toBeInTheDocument(); - }); - - it("should render with correct `data-` attributes", () => { - render( - - foobar - - ); - - const toast = screen.getByTestId("toast-role"); - - expect(toast).toHaveAttribute("data-component", "toast"); - expect(toast).toHaveAttribute("data-element", "toast-element"); - }); - - it("should allow custom data props to be passed to close button to be passed via `closeButtonDataProps`", () => { - render( - {}} - closeButtonDataProps={{ - "data-element": "close-element", - "data-role": "close-role", - }} - > - foobar - - ); - - const closeButton = screen.getByRole("button", { name: "Close" }); - - expect(closeButton).toHaveAttribute("data-component", "close"); - expect(closeButton).toHaveAttribute("data-element", "close-element"); - expect(closeButton).toHaveAttribute("data-role", "close-role"); - }); - it("should auto focus the toast wrapper element when initially opened", () => { render( @@ -286,17 +196,15 @@ describe("Toast component", () => { it("should not auto focus the toast wrapper element when initially opened if `disableAutoFocus` prop is set", () => { render( - + foobar ); - const toast = screen.getByTestId("toast"); - - expect(toast).not.toHaveAttribute("tabIndex"); - jest.runAllTimers(); + const toast = screen.getByRole("region"); + expect(toast).not.toHaveAttribute("tabIndex"); expect(toast).not.toHaveFocus(); }); @@ -321,11 +229,12 @@ describe("Toast component", () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); render(); - const button = await screen.findByRole("button", { name: "Show toast" }); + const button = screen.getByRole("button", { name: "Show toast" }); await user.click(button); jest.runAllTimers(); + const toast = await screen.findByTestId("toast"); - const closeButton = await screen.findByRole("button", { name: "Close" }); + const closeButton = screen.getByRole("button", { name: "Close" }); expect(toast).toHaveFocus(); @@ -339,12 +248,14 @@ describe("Toast component", () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); render(); - const button = await screen.findByRole("button", { name: "Show toast" }); + const button = screen.getByRole("button", { name: "Show toast" }); await user.click(button); jest.runAllTimers(); + + const toast = await screen.findByTestId("toast"); const closeButton = screen.getByRole("button", { name: "Close" }); - expect(await screen.findByTestId("toast")).toHaveFocus(); + expect(toast).toHaveFocus(); await user.click(closeButton); jest.runAllTimers(); @@ -361,292 +272,342 @@ describe("Toast component", () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); render(); - const button = await screen.findByRole("button", { name: "Show toast" }); + const button = screen.getByRole("button", { name: "Show toast" }); await user.click(button); jest.runAllTimers(); + const closeButton = await screen.findByRole("button", { name: "Close" }); await user.click(closeButton); jest.runAllTimers(); expect(button).not.toHaveFocus(); }); +}); - it("should render content container with correct expected styling when `maxWidth` is set", () => { - render( - - Child - - ); +test("should not render close button when no `onDismiss` prop is set", () => { + render(foobar); - expect(screen.getByTestId("toast")).toHaveStyle({ maxWidth: "200px" }); - }); + const closeButton = screen.queryByRole("button", { name: "Close" }); - it("should render with correct styling when `variant` prop is set to 'notice' and no `onDismiss` prop set", () => { - render( - - foobar - - ); + expect(closeButton).not.toBeInTheDocument(); +}); - const toast = screen.getByTestId("toast"); +test("should render close button when `onDismiss` prop is set", () => { + render( + {}}> + foobar + + ); - expect(screen.getByTestId("toast-wrapper")).toHaveStyle({ - display: "block", - }); - expect(toast).toHaveStyle({ - "background-color": "var(--colorsUtilityMajor400)", - border: "none", - color: "var(--colorsSemanticNeutralYang100)", - "margin-right": "0", - "max-width": "100%", - }); - expect(screen.getByTestId("toast-content")).toHaveStyle({ - display: "flex", - "align-items": "center", - padding: "11px 40px", - }); - expect(screen.queryByTestId("toast-type-icon")).not.toBeInTheDocument(); - }); - - it("should render with correct styling when `variant` prop is set to 'notice' and `onDismiss` prop set", () => { - render( - {}}> - foobar - - ); + const closeButton = screen.getByRole("button", { name: "Close" }); - expect(screen.getByTestId("toast-content")).toHaveStyle({ - display: "flex", - "align-items": "center", - padding: "11px 88px 11px 40px", - }); - expect(screen.getByRole("button", { name: "Close" })).toHaveStyle( - "right: 55px" - ); - }); + expect(closeButton).toBeVisible(); +}); - it("should render with correct styling when `variant` prop is set to 'notice' and `alignY` prop is set to 'top'", () => { - render( - {}} - > - foobar - - ); +test("should render with any custom classes passed via the `className` prop", () => { + render( + + foobar + + ); - const toast = screen.getByTestId("toast"); + expect(screen.getByTestId("toast")).toHaveClass("exampleClass"); +}); - expect(toast).toHaveStyle({ - margin: "0px 0px 0px auto", - }); - }); +test("should render with provided custom id passed via `id` prop", () => { + render( + + foobar + + ); - it("should render with correct styling when `variant` prop is set to 'notice' and `alignY` prop is set to 'bottom'", () => { - render( - {}} - > - foobar - - ); + expect(screen.getByTestId("toast")).toHaveAttribute("id", "exampleId"); +}); - const toast = screen.getByTestId("toast"); +test("should render any child content passed via the `children` prop", () => { + render( + + foobar + + ); - expect(toast).toHaveStyle({ - margin: "0px 0px 0px auto", - }); - }); + expect(screen.getByText("foobar")).toBeVisible(); +}); - it("should render the expected icon when `variant` prop is set to 'neutral'", () => { - render( - - foobar - - ); +test("should render with provided `data-` attributes", () => { + render( + + foobar + + ); - expect(screen.getByTestId("icon")).toHaveAttribute("type", "info"); - }); + const toast = screen.getByTestId("toast-role"); + expect(toast).toHaveAttribute("data-element", "toast-element"); +}); - it("should render the expected icon when `variant` prop is set to 'success'", () => { - render( - - foobar - - ); +test("should allow custom data props to be passed to close button to be passed via `closeButtonDataProps`", () => { + render( + {}} + closeButtonDataProps={{ + "data-element": "close-element", + "data-role": "close-role", + }} + > + foobar + + ); - expect(screen.getByTestId("icon")).toHaveAttribute("type", "tick_circle"); - }); + const closeButton = screen.getByRole("button", { name: "Close" }); - it("should render the expected icon when `variant` prop is set to 'warning'", () => { - render( - - foobar - - ); + expect(closeButton).toHaveAttribute("data-element", "close-element"); + expect(closeButton).toHaveAttribute("data-role", "close-role"); +}); + +test("should render content container with correct expected styling when `maxWidth` is set", () => { + render( + + Child + + ); + + expect(screen.getByTestId("toast")).toHaveStyle({ maxWidth: "200px" }); +}); + +test("should render with correct styling when `variant` prop is set to 'notice' and `onDismiss` is not set", () => { + render( + + foobar + + ); - expect(screen.getByTestId("icon")).toHaveAttribute("type", "warning"); + const toast = screen.getByTestId("toast"); + + expect(screen.getByTestId("toast-wrapper")).toHaveStyle({ + display: "block", }); - it("should render the expected icon when `variant` prop is set to 'error'", () => { - render( - - foobar - - ); + expect(toast).toHaveStyle({ + border: "none", + marginRight: "0", + maxWidth: "100%", + }); + expect(toast).toHaveStyleRule( + "background-color", + "var(--colorsUtilityMajor400)" + ); + expect(toast).toHaveStyleRule("color", "var(--colorsSemanticNeutralYang100)"); - expect(screen.getByTestId("icon")).toHaveAttribute("type", "error"); + expect(screen.getByTestId("toast-content")).toHaveStyle({ + display: "flex", + "align-items": "center", + padding: "11px 40px", }); - it("should render the expected icon when `variant` prop is set to 'info'", () => { - render( - - foobar - - ); + expect(screen.queryByTestId("toast-type-icon")).not.toBeInTheDocument(); +}); + +test("should render with correct styling when `variant` prop is set to 'notice' and `onDismiss` is set", () => { + render( + {}}> + foobar + + ); - expect(screen.getByTestId("icon")).toHaveAttribute("type", "info"); + expect(screen.getByTestId("toast-content")).toHaveStyle({ + display: "flex", + alignItems: "center", + padding: "11px 88px 11px 40px", }); - it("should render the expected icon when `variant` prop is set to 'notification'", () => { - render( - - foobar - - ); + expect(screen.getByRole("button", { name: "Close" })).toHaveStyle({ + right: "55px", + }); +}); - expect(screen.getByTestId("icon")).toHaveAttribute("type", "alert"); +test("should render with correct styling when `variant` prop is set to 'notice' and `alignY` prop is set to 'top'", () => { + render( + {}} + > + foobar + + ); + + const toast = screen.getByTestId("toast"); + + expect(toast).toHaveStyle({ + margin: "0px 0px 0px auto", }); +}); + +test("should render with correct styling when `variant` prop is set to 'notice' and `alignY` prop is set to 'bottom'", () => { + render( + {}} + > + foobar + + ); + + const toast = screen.getByTestId("toast"); - it("should not throw when ref is a function", () => { - expect(() => { - render( - {}} ref={(ref) => ref}> - foobar - - ); - }).not.toThrow(); + expect(toast).toHaveStyle({ + margin: "0px 0px 0px auto", }); +}); - it("should pass ref to the wrapper element", () => { - const ref = { current: null }; +test.each<[ToastProps["variant"], string]>([ + ["neutral", "info"], + ["success", "tick_circle"], + ["warning", "warning"], + ["error", "error"], + ["info", "info"], + ["notification", "alert"], +])( + "should render the expected icon when `variant` prop is set to '%s'", + (variant, iconType) => { render( - {}} ref={ref}> + foobar ); - expect(ref.current).toBe(screen.getByTestId("toast-wrapper")); - }); + expect(screen.getByTestId("icon")).toHaveAttribute("type", iconType); + } +); - it("should render with expected styling when `align` prop is 'right'", () => { +test("should not throw when ref is a function", () => { + expect(() => { render( - + {}} ref={(ref) => ref}> foobar ); + }).not.toThrow(); +}); + +test("should pass ref to the wrapper element", () => { + const ref = { current: null }; + render( + {}} ref={ref}> + foobar + + ); + + expect(ref.current).toBe(screen.getByTestId("toast-wrapper")); +}); + +test("should render with expected styling when `align` prop is 'right'", () => { + render( + + foobar + + ); - expect(screen.getByTestId("toast-wrapper")).toHaveStyle({ - "justify-content": "right", - }); - expect(screen.getByTestId("toast")).toHaveStyle({ - "margin-right": "auto", - "margin-left": "30px", - }); + expect(screen.getByRole("region")).toHaveStyle({ + "justify-content": "right", }); - it("should render with expected styling when `align` prop is 'center'", () => { - render( - - foobar - - ); + expect(screen.getByTestId("toast")).toHaveStyle({ + "margin-right": "auto", + "margin-left": "30px", + }); +}); + +test("should render with expected styling when `align` prop is 'center'", () => { + render( + + foobar + + ); - expect(screen.getByTestId("toast-wrapper")).toHaveStyle({ - "justify-content": "center", - }); - expect(screen.getByTestId("toast")).toHaveStyle({ - "margin-right": "auto", - "margin-left": "auto", - }); + expect(screen.getByRole("region")).toHaveStyle({ + "justify-content": "center", + }); + expect(screen.getByTestId("toast")).toHaveStyle({ + "margin-right": "auto", + "margin-left": "auto", }); +}); - it("should render with expected styling when `align` prop is 'left'", () => { - render( - - foobar - - ); +test("should render with expected styling when `align` prop is 'left'", () => { + render( + + foobar + + ); - expect(screen.getByTestId("toast-wrapper")).toHaveStyle({ - "justify-content": "left", - }); - expect(screen.getByTestId("toast")).toHaveStyle({ - "margin-right": "30px", - "margin-left": "auto", - }); + expect(screen.getByRole("region")).toHaveStyle({ + "justify-content": "left", + }); + expect(screen.getByTestId("toast")).toHaveStyle({ + "margin-right": "30px", + "margin-left": "auto", }); +}); - it("should render with expected styling when `alignY` prop is set to 'top'", () => { - render( - - foobar - - ); +test("should render with expected styling when `alignY` prop is set to 'top'", () => { + render( + + foobar + + ); - const toast = screen.getByTestId("toast"); + const toast = screen.getByTestId("toast"); - expect(toast).toHaveStyle({ - "margin-top": "30px", - "margin-bottom": "0", - }); + expect(toast).toHaveStyle({ + "margin-top": "30px", + "margin-bottom": "0", }); +}); - it("should render with expected styling when `alignY` prop is set to 'bottom'", () => { - render( - - foobar - - ); +test("should render with expected styling when `alignY` prop is set to 'bottom'", () => { + render( + + foobar + + ); - const toast = screen.getByTestId("toast"); + const toast = screen.getByTestId("toast"); - expect(toast).toHaveStyle({ - "margin-top": "0", - "margin-bottom": "30px", - }); + expect(toast).toHaveStyle({ + "margin-top": "0", + "margin-bottom": "30px", }); +}); - it("should render with expected styling when `alignY` prop is 'center' and `align` prop is 'left'", () => { - render( - - foobar - - ); +test("should render with expected styling when `alignY` prop is 'center' and `align` prop is 'left'", () => { + render( + + foobar + + ); - expect(screen.getByTestId("carbon-portal-exit")).toHaveStyle({ - top: "50%", - transform: "translate(50%,-50%)", - }); + expect(screen.getByTestId("carbon-portal-exit")).toHaveStyle({ + top: "50%", + transform: "translate(50%,-50%)", }); +}); - it("should render with expected styling when `alignY` prop is 'center' and `align` prop is not 'left'", () => { - render( - - foobar - - ); +test("should render with expected styling when `alignY` prop is 'center' and `align` prop is not 'left'", () => { + render( + + foobar + + ); - expect(screen.getByTestId("carbon-portal-exit")).toHaveStyle({ - top: "50%", - transform: "translate(-50%,-50%)", - }); + expect(screen.getByTestId("carbon-portal-exit")).toHaveStyle({ + top: "50%", + transform: "translate(-50%,-50%)", }); });