From 02db98157a49cb420a183f0142a3184a9c0de2de Mon Sep 17 00:00:00 2001 From: mhevyk Date: Tue, 1 Oct 2024 08:39:36 +0300 Subject: [PATCH] Add tests for useLazyImage --- src/hooks/use-lazy-mage/useLazyImage.ts | 2 +- .../cart-item-card/CartItemCard.tsx | 7 +- .../hooks/use-lazy-image/useLazyImage.spec.ts | 81 +++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 tests/unit/src/hooks/use-lazy-image/useLazyImage.spec.ts diff --git a/src/hooks/use-lazy-mage/useLazyImage.ts b/src/hooks/use-lazy-mage/useLazyImage.ts index a023f975..0f3f68e3 100644 --- a/src/hooks/use-lazy-mage/useLazyImage.ts +++ b/src/hooks/use-lazy-mage/useLazyImage.ts @@ -5,7 +5,7 @@ type UseLazyImage = { placeholderSrc: string; }; -export function useLazyImage({ src, placeholderSrc }: UseLazyImage) { +export default function useLazyImage({ src, placeholderSrc }: UseLazyImage) { const [source, setSource] = useState(placeholderSrc); const [hasError, setHasError] = useState(false); diff --git a/src/pages/cart/components/cart-item-card/CartItemCard.tsx b/src/pages/cart/components/cart-item-card/CartItemCard.tsx index 0970cb9c..a62ba02b 100644 --- a/src/pages/cart/components/cart-item-card/CartItemCard.tsx +++ b/src/pages/cart/components/cart-item-card/CartItemCard.tsx @@ -8,7 +8,7 @@ import Typography from "@mui/material/Typography"; import imagePlaceholder from "@/assets/icons/image-placeholder.svg?url"; -import { useLazyImage } from "@/hooks/use-lazy-mage/useLazyImage"; +import useLazyImage from "@/hooks/use-lazy-mage/useLazyImage"; import useToggle from "@/hooks/use-toggle/useToggle"; import CartSessionList from "@/pages/cart/components/cart-session-list/CartSessionList"; import TreatmentGeneralInfo from "@/pages/cart/components/treatment-general-info/TreatmentGeneralInfo"; @@ -71,7 +71,10 @@ export default function CartItemCard({ item }: ItemCardProps) { const { treatment, sessions } = item; const [src, { hasError, isLoading }] = useLazyImage({ - src: concatUrls(import.meta.env.VITE_API_BASE_IMAGE_URL, treatment.imageUrl!), + src: concatUrls( + import.meta.env.VITE_API_BASE_IMAGE_URL, + treatment.imageUrl! + ), placeholderSrc: imagePlaceholder, }); diff --git a/tests/unit/src/hooks/use-lazy-image/useLazyImage.spec.ts b/tests/unit/src/hooks/use-lazy-image/useLazyImage.spec.ts new file mode 100644 index 00000000..a2fa1f84 --- /dev/null +++ b/tests/unit/src/hooks/use-lazy-image/useLazyImage.spec.ts @@ -0,0 +1,81 @@ +import { act, renderHook } from "@testing-library/react"; + +import useLazyImage from "@/hooks/use-lazy-mage/useLazyImage"; + +const src = "image.jpg"; +const placeholderSrc = "placeholder.jpg"; + +describe("useLazyImage()", () => { + let loadCallback: () => void; + let errorCallback: () => void; + + beforeEach(() => { + global.Image = class { + src?: string; + addEventListener: (event: "load" | "error", callback: () => void) => void; + + constructor() { + this.addEventListener = (event, callback) => { + if (event === "load") { + loadCallback = callback; + } else if (event === "error") { + errorCallback = callback; + } + }; + } + + removeEventListener() {} + } as jest.Mock; + }); + + it("should return the placeholder source initially", () => { + const { result } = renderHook(() => useLazyImage({ src, placeholderSrc })); + + const [source, { isLoading, hasError }] = result.current; + + expect(source).toBe(placeholderSrc); + expect(isLoading).toBe(true); + expect(hasError).toBe(false); + }); + + it("should handle image load correctly", () => { + const { result } = renderHook(() => useLazyImage({ src, placeholderSrc })); + + act(() => { + loadCallback(); + }); + + const [source, { isLoading, hasError }] = result.current; + + expect(source).toBe(src); + expect(isLoading).toBe(false); + expect(hasError).toBe(false); + }); + + it("should handle image error correctly", () => { + const { result } = renderHook(() => useLazyImage({ src, placeholderSrc })); + + act(() => { + errorCallback(); + }); + + const [source, { isLoading, hasError }] = result.current; + + expect(source).toBe(placeholderSrc); + expect(isLoading).toBe(false); + expect(hasError).toBe(true); + }); + + it("should remove event listeners on cleanup", () => { + const { unmount } = renderHook(() => useLazyImage({ src, placeholderSrc })); + + const removeEventListenerSpy = jest.spyOn( + global.Image.prototype, + "removeEventListener" + ); + + unmount(); + + expect(removeEventListenerSpy).toHaveBeenCalledTimes(2); + }); +});