story-kit: create 174_story_matrix_chatbot_interface_for_story_kit

This commit is contained in:
Dave
2026-02-25 11:40:09 +00:00
parent c0b882f29c
commit 48223b517d
3 changed files with 211 additions and 23 deletions

View File

@@ -5,12 +5,20 @@ import { useChatHistory } from "./useChatHistory";
const PROJECT = "/tmp/test-project";
const STORAGE_KEY = `storykit-chat-history:${PROJECT}`;
const LIMIT_KEY = `storykit-chat-history-limit:${PROJECT}`;
const sampleMessages: Message[] = [
{ role: "user", content: "Hello" },
{ role: "assistant", content: "Hi there!" },
];
function makeMessages(count: number): Message[] {
return Array.from({ length: count }, (_, i) => ({
role: "user" as const,
content: `Message ${i + 1}`,
}));
}
describe("useChatHistory", () => {
beforeEach(() => {
localStorage.clear();
@@ -143,4 +151,125 @@ describe("useChatHistory", () => {
expect(localStorage.getItem(STORAGE_KEY)).toBeNull();
});
// --- Story 179: Chat history pruning tests ---
it("S179: default limit of 200 is applied when saving to localStorage", () => {
const { result } = renderHook(() => useChatHistory(PROJECT));
expect(result.current.maxMessages).toBe(200);
});
it("S179: messages are pruned from the front when exceeding the limit", () => {
// Set a small limit to make testing practical
localStorage.setItem(LIMIT_KEY, "3");
const { result } = renderHook(() => useChatHistory(PROJECT));
const fiveMessages = makeMessages(5);
act(() => {
result.current.setMessages(fiveMessages);
});
// localStorage should contain only the last 3 messages
const stored: Message[] = JSON.parse(
localStorage.getItem(STORAGE_KEY) ?? "[]",
);
expect(stored).toEqual(fiveMessages.slice(-3));
expect(stored).toHaveLength(3);
expect(stored[0].content).toBe("Message 3");
});
it("S179: messages under the limit are not pruned", () => {
localStorage.setItem(LIMIT_KEY, "10");
const { result } = renderHook(() => useChatHistory(PROJECT));
const threeMessages = makeMessages(3);
act(() => {
result.current.setMessages(threeMessages);
});
const stored: Message[] = JSON.parse(
localStorage.getItem(STORAGE_KEY) ?? "[]",
);
expect(stored).toEqual(threeMessages);
expect(stored).toHaveLength(3);
});
it("S179: limit is configurable via localStorage key", () => {
localStorage.setItem(LIMIT_KEY, "5");
const { result } = renderHook(() => useChatHistory(PROJECT));
expect(result.current.maxMessages).toBe(5);
});
it("S179: setMaxMessages updates the limit and persists it", () => {
const { result } = renderHook(() => useChatHistory(PROJECT));
act(() => {
result.current.setMaxMessages(50);
});
expect(result.current.maxMessages).toBe(50);
expect(localStorage.getItem(LIMIT_KEY)).toBe("50");
});
it("S179: a limit of 0 means unlimited (no pruning)", () => {
localStorage.setItem(LIMIT_KEY, "0");
const { result } = renderHook(() => useChatHistory(PROJECT));
const manyMessages = makeMessages(500);
act(() => {
result.current.setMessages(manyMessages);
});
const stored: Message[] = JSON.parse(
localStorage.getItem(STORAGE_KEY) ?? "[]",
);
expect(stored).toHaveLength(500);
expect(stored).toEqual(manyMessages);
});
it("S179: changing the limit re-prunes messages on next save", () => {
const { result } = renderHook(() => useChatHistory(PROJECT));
const tenMessages = makeMessages(10);
act(() => {
result.current.setMessages(tenMessages);
});
// All 10 saved (default limit 200 > 10)
let stored: Message[] = JSON.parse(
localStorage.getItem(STORAGE_KEY) ?? "[]",
);
expect(stored).toHaveLength(10);
// Now lower the limit — the effect re-runs and prunes
act(() => {
result.current.setMaxMessages(3);
});
stored = JSON.parse(localStorage.getItem(STORAGE_KEY) ?? "[]");
expect(stored).toHaveLength(3);
expect(stored[0].content).toBe("Message 8");
});
it("S179: invalid limit in localStorage falls back to default", () => {
localStorage.setItem(LIMIT_KEY, "not-a-number");
const { result } = renderHook(() => useChatHistory(PROJECT));
expect(result.current.maxMessages).toBe(200);
});
it("S179: negative limit in localStorage falls back to default", () => {
localStorage.setItem(LIMIT_KEY, "-5");
const { result } = renderHook(() => useChatHistory(PROJECT));
expect(result.current.maxMessages).toBe(200);
});
});