Files
erika/lib/share/create-core.test.ts
T

77 lines
2.1 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import {
createShareAtomically,
type CreateShareInput,
type CreateShareStore,
} from "@/lib/share/create-core";
const input: CreateShareInput = {
content: "exact content\n",
description: "description",
image: {
bytes: Buffer.from("image"),
name: "image.png",
type: "image/png",
size: 5,
},
source: "bot",
author: {
userId: "user-1",
discordId: "123456789012345678",
displayName: "Example user",
avatarUrl: null,
},
};
function memoryStore(failShareInsert = false) {
const images: string[] = [];
const shares: string[] = [];
const store: CreateShareStore = {
async transaction(callback) {
const nextImages = [...images];
const nextShares = [...shares];
const result = await callback({
async insertImage() {
nextImages.push("image-1");
return "image-1";
},
async insertShare(_input, imageCdnId) {
if (failShareInsert) throw new Error("share insert failed");
nextShares.push("share-1");
return {
id: "a1b2c3d4",
imageCdnId,
createdAt: new Date("2026-08-16T00:00:00.000Z"),
};
},
});
images.splice(0, images.length, ...nextImages);
shares.splice(0, shares.length, ...nextShares);
return result;
},
};
return { images, shares, store };
}
describe("atomic share creation", () => {
test("stores the image and share in one transaction", async () => {
const memory = memoryStore();
await expect(createShareAtomically(input, memory.store)).resolves.toEqual({
id: "a1b2c3d4",
imageCdnId: "image-1",
createdAt: new Date("2026-08-16T00:00:00.000Z"),
});
expect(memory.images).toEqual(["image-1"]);
expect(memory.shares).toEqual(["share-1"]);
});
test("rolls back the image when inserting the share fails", async () => {
const memory = memoryStore(true);
await expect(createShareAtomically(input, memory.store)).rejects.toThrow(
"share insert failed",
);
expect(memory.images).toEqual([]);
expect(memory.shares).toEqual([]);
});
});