241 lines
6.5 KiB
TypeScript
241 lines
6.5 KiB
TypeScript
import { describe, it, expect, vi } from "vitest";
|
|
import { render, screen, fireEvent } from "@testing-library/svelte";
|
|
import SearchBar from "./SearchBar.svelte";
|
|
|
|
describe("SearchBar", () => {
|
|
describe("Rendering Tests", () => {
|
|
it("should render input field with placeholder", () => {
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search test...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search test...");
|
|
expect(input).toBeTruthy();
|
|
});
|
|
|
|
it("should render search icon", () => {
|
|
const { container } = render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const svg = container.querySelector("svg");
|
|
expect(svg).toBeTruthy();
|
|
const classString = svg?.getAttribute("class") || "";
|
|
expect(classString).toContain("w-5");
|
|
expect(classString).toContain("h-5");
|
|
});
|
|
|
|
it("should display current value in input", () => {
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "test query",
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = screen.getByDisplayValue("test query") as HTMLInputElement;
|
|
expect(input.value).toBe("test query");
|
|
});
|
|
|
|
it("should apply custom className", () => {
|
|
const { container } = render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
className: "custom-class",
|
|
},
|
|
});
|
|
|
|
const wrapper = container.firstChild as HTMLElement;
|
|
expect(wrapper.className).toContain("custom-class");
|
|
});
|
|
|
|
it("should have proper accessibility attributes", () => {
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search genres...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search genres...") as HTMLInputElement;
|
|
expect(input.type).toBe("text");
|
|
});
|
|
});
|
|
|
|
describe("Interaction Tests", () => {
|
|
it("should call onInput callback when user types", () => {
|
|
const onInput = vi.fn();
|
|
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput,
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search...") as HTMLInputElement;
|
|
fireEvent.input(input, { target: { value: "test" } });
|
|
|
|
expect(onInput).toHaveBeenCalled();
|
|
});
|
|
|
|
it("should pass correct value to onInput callback", () => {
|
|
const onInput = vi.fn();
|
|
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput,
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search...") as HTMLInputElement;
|
|
fireEvent.input(input, { target: { value: "album search" } });
|
|
|
|
// Check that callback was called with the typed value
|
|
expect(onInput).toHaveBeenCalledWith("album search");
|
|
});
|
|
|
|
it("should handle multiple input changes", () => {
|
|
const onInput = vi.fn();
|
|
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput,
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search...") as HTMLInputElement;
|
|
fireEvent.input(input, { target: { value: "test" } });
|
|
fireEvent.input(input, { target: { value: "testing" } });
|
|
|
|
expect(onInput).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("Edge Cases", () => {
|
|
it("should handle empty search query", () => {
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search...") as HTMLInputElement;
|
|
expect(input.value).toBe("");
|
|
});
|
|
|
|
it("should handle special characters in value", () => {
|
|
render(SearchBar, {
|
|
props: {
|
|
value: '@$%^&*()',
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = screen.getByDisplayValue("@$%^&*()") as HTMLInputElement;
|
|
expect(input.value).toBe("@$%^&*()");
|
|
});
|
|
|
|
it("should handle very long input values", () => {
|
|
const longValue = "a".repeat(500);
|
|
render(SearchBar, {
|
|
props: {
|
|
value: longValue,
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = screen.getByDisplayValue(longValue) as HTMLInputElement;
|
|
expect(input.value).toBe(longValue);
|
|
});
|
|
|
|
it("should work with numeric input", () => {
|
|
const onInput = vi.fn();
|
|
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput,
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search...") as HTMLInputElement;
|
|
fireEvent.input(input, { target: { value: "12345" } });
|
|
|
|
expect(onInput).toHaveBeenCalledWith("12345");
|
|
});
|
|
});
|
|
|
|
describe("Requirement Tests", () => {
|
|
it("should support searching with spaces", () => {
|
|
const onInput = vi.fn();
|
|
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput,
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText("Search...") as HTMLInputElement;
|
|
fireEvent.input(input, { target: { value: "search multiple words" } });
|
|
|
|
expect(onInput).toHaveBeenCalledWith("search multiple words");
|
|
});
|
|
|
|
it("should work as controlled component with value prop", () => {
|
|
render(SearchBar, {
|
|
props: {
|
|
value: "initial value",
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = screen.getByDisplayValue("initial value") as HTMLInputElement;
|
|
expect(input.value).toBe("initial value");
|
|
});
|
|
|
|
it("should have proper styling for dark theme", () => {
|
|
const { container } = render(SearchBar, {
|
|
props: {
|
|
value: "",
|
|
placeholder: "Search...",
|
|
onInput: vi.fn(),
|
|
},
|
|
});
|
|
|
|
const input = container.querySelector("input");
|
|
expect(input).toBeTruthy();
|
|
const classString = input?.getAttribute("class") || "";
|
|
expect(classString.length).toBeGreaterThan(0);
|
|
expect(classString).toContain("bg-");
|
|
expect(classString).toContain("text-white");
|
|
expect(classString).toContain("placeholder-gray");
|
|
});
|
|
});
|
|
});
|