1import { afterEach, describe, expect, it } from "@effect/vitest";
2import { vi } from "vite-plus/test";
3
4const fileSystemMocks = vi.hoisted(() => {
5 let entries: File[] = [];
6
7 class File {
8 readonly exists = true;
9
10 constructor(
11 readonly name: string,
12 private readonly contents: string,
13 ) {}
14
15 async text(): Promise<string> {
16 return this.contents;
17 }
18 }
19
20 class Directory {
21 create(): void {}
22
23 list(): ReadonlyArray<File> {
24 return entries;
25 }
26 }
27
28 return {
29 Directory,
30 File,
31 setEntries(next: File[]) {
32 entries = next;
33 },
34 };
35});
36
37vi.mock("expo-file-system", () => ({
38 Directory: fileSystemMocks.Directory,
39 File: fileSystemMocks.File,
40 Paths: { document: "/documents" },
41}));
42
43import { IncomingShareStorageError, loadIncomingShareDrafts } from "./incoming-share-storage";
44
45const VALID_DRAFT = {
46 schemaVersion: 1,
47 id: "share-valid",
48 createdAt: "2026-08-28T12:00:00.000Z",
49 text: "Review this file",
50 attachments: [],
51 warnings: [],
52} as const;
53
54afterEach(() => {
55 fileSystemMocks.setEntries([]);
56 vi.restoreAllMocks();
57});
58
59describe("incoming share storage", () => {
60 it("skips an invalid persisted share by default", async () => {
61 fileSystemMocks.setEntries([
62 new fileSystemMocks.File("valid.json", JSON.stringify(VALID_DRAFT)),
63 new fileSystemMocks.File("invalid.json", "{"),
64 ]);
65 const warning = vi.spyOn(console, "warn").mockImplementation(() => undefined);
66
67 await expect(loadIncomingShareDrafts()).resolves.toEqual([VALID_DRAFT]);
68 expect(warning).toHaveBeenCalledOnce();
69 });
70
71 it("rejects an invalid persisted share in strict mode", async () => {
72 fileSystemMocks.setEntries([new fileSystemMocks.File("invalid.json", "{")]);
73
74 await expect(loadIncomingShareDrafts({ strict: true })).rejects.toBeInstanceOf(
75 IncomingShareStorageError,
76 );
77 });
78});