Compare commits

..

1 commit

Author SHA1 Message Date
Edwin S Lopez
c5161d00c4
Merge c50cd3e6e7 into 112062c0b2 2025-03-20 21:11:52 -04:00
2 changed files with 129 additions and 36 deletions

View file

@ -1,10 +1,12 @@
import React, { act } from "react"; import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import ImageGallery from "../../../components/ImageGallery/ImageGallery"; import ImageDialog from "../../../components/ImageGallery/ImageGallery";
import ApiService from "../../../services/ApiService"; import ApiService from "../../../services/ApiService";
import { Images } from "../../../Types/Images"; import { Images } from "../../../Types/Images";
import { act } from "react";
import "@testing-library/jest-dom"; import "@testing-library/jest-dom";
// Mock ApiService
jest.mock("../../../services/ApiService"); jest.mock("../../../services/ApiService");
const mockImages: Images[] = [ const mockImages: Images[] = [
@ -13,43 +15,136 @@ const mockImages: Images[] = [
{ id: "3", file_name: "image3.jpg", mime_type: "image/jpeg", file_content: "mockBase64Content3" }, { id: "3", file_name: "image3.jpg", mime_type: "image/jpeg", file_content: "mockBase64Content3" },
]; ];
beforeAll(() => { describe("ImageDialog Component", () => {
Object.assign(navigator, { let setDialogOpenMock: jest.Mock;
clipboard: { let setImageLinksMock: jest.Mock;
writeText: jest.fn(),
},
});
});
describe("ImageGallery", () => {
beforeEach(() => { beforeEach(() => {
(ApiService.getUserImages as jest.Mock).mockResolvedValue({ images: mockImages, total: 3 }); jest.clearAllMocks();
(ApiService.deleteImage as jest.Mock).mockResolvedValue(true); setDialogOpenMock = jest.fn();
(ApiService.uploadImage as jest.Mock).mockResolvedValue('mockImageUrl'); setImageLinksMock = jest.fn();
jest.spyOn(ApiService, "getImages").mockResolvedValue({ images: mockImages, total: 6 });
render(<ImageGallery />);
}); });
it("should render images correctly", async () => { test("renders the dialog when open", async () => {
await act(async () => { await act(async () => {
await screen.findByText("Gallery"); render(
<ImageDialog
galleryOpen={true}
setDialogOpen={setDialogOpenMock}
setImageLinks={setImageLinksMock}
/>
);
});
expect(screen.getByText("Images disponibles")).toBeInTheDocument();
await waitFor(() => expect(ApiService.getImages).toHaveBeenCalledWith(1, 3));
expect(screen.getAllByRole("img")).toHaveLength(mockImages.length);
});
test("closes the dialog when close button is clicked", async () => {
await act(async () => {
render(
<ImageDialog
galleryOpen={true}
setDialogOpen={setDialogOpenMock}
setImageLinks={setImageLinksMock}
/>
);
});
fireEvent.click(screen.getByLabelText("close"));
expect(setDialogOpenMock).toHaveBeenCalledWith(false);
});
test("copies the image link when copy button is clicked", async () => {
//const setImageLinksMock = jest.fn();
await act(async () => {
render(
<ImageDialog
galleryOpen={true}
setDialogOpen={setDialogOpenMock}
setImageLinks={setImageLinksMock}
/>
);
});
await act(async () => {
await waitFor(() => expect(screen.getAllByRole("img")).toHaveLength(mockImages.length));
});
// Click the copy button
fireEvent.click(screen.getByTestId("copy-button-1"));
// Check that "Copié!" appears
expect(screen.getByText("Copié!")).toBeInTheDocument();
});
test("navigates to next and previous page", async () => {
await act(async () => {
render(
<ImageDialog
galleryOpen={true}
setDialogOpen={setDialogOpenMock}
setImageLinks={setImageLinksMock}
/>
);
});
await waitFor(() => expect(ApiService.getImages).toHaveBeenCalledWith(1, 3));
fireEvent.click(screen.getByText("Suivant"));
await waitFor(() => expect(ApiService.getImages).toHaveBeenCalledWith(2, 3));
fireEvent.click(screen.getByText("Précédent"));
await waitFor(() => expect(ApiService.getImages).toHaveBeenCalledWith(1, 3));
});
test("deletes an image successfully", async () => {
jest.spyOn(ApiService, "deleteImage").mockResolvedValue(true);
await act(async () => {
render(
<ImageDialog
galleryOpen={true}
setDialogOpen={setDialogOpenMock}
setImageLinks={setImageLinksMock}
/>
);
}); });
expect(screen.getByAltText("Image image1.jpg")).toBeInTheDocument(); await waitFor(() => expect(ApiService.getImages).toHaveBeenCalled());
expect(screen.getByAltText("Image image2.jpg")).toBeInTheDocument();
fireEvent.click(screen.getByTestId("delete-button-1"));
await waitFor(() => expect(ApiService.deleteImage).toHaveBeenCalledWith("1"));
expect(screen.queryByTestId("delete-button-1")).not.toBeInTheDocument();
}); });
it("should handle copy action", async () => { test("handles failed delete when image is linked", async () => {
const handleCopyMock = jest.fn(); jest.spyOn(ApiService, "deleteImage").mockResolvedValue(false);
render(<ImageGallery handleCopy={handleCopyMock} />); await act(async () => {
render(
const copyButtons = await waitFor(() => screen.findAllByTestId(/gallery-tab-copy-/)); <ImageDialog
await act(async () => { galleryOpen={true}
fireEvent.click(copyButtons[0]); setDialogOpen={setDialogOpenMock}
}); setImageLinks={setImageLinksMock}
/>
expect(navigator.clipboard.writeText).toHaveBeenCalled(); );
}); });
await waitFor(() => expect(ApiService.getImages).toHaveBeenCalled());
fireEvent.click(screen.getByTestId("delete-button-1"));
await waitFor(() => expect(ApiService.deleteImage).toHaveBeenCalledWith("1"));
expect(screen.getByText("Confirmer la suppression")).toBeInTheDocument();
});
}); });

View file

@ -45,7 +45,7 @@ const ImageGallery: React.FC<ImagesProps> = ({ handleCopy }) => {
const fetchImages = async () => { const fetchImages = async () => {
setLoading(true); setLoading(true);
const data = await ApiService.getUserImages(imgPage, imgLimit); const data = await ApiService.getImages(imgPage, imgLimit);
setImages(data.images); setImages(data.images);
setTotalImg(data.total); setTotalImg(data.total);
setLoading(false); setLoading(false);
@ -156,8 +156,7 @@ const ImageGallery: React.FC<ImagesProps> = ({ handleCopy }) => {
e.stopPropagation(); e.stopPropagation();
handleCopyFunction(obj.id); handleCopyFunction(obj.id);
}} }}
color="primary" color="primary" >
data-testid={`gallery-tab-copy-${obj.id}`} >
<ContentCopyIcon sx={{ fontSize: 18 }} /> <ContentCopyIcon sx={{ fontSize: 18 }} />
</IconButton> </IconButton>
@ -168,8 +167,7 @@ const ImageGallery: React.FC<ImagesProps> = ({ handleCopy }) => {
setImageToDelete(obj); setImageToDelete(obj);
setOpenDeleteDialog(true); setOpenDeleteDialog(true);
}} }}
color="error" color="error" >
data-testid={`gallery-tab-delete-${obj.id}`} >
<DeleteIcon sx={{ fontSize: 18 }} /> <DeleteIcon sx={{ fontSize: 18 }} />
</IconButton> </IconButton>