test: cover runtime regression scenarios
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { ConversationStore } from "./conversation-store";
|
||||
|
||||
class MemoryStorage implements Storage {
|
||||
private readonly values = new Map<string, string>();
|
||||
|
||||
public get length(): number { return this.values.size; }
|
||||
public clear(): void { this.values.clear(); }
|
||||
public getItem(key: string): string | null { return this.values.get(key) ?? null; }
|
||||
public key(index: number): string | null { return [...this.values.keys()][index] ?? null; }
|
||||
public removeItem(key: string): void { this.values.delete(key); }
|
||||
public setItem(key: string, value: string): void { this.values.set(key, value); }
|
||||
}
|
||||
|
||||
const conversationID = "user_test:2:agent_channel";
|
||||
const createdAt = "2026-08-03T00:00:00.000Z";
|
||||
|
||||
describe("ConversationStore", () => {
|
||||
it("keeps the inclusive sync cursor at zero after a send acknowledgement", () => {
|
||||
const store = new ConversationStore(new MemoryStorage());
|
||||
store.open(conversationID);
|
||||
store.appendLocalText("local_001", "hello", createdAt);
|
||||
store.markSubmitted("local_001", 41, createdAt);
|
||||
|
||||
expect(store.snapshot()).toMatchObject({ cursor: 0, outbox: [] });
|
||||
expect(store.snapshot().items).toEqual([expect.objectContaining({
|
||||
local_id: "local_001",
|
||||
message_seq: 41,
|
||||
item: expect.objectContaining({ kind: "user-message", delivery: expect.objectContaining({ status: "submitted" }) }),
|
||||
})]);
|
||||
});
|
||||
|
||||
it("deduplicates the inclusive sync echo of a locally submitted user message", () => {
|
||||
const store = new ConversationStore(new MemoryStorage());
|
||||
store.open(conversationID);
|
||||
store.appendLocalText("local_001", "hello", createdAt);
|
||||
store.markSubmitted("local_001", 41, createdAt);
|
||||
|
||||
const restored = store.recordSyncedUserText(41, "hello", createdAt);
|
||||
|
||||
expect(restored).toBeUndefined();
|
||||
expect(store.snapshot()).toMatchObject({ cursor: 41 });
|
||||
expect(store.snapshot().items).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("persists a local echo and restores it for the same conversation", () => {
|
||||
const storage = new MemoryStorage();
|
||||
const first = new ConversationStore(storage);
|
||||
first.open(conversationID);
|
||||
first.appendLocalText("local_002", "persist me", createdAt);
|
||||
|
||||
const reopened = new ConversationStore(storage);
|
||||
const snapshot = reopened.open(conversationID);
|
||||
|
||||
expect(snapshot.cursor).toBe(0);
|
||||
expect(snapshot.outbox).toEqual([expect.objectContaining({ local_id: "local_002", payload: "persist me" })]);
|
||||
expect(snapshot.items).toEqual([expect.objectContaining({
|
||||
local_id: "local_002",
|
||||
item: expect.objectContaining({ kind: "user-message", text: "persist me" }),
|
||||
})]);
|
||||
});
|
||||
|
||||
it("accepts one remote message per IM sequence and advances the cursor only from sync data", () => {
|
||||
const store = new ConversationStore(new MemoryStorage());
|
||||
store.open(conversationID);
|
||||
const item = { kind: "markdown" as const, id: "evt_remote_001", markdown: "remote" };
|
||||
|
||||
expect(store.recordIncoming(item, 42, createdAt)).toBe(true);
|
||||
expect(store.recordIncoming(item, 42, createdAt)).toBe(false);
|
||||
expect(store.snapshot()).toMatchObject({ cursor: 42 });
|
||||
expect(store.snapshot().items).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user