104 lines
3.7 KiB
TypeScript
104 lines
3.7 KiB
TypeScript
import PreviewManager from "$components/panel/PreviewManager.svelte";
|
|
import { downloadService } from "$services/downloadService";
|
|
import { konvaStageState } from "$states/konvaStage.svelte";
|
|
import { STATE_DATA } from "$states/persisted.svelte";
|
|
import { textsState } from "$states/texts.svelte";
|
|
import { render, screen, waitFor } from "@testing-library/svelte";
|
|
import userEvent from "@testing-library/user-event";
|
|
import type { Stage } from "svelte-konva";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
vi.mock("$services/downloadService", () => ({
|
|
downloadService: {
|
|
downloadAll: vi.fn(),
|
|
downloadPanel: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
vi.mock("./Preview.svelte", () => ({
|
|
default: { render: () => ({}) },
|
|
}));
|
|
describe("PreviewManager Integration", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
textsState[STATE_DATA] = [];
|
|
});
|
|
|
|
it("should show empty state by aria-label when no texts", () => {
|
|
render(PreviewManager);
|
|
expect(screen.getByLabelText(/Empty texts info/i)).toBeInTheDocument();
|
|
});
|
|
|
|
it("should toggle navigation buttons availability based on texts length", async () => {
|
|
textsState[STATE_DATA] = ["1", "2"];
|
|
render(PreviewManager);
|
|
|
|
const nextBtn = screen.getByRole("button", { name: /next slide/i });
|
|
const prevBtn = screen.getByRole("button", { name: /previous slide/i });
|
|
|
|
expect(nextBtn).not.toBeDisabled();
|
|
expect(prevBtn).toBeDisabled();
|
|
});
|
|
|
|
it("should send correct data to downloadAll service", async () => {
|
|
const user = userEvent.setup();
|
|
textsState[STATE_DATA] = ["Apple", "Banana"];
|
|
render(PreviewManager);
|
|
|
|
await user.click(screen.getByRole("button", { name: /download all/i }));
|
|
|
|
expect(downloadService.downloadAll).toHaveBeenCalledWith(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({ filename: "Apple" }),
|
|
expect.objectContaining({ filename: "Banana" }),
|
|
]),
|
|
);
|
|
});
|
|
|
|
it("should call downloadPanel with current active text", async () => {
|
|
const user = userEvent.setup();
|
|
textsState[STATE_DATA] = ["First", "Second"];
|
|
konvaStageState.stage = { node: { id: "stage-ref" } } as unknown as Stage;
|
|
|
|
render(PreviewManager);
|
|
|
|
// Переходим на второй слайд
|
|
await user.click(screen.getByRole("button", { name: /next slide/i }));
|
|
await user.click(screen.getByRole("button", { name: /download current/i }));
|
|
|
|
expect(downloadService.downloadPanel).toHaveBeenCalledWith(expect.anything(), "Second");
|
|
});
|
|
|
|
it("should return to empty state when texts are removed", async () => {
|
|
textsState[STATE_DATA] = ["Temp"];
|
|
render(PreviewManager);
|
|
|
|
expect(screen.queryByLabelText(/Empty texts info/i)).not.toBeInTheDocument();
|
|
|
|
textsState[STATE_DATA] = [];
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByLabelText(/Empty texts info/i)).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it("should automatically correct current index on items deletion", async () => {
|
|
const user = userEvent.setup();
|
|
textsState[STATE_DATA] = ["1", "2", "3"];
|
|
render(PreviewManager);
|
|
|
|
// Уходим на последний слайд
|
|
await user.click(screen.getByRole("button", { name: /next slide/i }));
|
|
await user.click(screen.getByRole("button", { name: /next slide/i }));
|
|
|
|
// Удаляем элементы. Индекс должен упасть с 2 до 0
|
|
textsState[STATE_DATA] = ["Only one left"];
|
|
|
|
await waitFor(() => {
|
|
// Проверяем, что кнопка "Next" заблокировалась (значит мы на последнем/единственном)
|
|
expect(screen.getByRole("button", { name: /next slide/i })).toBeDisabled();
|
|
expect(screen.getByRole("button", { name: /previous slide/i })).toBeDisabled();
|
|
});
|
|
});
|
|
});
|