1import { describe, expect, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import * as Option from "effect/Option";
4import { vi } from "vite-plus/test";
5
6const openDatabaseAsync = vi.hoisted(() => vi.fn());
7
8vi.mock("expo-sqlite", () => ({ openDatabaseAsync }));
9
10import * as MobileDatabase from "./mobile-database";
11
12describe("offline pull request cache", () => {
13 const environmentId = "cached-environment" as import("@t3tools/contracts").EnvironmentId;
14 const otherEnvironment = "other-environment" as import("@t3tools/contracts").EnvironmentId;
15
16 async function sqliteDatabase() {
17 const { DatabaseSync } = await import("node:sqlite");
18 const sqlite = new DatabaseSync(":memory:");
19 sqlite.exec("PRAGMA user_version = 1");
20 const database = {
21 execAsync: async (sql: string) => {
22 sqlite.exec(sql);
23 },
24 runAsync: async (sql: string, ...args: Array<string | number>) =>
25 sqlite.prepare(sql).run(...args),
26 getFirstAsync: async (sql: string, ...args: Array<string | number>) =>
27 sqlite.prepare(sql).get(...args),
28 getAllAsync: async (sql: string, ...args: Array<string | number>) =>
29 sqlite.prepare(sql).all(...args),
30 withExclusiveTransactionAsync: async (run: (transaction: unknown) => Promise<void>) => {
31 await run(database);
32 },
33 closeAsync: async () => {
34 sqlite.close();
35 },
36 };
37 openDatabaseAsync.mockResolvedValueOnce(database);
38 return sqlite;
39 }
40
41 it.effect("restores saved records and clears them with the environment", () =>
42 Effect.gen(function* () {
43 yield* Effect.promise(sqliteDatabase);
44 const database = yield* MobileDatabase.make;
45 yield* database.saveCache(environmentId, "pull-request", "v1:list", 1, '{"entries":[]}');
46 yield* database.saveCache(otherEnvironment, "pull-request", "v1:list", 1, "other");
47 expect(yield* database.loadCache(environmentId, "pull-request", "v1:list")).toEqual(
48 Option.some('{"entries":[]}'),
49 );
50 yield* database.clearEnvironmentCache(environmentId);
51 expect((yield* database.loadCache(environmentId, "pull-request", "v1:list"))._tag).toBe(
52 "None",
53 );
54 expect((yield* database.loadCache(otherEnvironment, "pull-request", "v1:list"))._tag).toBe(
55 "Some",
56 );
57 }),
58 );
59});