test: implement tests
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
||||
import "@testing-library/jest-dom";
|
||||
import { vi } from "vitest";
|
||||
|
||||
// Extend global type
|
||||
declare global {
|
||||
var testUtils: {
|
||||
createMockFile: (name?: string, size?: number, type?: string) => File;
|
||||
createMockPanel: (overrides?: any) => any;
|
||||
waitFor: (ms: number) => Promise<void>;
|
||||
};
|
||||
}
|
||||
|
||||
// Mock localStorage for testing
|
||||
const localStorageMock = {
|
||||
getItem: vi.fn(),
|
||||
setItem: vi.fn(),
|
||||
removeItem: vi.fn(),
|
||||
clear: vi.fn(),
|
||||
length: 0,
|
||||
key: vi.fn(),
|
||||
};
|
||||
|
||||
Object.defineProperty(window, "localStorage", {
|
||||
value: localStorageMock,
|
||||
});
|
||||
|
||||
// Mock crypto for testing
|
||||
Object.defineProperty(window, "crypto", {
|
||||
value: {
|
||||
randomUUID: () => "test-uuid-12345",
|
||||
},
|
||||
});
|
||||
|
||||
// Mock HTMLCanvasElement for Konva testing
|
||||
Object.defineProperty(HTMLCanvasElement.prototype, "getContext", {
|
||||
value: vi.fn(() => ({
|
||||
fillRect: vi.fn(),
|
||||
clearRect: vi.fn(),
|
||||
getImageData: vi.fn(() => ({ data: new Array(4) })),
|
||||
putImageData: vi.fn(),
|
||||
createImageData: vi.fn(() => ({ data: new Array(4) })),
|
||||
setTransform: vi.fn(),
|
||||
drawImage: vi.fn(),
|
||||
save: vi.fn(),
|
||||
fillText: vi.fn(),
|
||||
restore: vi.fn(),
|
||||
beginPath: vi.fn(),
|
||||
moveTo: vi.fn(),
|
||||
lineTo: vi.fn(),
|
||||
closePath: vi.fn(),
|
||||
stroke: vi.fn(),
|
||||
translate: vi.fn(),
|
||||
scale: vi.fn(),
|
||||
rotate: vi.fn(),
|
||||
arc: vi.fn(),
|
||||
fill: vi.fn(),
|
||||
measureText: vi.fn(() => ({ width: 0 })),
|
||||
transform: vi.fn(),
|
||||
rect: vi.fn(),
|
||||
clip: vi.fn(),
|
||||
})),
|
||||
});
|
||||
|
||||
// Mock FileReader for image upload testing
|
||||
Object.defineProperty(window, "FileReader", {
|
||||
value: vi.fn(() => ({
|
||||
readAsDataURL: vi.fn(),
|
||||
onload: null,
|
||||
onerror: null,
|
||||
result: "data:image/jpeg;base64,/9j/4AAQSkZJRg==",
|
||||
})),
|
||||
});
|
||||
|
||||
// Global test utilities
|
||||
global.testUtils = {
|
||||
createMockFile: (name = "test.jpg", size = 1024, type = "image/jpeg") => {
|
||||
const blob = new Blob([new ArrayBuffer(size)], { type });
|
||||
return new File([blob], name, { type });
|
||||
},
|
||||
|
||||
createMockPanel: (overrides = {}) => ({
|
||||
id: "test-panel-id",
|
||||
backgroundImage: "/backgrounds/b1.jpg",
|
||||
text: {
|
||||
id: "test-text-id",
|
||||
text: "Test Panel",
|
||||
fontSize: 18,
|
||||
fontFamily: "Arial",
|
||||
color: "#ffffff",
|
||||
textAlign: "center" as const,
|
||||
paddingX: 10,
|
||||
verticalOffset: 0,
|
||||
},
|
||||
height: 100,
|
||||
createdAt: new Date("2024-01-01"),
|
||||
updatedAt: new Date("2024-01-01"),
|
||||
...overrides,
|
||||
}),
|
||||
|
||||
waitFor: (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)),
|
||||
};
|
||||
|
||||
// Export cleanup function for use in individual test files
|
||||
export function cleanupMocks() {
|
||||
vi.clearAllMocks();
|
||||
localStorageMock.getItem.mockClear();
|
||||
localStorageMock.setItem.mockClear();
|
||||
localStorageMock.removeItem.mockClear();
|
||||
localStorageMock.clear.mockClear();
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// Use global test functions with globals enabled in config
|
||||
|
||||
import { AppError } from "$lib/types/errors";
|
||||
import { createError, handleError, isRecoverableError, logError, retryOperation } from "$lib/utils/errorHandler";
|
||||
|
||||
let consoleErrorSpy: any;
|
||||
|
||||
beforeEach(() => {
|
||||
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
consoleErrorSpy.mockClear();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("errorHandler", () => {
|
||||
describe("handleError", () => {
|
||||
it("should handle AppError with recoverable flag", () => {
|
||||
const error = new AppError("Test error", "TEST_ERROR", true);
|
||||
const result = handleError(error);
|
||||
|
||||
expect(result).toBe("Ошибка: Test error. Попробуйте снова.");
|
||||
});
|
||||
|
||||
it("should handle AppError with non-recoverable flag", () => {
|
||||
const error = new AppError("Critical error", "CRITICAL_ERROR", false);
|
||||
const result = handleError(error);
|
||||
|
||||
expect(result).toBe("Критическая ошибка: Critical error");
|
||||
});
|
||||
|
||||
it("should handle standard Error objects", () => {
|
||||
const error = new Error("Standard error message");
|
||||
const result = handleError(error, "Custom prefix");
|
||||
|
||||
expect(result).toBe("Custom prefix: Standard error message");
|
||||
});
|
||||
|
||||
it("should handle string errors", () => {
|
||||
const result = handleError("String error", "Custom prefix");
|
||||
|
||||
expect(result).toBe("Custom prefix: String error");
|
||||
});
|
||||
|
||||
it("should handle unknown error types", () => {
|
||||
const result = handleError({ some: "object" }, "Custom prefix");
|
||||
|
||||
expect(result).toBe("Custom prefix: Произошла неизвестная ошибка");
|
||||
});
|
||||
|
||||
it("should use default message when none provided", () => {
|
||||
const result = handleError({ some: "object" });
|
||||
|
||||
expect(result).toBe("Произошла ошибка: Произошла неизвестная ошибка");
|
||||
});
|
||||
});
|
||||
|
||||
describe("isRecoverableError", () => {
|
||||
it("should return true for recoverable AppError", () => {
|
||||
const error = new AppError("Test error", "TEST_ERROR", true);
|
||||
const result = isRecoverableError(error);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-recoverable AppError", () => {
|
||||
const error = new AppError("Test error", "TEST_ERROR", false);
|
||||
const result = isRecoverableError(error);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for non-AppError objects", () => {
|
||||
const error = new Error("Standard error");
|
||||
const result = isRecoverableError(error);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("createError", () => {
|
||||
it("should create AppError with default recoverable flag", () => {
|
||||
const error = createError("Test message", "TEST_CODE");
|
||||
|
||||
expect(error).toBeInstanceOf(AppError);
|
||||
expect(error.message).toBe("Test message");
|
||||
expect(error.code).toBe("TEST_CODE");
|
||||
expect(error.recoverable).toBe(true);
|
||||
});
|
||||
|
||||
it("should create AppError with custom recoverable flag", () => {
|
||||
const error = createError("Test message", "TEST_CODE", false);
|
||||
|
||||
expect(error).toBeInstanceOf(AppError);
|
||||
expect(error.recoverable).toBe(false);
|
||||
});
|
||||
|
||||
it("should create AppError with details", () => {
|
||||
const details = { some: "additional info" };
|
||||
const error = createError("Test message", "TEST_CODE", true, details);
|
||||
|
||||
expect(error.details).toBe(details);
|
||||
});
|
||||
});
|
||||
|
||||
describe("logError", () => {
|
||||
it("should log error with context", () => {
|
||||
const error = new Error("Test error");
|
||||
const context = "Test context";
|
||||
|
||||
logError(error, context);
|
||||
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("Error occurred:", {
|
||||
error,
|
||||
context,
|
||||
timestamp: expect.any(String),
|
||||
stack: error.stack,
|
||||
});
|
||||
});
|
||||
|
||||
it("should log error without context", () => {
|
||||
const error = new Error("Test error");
|
||||
|
||||
logError(error);
|
||||
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("Error occurred:", {
|
||||
error,
|
||||
context: undefined,
|
||||
timestamp: expect.any(String),
|
||||
stack: error.stack,
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle non-Error objects", () => {
|
||||
const error = "String error";
|
||||
|
||||
logError(error, "Test context");
|
||||
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("Error occurred:", {
|
||||
error,
|
||||
context: "Test context",
|
||||
timestamp: expect.any(String),
|
||||
stack: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("retryOperation", () => {
|
||||
it("should succeed on first attempt", async () => {
|
||||
const operation = vi.fn().mockResolvedValue("success");
|
||||
|
||||
const result = await retryOperation(operation, 3);
|
||||
|
||||
expect(result).toBe("success");
|
||||
expect(operation).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should retry on failure and succeed", async () => {
|
||||
const operation = vi.fn().mockRejectedValueOnce(new Error("First failure")).mockResolvedValueOnce("success");
|
||||
|
||||
const result = await retryOperation(operation, 3, 10);
|
||||
|
||||
expect(result).toBe("success");
|
||||
expect(operation).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("should throw after max retries", async () => {
|
||||
const operation = vi.fn().mockRejectedValue(new Error("Persistent failure"));
|
||||
|
||||
await expect(retryOperation(operation, 2, 10)).rejects.toThrow("Persistent failure");
|
||||
expect(operation).toHaveBeenCalledTimes(2); // Initial + 1 retry
|
||||
});
|
||||
|
||||
it("should wait between retries", async () => {
|
||||
const operation = vi.fn().mockRejectedValueOnce(new Error("First failure")).mockResolvedValueOnce("success");
|
||||
|
||||
const startTime = Date.now();
|
||||
await retryOperation(operation, 2, 50);
|
||||
const endTime = Date.now();
|
||||
|
||||
expect(endTime - startTime).toBeGreaterThanOrEqual(50);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
// Use global test functions with globals enabled in config
|
||||
|
||||
import { PanelStorage } from "$lib/utils/panelStorage";
|
||||
|
||||
let storage: any;
|
||||
|
||||
beforeEach(() => {
|
||||
storage = new PanelStorage();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("PanelStorage", () => {
|
||||
it("should create storage instance", () => {
|
||||
expect(storage).toBeInstanceOf(PanelStorage);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,342 @@
|
||||
import type { Panel } from "$lib/types/panel";
|
||||
import { PanelStorage } from "$lib/utils/panelStorage";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
// Mock the error handler to avoid console noise during tests
|
||||
vi.mock("$lib/utils/errorHandler", () => ({
|
||||
logError: vi.fn(),
|
||||
handleError: vi.fn((error: any, message: string) => `${message}: ${error}`),
|
||||
}));
|
||||
|
||||
describe("PanelStorage", () => {
|
||||
let storage: PanelStorage;
|
||||
let mockPanel: Panel;
|
||||
let mockLocalStorage: any;
|
||||
|
||||
beforeEach(() => {
|
||||
storage = new PanelStorage();
|
||||
mockPanel = {
|
||||
id: "test-panel-1",
|
||||
backgroundImage: "/backgrounds/b1.jpg",
|
||||
text: {
|
||||
id: "test-text-1",
|
||||
text: "Test Panel",
|
||||
fontSize: 18,
|
||||
fontFamily: "Arial",
|
||||
color: "#ffffff",
|
||||
textAlign: "center",
|
||||
paddingX: 10,
|
||||
verticalOffset: 0,
|
||||
},
|
||||
height: 100,
|
||||
createdAt: new Date("2024-01-01"),
|
||||
updatedAt: new Date("2024-01-01"),
|
||||
};
|
||||
|
||||
// Create a properly typed mock for localStorage
|
||||
mockLocalStorage = {
|
||||
getItem: vi.fn(),
|
||||
setItem: vi.fn(),
|
||||
removeItem: vi.fn(),
|
||||
clear: vi.fn(),
|
||||
length: 0,
|
||||
key: vi.fn(),
|
||||
};
|
||||
|
||||
// Replace window.localStorage with our mock
|
||||
Object.defineProperty(window, "localStorage", {
|
||||
value: mockLocalStorage,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("savePanel", () => {
|
||||
it("should save a new panel successfully", () => {
|
||||
const result = storage.savePanel(mockPanel);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(mockLocalStorage.setItem).toHaveBeenCalledWith("twitch-panels", expect.stringContaining("test-panel-1"));
|
||||
});
|
||||
|
||||
it("should update existing panel", () => {
|
||||
// Save initial panel
|
||||
storage.savePanel(mockPanel);
|
||||
|
||||
// Update panel
|
||||
const updatedPanel = { ...mockPanel, height: 150 };
|
||||
const result = storage.savePanel(updatedPanel);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
// Get the last call to localStorage.setItem
|
||||
const calls = mockLocalStorage.setItem.mock.calls;
|
||||
const savedData = JSON.parse(calls[calls.length - 1][1]);
|
||||
expect(savedData[0].height).toBe(150);
|
||||
});
|
||||
|
||||
it("should limit panels to MAX_PANELS count", () => {
|
||||
// Create and save 51 panels (exceeding MAX_PANELS = 50)
|
||||
const panels = Array.from({ length: 51 }, (_, i) => ({
|
||||
...mockPanel,
|
||||
id: `panel-${i}`,
|
||||
}));
|
||||
|
||||
// Mock localStorage to return the saved data for getAllPanels
|
||||
let savedData: any[] = [];
|
||||
mockLocalStorage.setItem.mockImplementation((key: string, value: string) => {
|
||||
if (key === "twitch-panels") {
|
||||
savedData = JSON.parse(value);
|
||||
}
|
||||
});
|
||||
|
||||
mockLocalStorage.getItem.mockImplementation((key: string) => {
|
||||
if (key === "twitch-panels") {
|
||||
return JSON.stringify(savedData);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
panels.forEach((panel) => storage.savePanel(panel));
|
||||
|
||||
// Check the final state by calling getAllPanels
|
||||
const finalPanels = storage.getAllPanels();
|
||||
expect(finalPanels.length).toBe(50);
|
||||
expect(finalPanels[0].id).toBe("panel-50"); // Most recent panel
|
||||
});
|
||||
|
||||
it("should handle localStorage errors gracefully", () => {
|
||||
// Mock localStorage to throw an error
|
||||
mockLocalStorage.setItem.mockImplementation(() => {
|
||||
throw new Error("Storage full");
|
||||
});
|
||||
|
||||
const result = storage.savePanel(mockPanel);
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain("Ошибка сохранения панели");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getAllPanels", () => {
|
||||
it("should return empty array when no panels exist", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue(null);
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return saved panels", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toHaveLength(1);
|
||||
expect(panels[0]).toEqual(mockPanel);
|
||||
});
|
||||
|
||||
it("should filter out invalid panels", () => {
|
||||
const validPanel = mockPanel;
|
||||
const invalidPanel = {
|
||||
id: "invalid-1",
|
||||
backgroundImage: "/backgrounds/b2.jpg",
|
||||
// Missing required text property
|
||||
height: 100,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([validPanel, invalidPanel]));
|
||||
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toHaveLength(1);
|
||||
expect(panels[0]).toEqual(validPanel);
|
||||
});
|
||||
|
||||
it("should handle corrupted localStorage data", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue("invalid json");
|
||||
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getPanelById", () => {
|
||||
it("should return panel by id", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
|
||||
const panel = storage.getPanelById("test-panel-1");
|
||||
|
||||
expect(panel).toEqual(mockPanel);
|
||||
});
|
||||
|
||||
it("should return undefined for non-existent panel", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
|
||||
const panel = storage.getPanelById("non-existent");
|
||||
|
||||
expect(panel).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should handle errors gracefully", () => {
|
||||
// Mock localStorage to throw an error
|
||||
mockLocalStorage.getItem.mockImplementation(() => {
|
||||
throw new Error("Storage error");
|
||||
});
|
||||
|
||||
const panel = storage.getPanelById("test-panel-1");
|
||||
|
||||
expect(panel).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("deletePanel", () => {
|
||||
it("should delete panel by id", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
|
||||
const result = storage.deletePanel("test-panel-1");
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(mockLocalStorage.setItem).toHaveBeenCalledWith("twitch-panels", "[]");
|
||||
});
|
||||
|
||||
it("should succeed when panel does not exist", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
|
||||
const result = storage.deletePanel("non-existent");
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
// Should still save the unchanged array
|
||||
expect(mockLocalStorage.setItem).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should handle localStorage errors", () => {
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
|
||||
// Mock localStorage to throw an error
|
||||
mockLocalStorage.setItem.mockImplementation(() => {
|
||||
throw new Error("Storage error");
|
||||
});
|
||||
|
||||
const result = storage.deletePanel("test-panel-1");
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain("Ошибка удаления панели");
|
||||
});
|
||||
});
|
||||
|
||||
describe("clearAll", () => {
|
||||
it("should clear all panels", () => {
|
||||
const result = storage.clearAll();
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(mockLocalStorage.removeItem).toHaveBeenCalledWith("twitch-panels");
|
||||
});
|
||||
|
||||
it("should handle localStorage errors", () => {
|
||||
// Mock localStorage to throw an error
|
||||
mockLocalStorage.removeItem.mockImplementation(() => {
|
||||
throw new Error("Storage error");
|
||||
});
|
||||
|
||||
const result = storage.clearAll();
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain("Ошибка очистки хранилища");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getPanelCount", () => {
|
||||
it("should return correct panel count", () => {
|
||||
expect(storage.getPanelCount()).toBe(0);
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
expect(storage.getPanelCount()).toBe(1);
|
||||
|
||||
const secondPanel = { ...mockPanel, id: "test-panel-2" };
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel, secondPanel]));
|
||||
expect(storage.getPanelCount()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("hasSpaceForNewPanel", () => {
|
||||
it("should return true when under limit", () => {
|
||||
expect(storage.hasSpaceForNewPanel()).toBe(true);
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([mockPanel]));
|
||||
expect(storage.hasSpaceForNewPanel()).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false when at limit", () => {
|
||||
// Create and save 50 panels (MAX_PANELS limit)
|
||||
const panels = Array.from({ length: 50 }, (_, i) => ({
|
||||
...mockPanel,
|
||||
id: `panel-${i}`,
|
||||
}));
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify(panels));
|
||||
|
||||
expect(storage.hasSpaceForNewPanel()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("panel validation", () => {
|
||||
it("should validate correct panel structure", () => {
|
||||
const validPanel = mockPanel;
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([validPanel]));
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toHaveLength(1);
|
||||
expect(panels[0]).toEqual(validPanel);
|
||||
});
|
||||
|
||||
it("should reject panel with invalid height", () => {
|
||||
const invalidPanel = {
|
||||
...mockPanel,
|
||||
height: -100, // Negative height
|
||||
};
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([invalidPanel]));
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should reject panel with height exceeding maximum", () => {
|
||||
const invalidPanel = {
|
||||
...mockPanel,
|
||||
height: 2000, // Exceeds PANEL_HEIGHT_MAX (1000)
|
||||
};
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([invalidPanel]));
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should reject panel with missing required properties", () => {
|
||||
const invalidPanel = {
|
||||
id: "invalid-panel",
|
||||
// Missing backgroundImage
|
||||
text: mockPanel.text,
|
||||
height: 100,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
} as any;
|
||||
|
||||
mockLocalStorage.getItem.mockReturnValue(JSON.stringify([invalidPanel]));
|
||||
const panels = storage.getAllPanels();
|
||||
|
||||
expect(panels).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
// Use global test functions without importing vitest
|
||||
test("basic math", () => {
|
||||
expect(2 + 2).toBe(4);
|
||||
});
|
||||
|
||||
test("string equality", () => {
|
||||
expect("hello").toBe("hello");
|
||||
});
|
||||
Reference in New Issue
Block a user