test: update coverage, add some tests
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
import TextManager from "$components/text/TextManager.svelte";
|
||||
import { fireEvent, render, screen } from "@testing-library/svelte";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
// Mock the stores
|
||||
vi.mock("$stores/panelStore", () => ({
|
||||
textSettingsStore: {
|
||||
subscribe: vi.fn((callback) => {
|
||||
callback({
|
||||
fontSize: 18,
|
||||
fontFamily: "Arial",
|
||||
color: "#ffffff",
|
||||
textAlign: "center",
|
||||
paddingX: 10,
|
||||
verticalOffset: 0,
|
||||
});
|
||||
return () => {}; // unsubscribe function
|
||||
}),
|
||||
update: vi.fn(),
|
||||
},
|
||||
updateAllTextSettings: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("TextManager", () => {
|
||||
let mockOnTextAdd: (text: string, settings?: any) => void;
|
||||
let mockOnTextUpdate: (id: string, text: string) => void;
|
||||
let mockOnTextDelete: (id: string) => void;
|
||||
|
||||
beforeEach(() => {
|
||||
mockOnTextAdd = vi.fn();
|
||||
mockOnTextUpdate = vi.fn();
|
||||
mockOnTextDelete = vi.fn();
|
||||
});
|
||||
|
||||
it("should render with empty text list", () => {
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: [],
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should render with existing texts", () => {
|
||||
const mockTexts = [
|
||||
{ id: "text-1", text: "First text" },
|
||||
{ id: "text-2", text: "Second text" },
|
||||
];
|
||||
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: mockTexts,
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should call onTextAdd when add text form is submitted", async () => {
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: [],
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Find text input and add button
|
||||
const textInputs = container.querySelectorAll('input[type="text"], textarea');
|
||||
const buttons = screen.getAllByRole("button");
|
||||
|
||||
if (textInputs.length > 0 && buttons.length > 0) {
|
||||
await fireEvent.input(textInputs[0], { target: { value: "New text" } });
|
||||
await fireEvent.click(buttons[0]);
|
||||
|
||||
expect(mockOnTextAdd).toHaveBeenCalledWith("New text", expect.any(Object));
|
||||
}
|
||||
});
|
||||
|
||||
it("should show error for empty text", async () => {
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: [],
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Find add button and click without entering text
|
||||
const buttons = screen.getAllByRole("button");
|
||||
if (buttons.length > 0) {
|
||||
await fireEvent.click(buttons[0]);
|
||||
|
||||
// Should not call onTextAdd for empty text
|
||||
expect(mockOnTextAdd).not.toHaveBeenCalled();
|
||||
}
|
||||
});
|
||||
|
||||
it("should handle text update", async () => {
|
||||
const mockTexts = [{ id: "text-1", text: "Original text" }];
|
||||
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: mockTexts,
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Find text inputs for existing texts
|
||||
const textInputs = container.querySelectorAll('input[type="text"], textarea');
|
||||
if (textInputs.length > 0) {
|
||||
await fireEvent.input(textInputs[0], { target: { value: "Updated text" } });
|
||||
|
||||
// Should call onTextUpdate with the text ID and new text
|
||||
expect(mockOnTextUpdate).toHaveBeenCalledWith("text-1", "Updated text");
|
||||
}
|
||||
});
|
||||
|
||||
it("should handle text deletion", async () => {
|
||||
const mockTexts = [{ id: "text-1", text: "Text to delete" }];
|
||||
|
||||
render(TextManager, {
|
||||
props: {
|
||||
texts: mockTexts,
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Find delete button (might be an X button or similar)
|
||||
const buttons = screen.getAllByRole("button");
|
||||
const deleteButton = buttons.find(
|
||||
(button) =>
|
||||
button.textContent?.includes("Delete") ||
|
||||
button.textContent?.includes("Remove") ||
|
||||
button.textContent?.includes("×") ||
|
||||
button.textContent?.includes("X"),
|
||||
);
|
||||
|
||||
if (deleteButton) {
|
||||
await fireEvent.click(deleteButton);
|
||||
expect(mockOnTextDelete).toHaveBeenCalledWith("text-1");
|
||||
}
|
||||
});
|
||||
|
||||
it("should handle font size changes", async () => {
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: [],
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Find font size input (number input)
|
||||
const numberInputs = container.querySelectorAll('input[type="number"]');
|
||||
if (numberInputs.length > 0) {
|
||||
await fireEvent.input(numberInputs[0], { target: { value: "24" } });
|
||||
|
||||
// Font size change should be handled in the component
|
||||
expect(container).toBeTruthy(); // Basic check that component still renders
|
||||
}
|
||||
});
|
||||
|
||||
it("should handle color changes", async () => {
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: [],
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Find color input
|
||||
const colorInputs = container.querySelectorAll('input[type="color"]');
|
||||
if (colorInputs.length > 0) {
|
||||
await fireEvent.input(colorInputs[0], { target: { value: "#ff0000" } });
|
||||
|
||||
// Color change should be handled in the component
|
||||
expect(container).toBeTruthy(); // Basic check that component still renders
|
||||
}
|
||||
});
|
||||
|
||||
it("should handle text alignment changes", async () => {
|
||||
const { container } = render(TextManager, {
|
||||
props: {
|
||||
texts: [],
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Look for alignment buttons or radio buttons
|
||||
const radioButtons = screen.getAllByRole("radio");
|
||||
if (radioButtons.length > 0) {
|
||||
await fireEvent.click(radioButtons[0]);
|
||||
expect(container).toBeTruthy(); // Basic check that component still renders
|
||||
}
|
||||
});
|
||||
|
||||
it("should call updateAllTextSettings when update all button is clicked", async () => {
|
||||
const { updateAllTextSettings } = await import("$stores/panelStore");
|
||||
|
||||
render(TextManager, {
|
||||
props: {
|
||||
texts: [],
|
||||
onTextAdd: mockOnTextAdd,
|
||||
onTextUpdate: mockOnTextUpdate,
|
||||
onTextDelete: mockOnTextDelete,
|
||||
},
|
||||
});
|
||||
|
||||
// Look for "Update All" or similar button
|
||||
const buttons = screen.getAllByRole("button");
|
||||
const updateAllButton = buttons.find(
|
||||
(button) =>
|
||||
button.textContent?.includes("Update All") ||
|
||||
button.textContent?.includes("Apply to All") ||
|
||||
button.textContent?.includes("Сохранить"),
|
||||
);
|
||||
|
||||
if (updateAllButton) {
|
||||
await fireEvent.click(updateAllButton);
|
||||
expect(updateAllTextSettings).toHaveBeenCalled();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user