diff --git a/src/internal/components/Toast.test.tsx b/src/internal/components/Toast.test.tsx new file mode 100644 index 0000000000..91471f0fc3 --- /dev/null +++ b/src/internal/components/Toast.test.tsx @@ -0,0 +1,206 @@ +import React from 'react'; +import { fireEvent, render } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { describe, expect, test, vi } from 'vitest'; +import { Toast } from './Toast'; + +describe('Toast component', () => { + test('bottom-right renders correctly', () => { + const { getByTestId } = render( + {}} + > +
Test
+
+ ); + + const toastContainer = getByTestId('ockToast'); + expect(toastContainer).toBeInTheDocument(); + expect(toastContainer).toHaveClass('bottom-5 left-3/4'); + + const closeButton = getByTestId('ockCloseButton'); + expect(closeButton).toBeInTheDocument(); + }); + + test('top-right renders correctly', () => { + const { getByTestId } = render( + {}} + > +
Test
+
+ ); + + const toastContainer = getByTestId('ockToast'); + expect(toastContainer).toBeInTheDocument(); + expect(toastContainer).toHaveClass('top-[100px] left-3/4'); + + const closeButton = getByTestId('ockCloseButton'); + expect(closeButton).toBeInTheDocument(); + }); + + test('top-center renders correctly', () => { + const { getByTestId } = render( + {}} + > +
Test
+
+ ); + + const toastContainer = getByTestId('ockToast'); + expect(toastContainer).toBeInTheDocument(); + expect(toastContainer).toHaveClass('top-[100px] left-2/4'); + + const closeButton = getByTestId('ockCloseButton'); + expect(closeButton).toBeInTheDocument(); + }); + + test('bottom-center renders correctly', () => { + const { getByTestId } = render( + {}} + > +
Test
+
+ ); + + const toastContainer = getByTestId('ockToast'); + expect(toastContainer).toBeInTheDocument(); + expect(toastContainer).toHaveClass('bottom-5 left-2/4'); + + const closeButton = getByTestId('ockCloseButton'); + expect(closeButton).toBeInTheDocument(); + }); + + test('custom className is applied correctly', () => { + const { getByTestId } = render( + {}} + className="custom-class" + > +
Test
+
+ ); + + const toastContainer = getByTestId('ockToast'); + expect(toastContainer).toHaveClass('custom-class'); + }); + + test('toast is not visible when isToastVisible is false', () => { + const { queryByTestId } = render( + {}} + > +
Test
+
+ ); + const toastContainer = queryByTestId('ockToast'); + expect(toastContainer).not.toBeInTheDocument(); + }); + + test('toast close button works', () => { + const setIsToastVisible = vi.fn(); + const { getByTestId } = render( + +
Test
+
+ ); + + const closeButton = getByTestId('ockCloseButton'); + fireEvent.click(closeButton); + expect(setIsToastVisible).toHaveBeenCalledWith(false); + }); + + test('toast renders children correctly', () => { + const { getByText } = render( + {}} + > +
Test
+
+ ); + + const text = getByText('Test'); + expect(text).toBeInTheDocument(); + }); + + test('toast disappears after durationMs', async () => { + vi.useFakeTimers(); + const setIsToastVisible = vi.fn(); + const durationMs = 2000; + + render( + +
Test
+
+ ); + + expect(setIsToastVisible).not.toHaveBeenCalled(); + + // Fast-forward time by durationMs + vi.advanceTimersByTime(durationMs); + + expect(setIsToastVisible).toHaveBeenCalledWith(false); + + vi.useRealTimers(); + }); + + test('timer does not fire after manual close', () => { + vi.useFakeTimers(); + const setIsToastVisible = vi.fn(); + const durationMs = 2000; + + const { getByTestId } = render( + +
Test
+
+ ); + + // Advance partway through the duration + vi.advanceTimersByTime(1000); + + // Simulate clicking the close button + const closeButton = getByTestId('ockCloseButton'); + fireEvent.click(closeButton); + + // First call is from the close button + expect(setIsToastVisible).toHaveBeenCalledTimes(1); + expect(setIsToastVisible).toHaveBeenCalledWith(false); + + // Advance past when the original timer would have fired + vi.advanceTimersByTime(1500); + // setIsToastVisible should not have been called again by the timer + expect(setIsToastVisible).toHaveBeenCalledTimes(1); + + vi.useRealTimers(); + }); +}); diff --git a/src/internal/components/Toast.tsx b/src/internal/components/Toast.tsx index 2a3bc57a20..71e327b264 100644 --- a/src/internal/components/Toast.tsx +++ b/src/internal/components/Toast.tsx @@ -8,7 +8,6 @@ type ToastProps = { position: 'top-center' | 'top-right' | 'bottom-center' | 'bottom-right'; isToastVisible: boolean; setIsToastVisible: (isToastVisible: boolean) => void; - closeToast: () => void; children: React.ReactNode; }; @@ -18,7 +17,6 @@ export function Toast({ position = 'bottom-center', isToastVisible, setIsToastVisible, - closeToast, children, }: ToastProps) { const positionClass = useMemo(() => { @@ -62,12 +60,12 @@ export function Toast({ positionClass, className, )} - data-testid="GlobalToast" + data-testid="ockToast" >
{children}