diff --git a/src/hooks/__tests__/useToast.test.ts b/src/hooks/__tests__/useToast.test.ts new file mode 100644 index 00000000..fe36e567 --- /dev/null +++ b/src/hooks/__tests__/useToast.test.ts @@ -0,0 +1,51 @@ +import { renderHook, act } from "@testing-library/react"; +import { useToast } from "../useToast"; + +jest.mock("sonner", () => ({ + toast: Object.assign( + jest.fn(), + { + success: jest.fn(), + error: jest.fn(), + warning: jest.fn(), + info: jest.fn(), + dismiss: jest.fn(), + } + ), +})); + +import { toast } from "sonner"; + +describe("useToast", () => { + beforeEach(() => jest.clearAllMocks()); + + it("calls toast.success", () => { + const { result } = renderHook(() => useToast()); + act(() => result.current.success("Saved!")); + expect(toast.success).toHaveBeenCalledWith("Saved!", undefined); + }); + + it("calls toast.error", () => { + const { result } = renderHook(() => useToast()); + act(() => result.current.error("Failed", { description: "Details" })); + expect(toast.error).toHaveBeenCalledWith("Failed", { description: "Details" }); + }); + + it("calls toast.warning", () => { + const { result } = renderHook(() => useToast()); + act(() => result.current.warning("Low balance")); + expect(toast.warning).toHaveBeenCalledWith("Low balance", undefined); + }); + + it("calls toast.info", () => { + const { result } = renderHook(() => useToast()); + act(() => result.current.info("Network changed")); + expect(toast.info).toHaveBeenCalledWith("Network changed", undefined); + }); + + it("calls toast.dismiss", () => { + const { result } = renderHook(() => useToast()); + act(() => result.current.dismiss("toast-1")); + expect(toast.dismiss).toHaveBeenCalledWith("toast-1"); + }); +}); diff --git a/src/hooks/index.ts b/src/hooks/index.ts index af54e080..319642d3 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -2,6 +2,9 @@ export { useWalletConnector } from './useWalletConnector'; export type { ConnectorResult } from './useWalletConnector'; +export { useToast } from './useToast'; +export type { ToastOptions } from './useToast'; + // Lazy-loaded connectors are imported dynamically in useWalletConnector hook // to prevent eager bundle loading. They are not exported here to maintain // their lazy-loading behavior. diff --git a/src/hooks/useToast.ts b/src/hooks/useToast.ts new file mode 100644 index 00000000..9f91e23e --- /dev/null +++ b/src/hooks/useToast.ts @@ -0,0 +1,27 @@ +"use client"; + +import { toast } from "sonner"; + +export type ToastOptions = { + description?: string; + duration?: number; + id?: string | number; +}; + +export function useToast() { + return { + success: (message: string, options?: ToastOptions) => + toast.success(message, options), + + error: (message: string, options?: ToastOptions) => + toast.error(message, options), + + warning: (message: string, options?: ToastOptions) => + toast.warning(message, options), + + info: (message: string, options?: ToastOptions) => + toast.info(message, options), + + dismiss: (id?: string | number) => toast.dismiss(id), + }; +}