git » sdk » commit d293727

Add test factories and test existing behaviour

author Eric Roberts
2026-09-15 15:38:54 UTC
committer Eric Roberts
2026-09-21 17:49:22 UTC
parent 7b5bd51434020fae6b30b79e6982717fcb6022f0

Add test factories and test existing behaviour

I'd like to extend these factories to work for the other existing tests
to reduce duplication and boilerplate but that's gonna take a little
more effort than I have time for at the moment and I want to get these
changes in.

npm/package.json +2 -1
test/idb.spec.ts +2 -0
test/persistence-factories.ts +86 -0
test/persistence-tests.ts +40 -0
test/sqlite.spec.ts +8 -1

diff --git a/npm/package.json b/npm/package.json
index 6617be6..e681a4d 100644
--- a/npm/package.json
+++ b/npm/package.json
@@ -38,11 +38,12 @@
 		}
 	},
 	"devDependencies": {
+		"@faker-js/faker": "^10.6.0",
 		"@sqlite.org/sqlite-wasm": "^3.53.0-build1",
 		"@vitest/browser": "^5.0.0",
 		"@vitest/browser-playwright": "^5.0.0",
-		"oxlint": "^1.82.0",
 		"oxfmt": "^0.67.0",
+		"oxlint": "^1.82.0",
 		"playwright": "1.60.0",
 		"typescript": "^5.4.5",
 		"vitest": "^5.0.0"
diff --git a/test/idb.spec.ts b/test/idb.spec.ts
index 36df8c5..98e71f5 100644
--- a/test/idb.spec.ts
+++ b/test/idb.spec.ts
@@ -1,5 +1,6 @@
 import { expect, test } from "vitest";
 import * as borogove from "../playwright/.cache/borogove.js";
+import { createFactories } from "./persistence-factories";
 import { sharedPersistenceTests } from "./persistence-tests";
 
 async function idbFixture() {
@@ -35,6 +36,7 @@ async function idbFixture() {
 		});
 	};
 	return {
+		factories: createFactories(borogove),
 		borogove,
 		persistence,
 		createChannel,
diff --git a/test/persistence-factories.ts b/test/persistence-factories.ts
new file mode 100644
index 0000000..53cb915
--- /dev/null
+++ b/test/persistence-factories.ts
@@ -0,0 +1,86 @@
+import { faker } from "@faker-js/faker";
+
+type MakeMessageOpts = {
+	serverId?: string;
+	serverIdBy?: string;
+	localId?: string;
+	senderId?: string;
+	to?: any; // JID
+	from?: any; // JID
+	direction?: 0 | 1;
+	sortId?: string;
+	recipients?: string[];
+	replyTo?: string[];
+	text?: string;
+	timestamp?: Date;
+	versions?: any[];
+};
+
+type CorrectionProps = {
+	text: string;
+};
+
+export function createFactories(borogove: any) {
+	const message = ({
+		serverId,
+		serverIdBy,
+		localId,
+		senderId,
+		to,
+		from,
+		direction,
+		sortId,
+		recipients,
+		replyTo,
+		text,
+		timestamp,
+		versions,
+	}: MakeMessageOpts = {}) => {
+		const toJID = to ?? borogove.JID.parse(faker.internet.email());
+		const fromJID = from ?? borogove.JID.parse(faker.internet.email());
+
+		const builder = new borogove.ChatMessageBuilder({
+			serverId: serverId ?? crypto.randomUUID(),
+			serverIdBy: serverIdBy ?? toJID.asString(),
+			localId: localId ?? crypto.randomUUID(),
+			senderId: senderId ?? fromJID.asString(),
+			direction: direction ?? 0,
+		});
+		builder.sortId = sortId ?? crypto.randomUUID();
+		builder.to = toJID;
+		builder.from = fromJID;
+		builder.recipients = recipients ?? [toJID];
+		builder.replyTo = replyTo ?? [fromJID];
+		builder.versions = versions ?? [];
+		builder.text = text ?? faker.lorem.sentence();
+		builder.timestamp = timestamp?.toISOString() ?? new Date().toISOString();
+
+		return builder.build();
+	};
+
+	const corrections = (original: any, props: CorrectionProps[]) => {
+		const originalTimestamp = new Date(original.timestamp).getTime();
+
+		return props.map(({ text }, index) => {
+			const versionTimestamp = new Date(originalTimestamp + index + 1);
+
+			const version = message({
+				to: original.to,
+				from: original.from,
+				text,
+				timestamp: versionTimestamp,
+			});
+
+			return message({
+				to: original.to,
+				from: original.from,
+				localId: original.localId,
+				versions: [version],
+				timestamp: versionTimestamp,
+				text,
+			});
+		});
+	};
+
+	return { message, corrections };
+}
diff --git a/test/persistence-tests.ts b/test/persistence-tests.ts
index 66f908a..beee6c8 100644
--- a/test/persistence-tests.ts
+++ b/test/persistence-tests.ts
@@ -1,3 +1,4 @@
+import { faker } from "@faker-js/faker";
 import { expect } from "vitest";
 
 export function sharedPersistenceTests(test) {
@@ -1937,6 +1938,45 @@ export function sharedPersistenceTests(test) {
 		]);
 		expect([...stored.reactions.keys()]).toEqual([]);
 	});
+
+	test("storeMessages properly stores corrected messages", async ({
+		factories,
+		borogove,
+		persistence,
+	}) => {
+		const account = faker.internet.email();
+		const to = borogove.JID.parse(account);
+		const original = factories.message({ to, text: "Original message" });
+		await persistence.storeMessages(account, [original]);
+
+		const [correction] = factories.corrections(original, [
+			{ text: "Corrected message" },
+		]);
+		const [stored, ...restStored] = await persistence.storeMessages(account, [
+			correction,
+		]);
+
+		expect(restStored.length).toBe(0);
+		expect(stored.localId).toBe(original.localId);
+		expect(stored.serverId).toBe(original.serverId);
+		expect(stored.text).toBe(correction.text);
+
+		expect(stored.versions.map((version) => version.text)).toEqual([
+			correction.text,
+			original.text,
+		]);
+		const [fetched, ...rest] = await persistence.getMessagesBefore(
+			account,
+			original.chatId(),
+		);
+
+		expect(rest.length).toBe(0);
+		expect(fetched?.text).toBe(correction.text);
+		expect(fetched?.versions.map((version) => version.text)).toEqual([
+			correction.text,
+			original.text,
+		]);
+	});
 }
 
 type TestKeyPair = {
diff --git a/test/sqlite.spec.ts b/test/sqlite.spec.ts
index d34b33f..3efcccc 100644
--- a/test/sqlite.spec.ts
+++ b/test/sqlite.spec.ts
@@ -1,6 +1,7 @@
 import { test } from "vitest";
 import * as borogove from "../playwright/.cache/borogove.js";
 import * as sqlite from "../playwright/.cache/sqlite-wasm.js";
+import { createFactories } from "./persistence-factories";
 import { sharedPersistenceTests } from "./persistence-tests";
 
 async function sqliteFixture() {
@@ -48,7 +49,13 @@ async function sqliteFixture() {
 			],
 		);
 	};
-	return { borogove, persistence, createChannel, storeIncompleteMember };
+	return {
+		factories: createFactories(borogove),
+		borogove,
+		persistence,
+		createChannel,
+		storeIncompleteMember,
+	};
 }
 
 const sqlitePersistence = sqliteFixture();