|
|
@@ -0,0 +1,107 @@
|
|
|
+import { describe, expect, test, spyOn, beforeEach, afterEach } from "bun:test"
|
|
|
+import { z } from "zod"
|
|
|
+import { QuestionTool } from "../../src/tool/question"
|
|
|
+import * as QuestionModule from "../../src/question"
|
|
|
+
|
|
|
+const ctx = {
|
|
|
+ sessionID: "test-session",
|
|
|
+ messageID: "test-message",
|
|
|
+ callID: "test-call",
|
|
|
+ agent: "test-agent",
|
|
|
+ abort: AbortSignal.any([]),
|
|
|
+ metadata: () => {},
|
|
|
+ ask: async () => {},
|
|
|
+}
|
|
|
+
|
|
|
+describe("tool.question", () => {
|
|
|
+ let askSpy: any;
|
|
|
+
|
|
|
+ beforeEach(() => {
|
|
|
+ askSpy = spyOn(QuestionModule.Question, "ask").mockImplementation(async () => {
|
|
|
+ return []
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ afterEach(() => {
|
|
|
+ askSpy.mockRestore()
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should successfully execute with valid question parameters", async () => {
|
|
|
+ const tool = await QuestionTool.init()
|
|
|
+ const questions = [
|
|
|
+ {
|
|
|
+ question: "What is your favorite color?",
|
|
|
+ header: "Color",
|
|
|
+ options: [
|
|
|
+ { label: "Red", description: "The color of passion" },
|
|
|
+ { label: "Blue", description: "The color of sky" },
|
|
|
+ ],
|
|
|
+ multiple: false,
|
|
|
+ },
|
|
|
+ ]
|
|
|
+
|
|
|
+ askSpy.mockResolvedValueOnce([["Red"]])
|
|
|
+
|
|
|
+ const result = await tool.execute(
|
|
|
+ { questions },
|
|
|
+ ctx,
|
|
|
+ )
|
|
|
+ expect(askSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(result.title).toBe("Asked 1 question")
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should now pass with a header longer than 12 but less than 30 chars", async () => {
|
|
|
+ const tool = await QuestionTool.init()
|
|
|
+ const questions = [
|
|
|
+ {
|
|
|
+ question: "What is your favorite animal?",
|
|
|
+ header: "This Header is Over 12",
|
|
|
+ options: [{ label: "Dog", description: "Man's best friend" }],
|
|
|
+ },
|
|
|
+ ]
|
|
|
+
|
|
|
+ askSpy.mockResolvedValueOnce([["Dog"]])
|
|
|
+
|
|
|
+ const result = await tool.execute({ questions }, ctx)
|
|
|
+ expect(result.output).toContain(`"What is your favorite animal?"="Dog"`)
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should throw an Error for header exceeding 30 characters", async () => {
|
|
|
+ const tool = await QuestionTool.init()
|
|
|
+ const questions = [
|
|
|
+ {
|
|
|
+ question: "What is your favorite animal?",
|
|
|
+ header: "This Header is Definitely More Than Thirty Characters Long",
|
|
|
+ options: [{ label: "Dog", description: "Man's best friend" }],
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ try {
|
|
|
+ await tool.execute({ questions }, ctx)
|
|
|
+ // If it reaches here, the test should fail
|
|
|
+ expect(true).toBe(false)
|
|
|
+ } catch (e: any) {
|
|
|
+ expect(e).toBeInstanceOf(Error)
|
|
|
+ expect(e.cause).toBeInstanceOf(z.ZodError)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should throw an Error for label exceeding 30 characters", async () => {
|
|
|
+ const tool = await QuestionTool.init()
|
|
|
+ const questions = [
|
|
|
+ {
|
|
|
+ question: "A question with a very long label",
|
|
|
+ header: "Long Label",
|
|
|
+ options: [{ label: "This is a very, very, very long label that will exceed the limit", description: "A description" }],
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ try {
|
|
|
+ await tool.execute({ questions }, ctx)
|
|
|
+ // If it reaches here, the test should fail
|
|
|
+ expect(true).toBe(false)
|
|
|
+ } catch (e: any) {
|
|
|
+ expect(e).toBeInstanceOf(Error)
|
|
|
+ expect(e.cause).toBeInstanceOf(z.ZodError)
|
|
|
+ }
|
|
|
+ })
|
|
|
+})
|
|
|
+
|