Files
twitch-panels/tests/unit/components/TextManager.test.ts
T

243 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
}
});
});