mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 01:35:39 -04:00
- Rename `lib/test-preload.ts` → `test/preload.ts` and `lib/test-utils.ts` → `test/sqlite.ts` - Update `bunfig.toml` preload path to `./test/preload.ts` - Update all service test imports from `@/lib/test-utils` to `@/test/sqlite`
225 lines
4.7 KiB
TypeScript
225 lines
4.7 KiB
TypeScript
import { Database } from "bun:sqlite";
|
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
import { migrate } from "drizzle-orm/bun-sqlite/migrator";
|
|
import * as schema from "@/lib/db/schema";
|
|
|
|
const {
|
|
user,
|
|
titles,
|
|
seasons,
|
|
episodes,
|
|
userMovieWatches,
|
|
userEpisodeWatches,
|
|
userTitleStatus,
|
|
userRatings,
|
|
availabilityOffers,
|
|
titleRecommendations,
|
|
integrations,
|
|
} = schema;
|
|
|
|
export const testClient = new Database(":memory:");
|
|
testClient.run("PRAGMA foreign_keys = ON");
|
|
export const testDb = drizzle({ client: testClient, schema });
|
|
|
|
export function applyMigrations() {
|
|
migrate(testDb, { migrationsFolder: "./drizzle" });
|
|
}
|
|
|
|
export function clearAllTables() {
|
|
const tables = testClient
|
|
.query(
|
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE '__drizzle%'",
|
|
)
|
|
.all() as { name: string }[];
|
|
testClient.run("PRAGMA foreign_keys = OFF");
|
|
for (const { name } of tables) {
|
|
testClient.run(`DELETE FROM "${name}"`);
|
|
}
|
|
testClient.run("PRAGMA foreign_keys = ON");
|
|
}
|
|
|
|
const now = new Date();
|
|
|
|
export function insertUser(id = "user-1") {
|
|
testDb
|
|
.insert(user)
|
|
.values({
|
|
id,
|
|
name: "Test User",
|
|
email: `${id}@test.com`,
|
|
emailVerified: true,
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
})
|
|
.run();
|
|
return id;
|
|
}
|
|
|
|
export function insertTitle(
|
|
overrides: {
|
|
id?: string;
|
|
tmdbId?: number;
|
|
tvdbId?: number;
|
|
type?: "movie" | "tv";
|
|
title?: string;
|
|
} = {},
|
|
) {
|
|
const id = overrides.id ?? "title-1";
|
|
testDb
|
|
.insert(titles)
|
|
.values({
|
|
id,
|
|
tmdbId: overrides.tmdbId ?? 12345,
|
|
tvdbId: overrides.tvdbId,
|
|
type: overrides.type ?? "movie",
|
|
title: overrides.title ?? "Test Movie",
|
|
})
|
|
.run();
|
|
return id;
|
|
}
|
|
|
|
export function insertTvShow(
|
|
titleId = "tv-1",
|
|
tmdbId = 99999,
|
|
seasonCount = 1,
|
|
epsPerSeason = 3,
|
|
) {
|
|
insertTitle({ id: titleId, tmdbId, type: "tv", title: "Test Show" });
|
|
const episodeIds: string[] = [];
|
|
for (let s = 1; s <= seasonCount; s++) {
|
|
const seasonId = `${titleId}-s${s}`;
|
|
testDb
|
|
.insert(seasons)
|
|
.values({ id: seasonId, titleId, seasonNumber: s })
|
|
.run();
|
|
for (let e = 1; e <= epsPerSeason; e++) {
|
|
const epId = `${titleId}-s${s}e${e}`;
|
|
testDb
|
|
.insert(episodes)
|
|
.values({
|
|
id: epId,
|
|
seasonId,
|
|
episodeNumber: e,
|
|
name: `S${s}E${e}`,
|
|
})
|
|
.run();
|
|
episodeIds.push(epId);
|
|
}
|
|
}
|
|
return { titleId, episodeIds };
|
|
}
|
|
|
|
export function insertMovieWatch(
|
|
userId: string,
|
|
titleId: string,
|
|
watchedAt?: Date,
|
|
) {
|
|
testDb
|
|
.insert(userMovieWatches)
|
|
.values({
|
|
userId,
|
|
titleId,
|
|
watchedAt: watchedAt ?? new Date(),
|
|
source: "manual",
|
|
})
|
|
.run();
|
|
}
|
|
|
|
export function insertEpisodeWatch(
|
|
userId: string,
|
|
episodeId: string,
|
|
watchedAt?: Date,
|
|
) {
|
|
testDb
|
|
.insert(userEpisodeWatches)
|
|
.values({
|
|
userId,
|
|
episodeId,
|
|
watchedAt: watchedAt ?? new Date(),
|
|
source: "manual",
|
|
})
|
|
.run();
|
|
}
|
|
|
|
export function insertStatus(
|
|
userId: string,
|
|
titleId: string,
|
|
status: "watchlist" | "in_progress" | "completed",
|
|
) {
|
|
const now = new Date();
|
|
testDb
|
|
.insert(userTitleStatus)
|
|
.values({ userId, titleId, status, addedAt: now, updatedAt: now })
|
|
.run();
|
|
}
|
|
|
|
export function insertRating(
|
|
userId: string,
|
|
titleId: string,
|
|
ratingStars: number,
|
|
) {
|
|
testDb
|
|
.insert(userRatings)
|
|
.values({ userId, titleId, ratingStars, ratedAt: new Date() })
|
|
.run();
|
|
}
|
|
|
|
export function insertAvailabilityOffer(
|
|
titleId: string,
|
|
overrides: {
|
|
providerId?: number;
|
|
providerName?: string;
|
|
offerType?: "flatrate" | "rent" | "buy" | "free" | "ads";
|
|
} = {},
|
|
) {
|
|
testDb
|
|
.insert(availabilityOffers)
|
|
.values({
|
|
titleId,
|
|
providerId: overrides.providerId ?? 8,
|
|
providerName: overrides.providerName ?? "Netflix",
|
|
offerType: overrides.offerType ?? "flatrate",
|
|
})
|
|
.run();
|
|
}
|
|
|
|
export function insertIntegration(
|
|
userId: string,
|
|
provider: string,
|
|
token = "test-token",
|
|
) {
|
|
const type =
|
|
provider === "sonarr" || provider === "radarr" ? "list" : "webhook";
|
|
return testDb
|
|
.insert(integrations)
|
|
.values({
|
|
userId,
|
|
provider,
|
|
type,
|
|
token,
|
|
enabled: true,
|
|
createdAt: new Date(),
|
|
})
|
|
.returning()
|
|
.get();
|
|
}
|
|
|
|
export function insertRecommendation(
|
|
titleId: string,
|
|
recommendedTitleId: string,
|
|
overrides: {
|
|
source?: "tmdb_recommendations" | "tmdb_similar";
|
|
rank?: number;
|
|
} = {},
|
|
) {
|
|
testDb
|
|
.insert(titleRecommendations)
|
|
.values({
|
|
titleId,
|
|
recommendedTitleId,
|
|
source: overrides.source ?? "tmdb_recommendations",
|
|
rank: overrides.rank ?? 1,
|
|
})
|
|
.run();
|
|
}
|