114 lines · 3.5 KB · TypeScript
RawDownload
import { MessageId, ThreadId } from "@t3tools/contracts";import { assert, it } from "@effect/vitest";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer"; import { ProjectionThreadMessageRepository } from "../Services/ProjectionThreadMessages.ts";import { ProjectionThreadMessageRepositoryLive } from "./ProjectionThreadMessages.ts";import { SqlitePersistenceMemory } from "./Sqlite.ts"; const layer = it.layer(  ProjectionThreadMessageRepositoryLive.pipe(Layer.provideMerge(SqlitePersistenceMemory)),); layer("ProjectionThreadMessageRepository", (it) => {  it.effect("preserves existing attachments when upsert omits attachments", () =>    Effect.gen(function* () {      const repository = yield* ProjectionThreadMessageRepository;      const threadId = ThreadId.make("thread-preserve-attachments");      const messageId = MessageId.make("message-preserve-attachments");      const createdAt = "2026-02-28T19:00:00.000Z";      const updatedAt = "2026-02-28T19:00:01.000Z";      const persistedAttachments = [        {          type: "image" as const,          id: "thread-preserve-attachments-att-1",          name: "example.png",          mimeType: "image/png",          sizeBytes: 5,        },      ];       yield* repository.upsert({        messageId,        threadId,        turnId: null,        role: "user",        text: "initial",        attachments: persistedAttachments,        isStreaming: false,        createdAt,        updatedAt,      });       yield* repository.upsert({        messageId,        threadId,        turnId: null,        role: "user",        text: "updated",        isStreaming: false,        createdAt,        updatedAt: "2026-02-28T19:00:02.000Z",      });       const rows = yield* repository.listByThreadId({ threadId });      assert.equal(rows.length, 1);      assert.equal(rows[0]?.text, "updated");      assert.deepEqual(rows[0]?.attachments, persistedAttachments);       const rowById = yield* repository.getByMessageId({ messageId });      assert.equal(rowById._tag, "Some");      if (rowById._tag === "Some") {        assert.equal(rowById.value.text, "updated");        assert.deepEqual(rowById.value.attachments, persistedAttachments);      }    }),  );   it.effect("allows explicit attachment clearing with an empty array", () =>    Effect.gen(function* () {      const repository = yield* ProjectionThreadMessageRepository;      const threadId = ThreadId.make("thread-clear-attachments");      const messageId = MessageId.make("message-clear-attachments");      const createdAt = "2026-02-28T19:10:00.000Z";       yield* repository.upsert({        messageId,        threadId,        turnId: null,        role: "assistant",        text: "with attachment",        attachments: [          {            type: "image",            id: "thread-clear-attachments-att-1",            name: "example.png",            mimeType: "image/png",            sizeBytes: 5,          },        ],        isStreaming: false,        createdAt,        updatedAt: "2026-02-28T19:10:01.000Z",      });       yield* repository.upsert({        messageId,        threadId,        turnId: null,        role: "assistant",        text: "cleared",        attachments: [],        isStreaming: false,        createdAt,        updatedAt: "2026-02-28T19:10:02.000Z",      });       const rows = yield* repository.listByThreadId({ threadId });      assert.equal(rows.length, 1);      assert.equal(rows[0]?.text, "cleared");      assert.deepEqual(rows[0]?.attachments, []);    }),  );});