mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
- Replace bun:test with Vitest across all 22 test files - Create @sofa/test package with shared setup and DB test helpers - setup.ts: vi.mock for @sofa/db/client, Bun.randomUUIDv7 polyfill - db.ts: in-memory SQLite via better-sqlite3, seed helpers - Add per-project vitest configs (packages/core, apps/web) - Add root vitest.config.ts with projects and v8 coverage - Set up @vitest/browser + Playwright for web component tests - Move validateBackupDatabase from core/backup.ts to @sofa/db/client - Derive required backup tables from schema instead of hard-coded list - Update CI workflow with Playwright install and Codecov upload - Update CLAUDE.md documentation for Vitest Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
146 lines
4.1 KiB
TypeScript
146 lines
4.1 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
|
|
import { parseSofaExport } from "../src/imports/sofa-parser";
|
|
|
|
describe("parseSofaExport", () => {
|
|
const validExport = {
|
|
version: 1,
|
|
exportedAt: "2026-01-15T12:00:00.000Z",
|
|
user: { name: "Test", email: "test@example.com" },
|
|
library: [
|
|
{
|
|
tmdbId: 550,
|
|
title: "Fight Club",
|
|
year: 1999,
|
|
type: "movie",
|
|
status: "completed",
|
|
addedAt: "2025-01-15T10:30:00.000Z",
|
|
},
|
|
{
|
|
tmdbId: 1396,
|
|
title: "Breaking Bad",
|
|
year: 2008,
|
|
type: "tv",
|
|
status: "in_progress",
|
|
addedAt: "2025-02-01T08:00:00.000Z",
|
|
},
|
|
],
|
|
movieWatches: [
|
|
{
|
|
tmdbId: 550,
|
|
title: "Fight Club",
|
|
year: 1999,
|
|
watchedAt: "2025-01-15T10:30:00.000Z",
|
|
},
|
|
],
|
|
episodeWatches: [
|
|
{
|
|
showTmdbId: 1396,
|
|
showTitle: "Breaking Bad",
|
|
showYear: 2008,
|
|
seasonNumber: 1,
|
|
episodeNumber: 1,
|
|
episodeName: "Pilot",
|
|
watchedAt: "2025-02-01T20:00:00.000Z",
|
|
},
|
|
],
|
|
ratings: [
|
|
{
|
|
tmdbId: 550,
|
|
title: "Fight Club",
|
|
year: 1999,
|
|
type: "movie",
|
|
rating: 5,
|
|
ratedAt: "2025-01-15T10:35:00.000Z",
|
|
},
|
|
],
|
|
};
|
|
|
|
test("parses a valid Sofa export", () => {
|
|
const result = parseSofaExport(validExport);
|
|
|
|
expect(result.data.source).toBe("sofa");
|
|
expect(result.data.movies).toHaveLength(1);
|
|
expect(result.data.episodes).toHaveLength(1);
|
|
expect(result.data.watchlist).toHaveLength(2);
|
|
expect(result.data.ratings).toHaveLength(1);
|
|
expect(result.warnings).toHaveLength(0);
|
|
});
|
|
|
|
test("maps movie watches correctly", () => {
|
|
const result = parseSofaExport(validExport);
|
|
const movie = result.data.movies[0];
|
|
|
|
expect(movie.tmdbId).toBe(550);
|
|
expect(movie.title).toBe("Fight Club");
|
|
expect(movie.year).toBe(1999);
|
|
expect(movie.watchedAt).toBe("2025-01-15T10:30:00.000Z");
|
|
});
|
|
|
|
test("maps episode watches correctly", () => {
|
|
const result = parseSofaExport(validExport);
|
|
const ep = result.data.episodes[0];
|
|
|
|
expect(ep.showTmdbId).toBe(1396);
|
|
expect(ep.showTitle).toBe("Breaking Bad");
|
|
expect(ep.seasonNumber).toBe(1);
|
|
expect(ep.episodeNumber).toBe(1);
|
|
expect(ep.watchedAt).toBe("2025-02-01T20:00:00.000Z");
|
|
});
|
|
|
|
test("preserves status and addedAt on library items", () => {
|
|
const result = parseSofaExport(validExport);
|
|
|
|
const movie = result.data.watchlist[0];
|
|
expect(movie.status).toBe("completed");
|
|
expect(movie.addedAt).toBe("2025-01-15T10:30:00.000Z");
|
|
|
|
const show = result.data.watchlist[1];
|
|
expect(show.status).toBe("in_progress");
|
|
expect(show.addedAt).toBe("2025-02-01T08:00:00.000Z");
|
|
});
|
|
|
|
test("maps ratings correctly", () => {
|
|
const result = parseSofaExport(validExport);
|
|
const rating = result.data.ratings[0];
|
|
|
|
expect(rating.tmdbId).toBe(550);
|
|
expect(rating.rating).toBe(5);
|
|
expect(rating.type).toBe("movie");
|
|
expect(rating.ratedAt).toBe("2025-01-15T10:35:00.000Z");
|
|
});
|
|
|
|
test("handles empty export", () => {
|
|
const result = parseSofaExport({
|
|
version: 1,
|
|
exportedAt: "2026-01-15T12:00:00.000Z",
|
|
user: { name: "Test", email: "test@example.com" },
|
|
library: [],
|
|
movieWatches: [],
|
|
episodeWatches: [],
|
|
ratings: [],
|
|
});
|
|
|
|
expect(result.data.movies).toHaveLength(0);
|
|
expect(result.data.episodes).toHaveLength(0);
|
|
expect(result.data.watchlist).toHaveLength(0);
|
|
expect(result.data.ratings).toHaveLength(0);
|
|
expect(result.warnings).toHaveLength(0);
|
|
});
|
|
|
|
test("rejects invalid data with warnings", () => {
|
|
const result = parseSofaExport({ version: 2, bad: true });
|
|
|
|
expect(result.data.movies).toHaveLength(0);
|
|
expect(result.warnings.length).toBeGreaterThan(0);
|
|
expect(result.warnings[0]).toContain("Invalid Sofa export file");
|
|
});
|
|
|
|
test("rejects non-object input", () => {
|
|
const result = parseSofaExport("not json");
|
|
|
|
expect(result.warnings.length).toBeGreaterThan(0);
|
|
expect(result.warnings[0]).toContain("Invalid Sofa export file");
|
|
});
|
|
});
|