summaryrefslogtreecommitdiffhomepage
path: root/src/features/conversation-cache/cache.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/conversation-cache/cache.test.ts')
-rw-r--r--src/features/conversation-cache/cache.test.ts35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/features/conversation-cache/cache.test.ts b/src/features/conversation-cache/cache.test.ts
index 4306d51..72b4e20 100644
--- a/src/features/conversation-cache/cache.test.ts
+++ b/src/features/conversation-cache/cache.test.ts
@@ -214,3 +214,38 @@ it("serializes invalidation and rejects stale epoch commits", async () => {
expect(await cache.commit("c", [chunk(103)], 1)).toEqual([]);
expect(await store.historyEpoch("c")).toBe(2);
});
+
+it("replaces a confirmed full history at a lower epoch, without trusting stale commits", async () => {
+ const store = createFakeStore();
+ const cache = createConversationCache(store);
+ await cache.commit("c", [chunk(9)], 5);
+ expect(await cache.replace("c", [chunk(1)], 1, 5)).toBe(true);
+ expect(await cache.historyEpoch("c")).toBe(1);
+ expect(await cache.load("c")).toEqual([chunk(1)]);
+ expect(await cache.commit("c", [chunk(9)], 5)).toEqual([chunk(1)]);
+ // A delayed full response started against epoch 5 must not restore it.
+ expect(await cache.replace("c", [chunk(9)], 5, 5)).toBe(false);
+ expect(await cache.load("c")).toEqual([chunk(1)]);
+});
+
+it("serializes a guarded replacement behind newer invalidation", async () => {
+ const store = createFakeStore();
+ const cache = createConversationCache(store);
+ await cache.commit("c", [chunk(9)], 5);
+ const resetting = cache.reset("c", 6);
+ const replacing = cache.replace("c", [chunk(1)], 1, 5);
+ await resetting;
+ expect(await replacing).toBe(false);
+ expect(await cache.historyEpoch("c")).toBe(6);
+ expect(await cache.load("c")).toEqual([]);
+});
+
+it("allows an empty replacement and a legacy cache only if its observed epoch still matches", async () => {
+ const store = createFakeStore();
+ const cache = createConversationCache(store);
+ await store.append("c", [chunk(9)]);
+ expect(await cache.replace("c", [], 0, undefined)).toBe(true);
+ expect(await cache.sinceSeq("c")).toBe(0);
+ expect(await cache.historyEpoch("c")).toBe(0);
+ expect(await cache.replace("c", [chunk(9)], 2, undefined)).toBe(false);
+});