relay filter/appview bootstrap
1import { describe, it, expect, mock, beforeEach } from "bun:test";
2import { RecordProcessor } from "../src/util/recordProcessor";
3
4const mockExecute = mock(() => Promise.resolve([]));
5const mockOnConflict = mock(() => ({
6 execute: mockExecute,
7 doNothing: () => ({ execute: mockExecute }),
8 doUpdateSet: () => ({ execute: mockExecute }),
9 column: () => ({
10 doNothing: () => ({ execute: mockExecute }),
11 doUpdateSet: () => ({ execute: mockExecute })
12 })
13}));
14
15const mockValues = mock(() => ({
16 execute: mockExecute,
17 onConflict: mockOnConflict
18}));
19
20const mockInsertInto = mock(() => ({
21 values: mockValues
22}));
23
24mock.module("../src/db", () => ({
25 db: {
26 insertInto: mockInsertInto
27 }
28}));
29
30describe("RecordProcessor", () => {
31 let processor: RecordProcessor;
32 const did = "did:plc:123";
33
34 beforeEach(() => {
35 processor = new RecordProcessor(did);
36 mockInsertInto.mockClear();
37 mockValues.mockClear();
38 mockExecute.mockClear();
39 mockOnConflict.mockClear();
40 });
41
42 it("should process and insert a Lattice record", async () => {
43 const record = {
44 $type: "systems.gmstn.development.lattice",
45 createdAt: "2023-01-01T00:00:00Z",
46 description: "Test Lattice"
47 };
48 const uri = "at://did:plc:123/systems.gmstn.development.lattice/rkey";
49 const cid = "bafy...";
50 const indexedAt = "2023-01-02T00:00:00Z";
51
52 await processor.processRecord(record, uri, cid, indexedAt);
53 await processor.insertAllProcessedRecords();
54
55 expect(mockInsertInto).toHaveBeenCalledWith("lattice");
56
57 const calls = mockValues.mock.calls as unknown as any[][];
58 expect(calls.length).toBeGreaterThan(0);
59 const insertedRecords = calls[0][0];
60
61 expect(insertedRecords).toHaveLength(1);
62 expect(insertedRecords[0]).toMatchObject({
63 uri,
64 cid,
65 creator_did: did,
66 description: "Test Lattice",
67 created_at: record.createdAt,
68 indexed_at: indexedAt,
69 data: record
70 });
71 });
72
73 it("should process and insert a Shard record", async () => {
74 const record = {
75 $type: "systems.gmstn.development.shard",
76 createdAt: "2023-01-01T00:00:00Z",
77 description: "Test Shard"
78 };
79 const uri = "at://did:plc:123/systems.gmstn.development.shard/rkey";
80 const cid = "bafy_shard";
81 const indexedAt = "2023-01-02T00:00:00Z";
82
83 await processor.processRecord(record, uri, cid, indexedAt);
84 await processor.insertAllProcessedRecords();
85
86 expect(mockInsertInto).toHaveBeenCalledWith("shard");
87 const calls = mockValues.mock.calls as unknown as any[][];
88 const insertedRecords = calls[0][0];
89 expect(insertedRecords[0]).toMatchObject({
90 description: "Test Shard"
91 });
92 });
93
94 it("should process and insert a Channel record", async () => {
95 const record = {
96 $type: "systems.gmstn.development.channel",
97 createdAt: "2023-01-01T00:00:00Z",
98 name: "Test Channel",
99 topic: "Testing"
100 };
101 const uri = "at://did:plc:123/systems.gmstn.development.channel.record/rkey";
102 const cid = "bafy_channel";
103 const indexedAt = "2023-01-02T00:00:00Z";
104
105 await processor.processRecord(record, uri, cid, indexedAt);
106 await processor.insertAllProcessedRecords();
107
108 expect(mockInsertInto).toHaveBeenCalledWith("channel");
109
110 const calls = mockInsertInto.mock.calls as unknown as any[][];
111 const channelCall = calls.find(call => call[0] === 'channel');
112 expect(channelCall).toBeDefined();
113 });
114
115 it("should process and insert a Channel Invite record", async () => {
116 const record = {
117 $type: "systems.gmstn.development.channel.invite",
118 createdAt: "2023-01-01T00:00:00Z",
119 recipient: "did:plc:recipient",
120 channel: { cid: "bafy_channel_cid", uri: "at://..." }
121 };
122 const uri = "at://did:plc:123/systems.gmstn.development.channel.invite/rkey";
123 const cid = "bafy_invite";
124 const indexedAt = "2023-01-02T00:00:00Z";
125
126 await processor.processRecord(record, uri, cid, indexedAt);
127 await processor.insertAllProcessedRecords();
128
129 expect(mockInsertInto).toHaveBeenCalledWith("channel_invite");
130
131 const calls = mockInsertInto.mock.calls as unknown as any[][];
132 const tables = calls.map(c => c[0]);
133 expect(tables).toContain("channel_invite");
134 expect(tables).toContain("account");
135 expect(tables).toContain("channel");
136 });
137
138 it("should process and insert a Channel Membership record", async () => {
139 const record = {
140 $type: "systems.gmstn.development.channel.membership",
141 createdAt: "2023-01-01T00:00:00Z",
142 state: "joined",
143 channel: { cid: "bafy_channel_cid", uri: "at://..." },
144 invite: { cid: "bafy_invite_cid", uri: "at://..." }
145 };
146 const uri = "at://did:plc:123/systems.gmstn.development.channel.membership/rkey";
147 const cid = "bafy_membership";
148 const indexedAt = "2023-01-02T00:00:00Z";
149
150 await processor.processRecord(record, uri, cid, indexedAt);
151 await processor.insertAllProcessedRecords();
152
153 expect(mockInsertInto).toHaveBeenCalledWith("channel_membership");
154
155 const calls = mockInsertInto.mock.calls as unknown as any[][];
156 const tables = calls.map(c => c[0]);
157 expect(tables).toContain("channel_membership");
158 expect(tables).toContain("channel");
159 expect(tables).toContain("channel_invite");
160 });
161});