Files
sofa/packages/core/test/export.test.ts
T
jakeandClaude Opus 4.6 5f3e14b415 feat: migrate test runner from Bun to Vitest
- 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>
2026-03-22 12:03:06 -04:00

147 lines
4.8 KiB
TypeScript

import { beforeEach, describe, expect, test } from "vitest";
import {
clearAllTables,
insertEpisodeWatch,
insertMovieWatch,
insertRating,
insertStatus,
insertTitle,
insertTvShow,
insertUser,
} from "@sofa/test/db";
import { generateUserExport } from "../src/export";
beforeEach(() => clearAllTables());
describe("generateUserExport", () => {
test("exports empty data for user with no tracking", () => {
insertUser("user-1");
const result = generateUserExport("user-1", { name: "Test", email: "test@example.com" });
expect(result.version).toBe(1);
expect(result.user).toEqual({ name: "Test", email: "test@example.com" });
expect(result.library).toHaveLength(0);
expect(result.movieWatches).toHaveLength(0);
expect(result.episodeWatches).toHaveLength(0);
expect(result.ratings).toHaveLength(0);
expect(result.exportedAt).toBeTruthy();
});
test("exports library statuses", () => {
insertUser("user-1");
insertTitle({
id: "t1",
tmdbId: 550,
type: "movie",
title: "Fight Club",
releaseDate: "1999-10-15",
});
insertTitle({ id: "t2", tmdbId: 1396, type: "tv", title: "Breaking Bad" });
insertTitle({ id: "t3", tmdbId: 100, type: "movie", title: "Watchlisted" });
insertStatus("user-1", "t1", "completed");
insertStatus("user-1", "t2", "in_progress");
insertStatus("user-1", "t3", "watchlist");
const result = generateUserExport("user-1", { name: "Test", email: "t@t.com" });
expect(result.library).toHaveLength(3);
const fightClub = result.library.find((l) => l.tmdbId === 550);
expect(fightClub?.status).toBe("completed");
expect(fightClub?.type).toBe("movie");
expect(fightClub?.title).toBe("Fight Club");
expect(fightClub?.year).toBe(1999);
const bb = result.library.find((l) => l.tmdbId === 1396);
expect(bb?.status).toBe("in_progress");
expect(bb?.type).toBe("tv");
});
test("exports movie watches", () => {
insertUser("user-1");
insertTitle({
id: "t1",
tmdbId: 550,
type: "movie",
title: "Fight Club",
releaseDate: "1999-10-15",
});
const watchedAt = new Date("2025-06-15T20:00:00.000Z");
insertMovieWatch("user-1", "t1", watchedAt);
const result = generateUserExport("user-1", { name: "Test", email: "t@t.com" });
expect(result.movieWatches).toHaveLength(1);
expect(result.movieWatches[0].tmdbId).toBe(550);
expect(result.movieWatches[0].title).toBe("Fight Club");
expect(result.movieWatches[0].year).toBe(1999);
expect(result.movieWatches[0].watchedAt).toBe(watchedAt.toISOString());
});
test("exports episode watches with show context", () => {
insertUser("user-1");
const { episodeIds } = insertTvShow("tv-1", 1396, 1, 2, { title: "Breaking Bad" });
const watchedAt = new Date("2025-02-01T20:00:00.000Z");
insertEpisodeWatch("user-1", episodeIds[0], watchedAt);
const result = generateUserExport("user-1", { name: "Test", email: "t@t.com" });
expect(result.episodeWatches).toHaveLength(1);
expect(result.episodeWatches[0].showTmdbId).toBe(1396);
expect(result.episodeWatches[0].showTitle).toBe("Breaking Bad");
expect(result.episodeWatches[0].seasonNumber).toBe(1);
expect(result.episodeWatches[0].episodeNumber).toBe(1);
expect(result.episodeWatches[0].episodeName).toBe("S1E1");
expect(result.episodeWatches[0].watchedAt).toBe(watchedAt.toISOString());
});
test("exports ratings", () => {
insertUser("user-1");
insertTitle({
id: "t1",
tmdbId: 550,
type: "movie",
title: "Fight Club",
releaseDate: "1999-10-15",
});
insertRating("user-1", "t1", 5);
const result = generateUserExport("user-1", { name: "Test", email: "t@t.com" });
expect(result.ratings).toHaveLength(1);
expect(result.ratings[0].tmdbId).toBe(550);
expect(result.ratings[0].type).toBe("movie");
expect(result.ratings[0].rating).toBe(5);
});
test("does not include other users data", () => {
insertUser("user-1");
insertUser("user-2");
insertTitle({ id: "t1", tmdbId: 550, type: "movie", title: "Fight Club" });
insertTitle({ id: "t2", tmdbId: 100, type: "movie", title: "Other Movie" });
insertStatus("user-1", "t1", "completed");
insertMovieWatch("user-1", "t1");
insertRating("user-1", "t1", 5);
insertStatus("user-2", "t2", "watchlist");
insertMovieWatch("user-2", "t2");
insertRating("user-2", "t2", 3);
const result = generateUserExport("user-1", { name: "Test", email: "t@t.com" });
expect(result.library).toHaveLength(1);
expect(result.library[0].tmdbId).toBe(550);
expect(result.movieWatches).toHaveLength(1);
expect(result.movieWatches[0].tmdbId).toBe(550);
expect(result.ratings).toHaveLength(1);
expect(result.ratings[0].tmdbId).toBe(550);
});
});