evOo-local/packages/contracts/src/search.test.ts
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline
(Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/*
packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
2026-09-20 17:15:16 +02:00

62 lines
1.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { SearchHitSchema, SearchQueryOutputSchema } from "./search.js";
describe("search contracts", () => {
it("accepts bounded workspace search results", () => {
const parsed = SearchQueryOutputSchema.parse({
hits: [
{
kind: "message",
botId: "bot-1",
botName: "Scout",
title: "Scout",
snippet: "found it",
messageId: "msg-1",
seq: 3,
},
],
});
expect(parsed.hits).toHaveLength(1);
expect(SearchHitSchema.parse(parsed.hits[0]).kind).toBe("message");
});
it("accepts group thread hits", () => {
const parsed = SearchQueryOutputSchema.parse({
hits: [
{
kind: "message",
groupId: "group-1",
groupName: "Squad",
title: "Squad",
snippet: "found it",
messageId: "msg-1",
seq: 3,
},
],
});
expect(parsed.hits[0]?.groupId).toBe("group-1");
expect(parsed.hits[0]?.botId).toBeUndefined();
});
it("rejects hits with both or neither target id", () => {
expect(() =>
SearchHitSchema.parse({
kind: "message",
title: "x",
snippet: "y",
}),
).toThrow();
expect(() =>
SearchHitSchema.parse({
kind: "message",
botId: "bot-1",
botName: "Scout",
groupId: "group-1",
groupName: "Squad",
title: "x",
snippet: "y",
}),
).toThrow();
});
});