question.test.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { describe, expect, test, spyOn, beforeEach, afterEach } from "bun:test"
  2. import { z } from "zod"
  3. import { QuestionTool } from "../../src/tool/question"
  4. import * as QuestionModule from "../../src/question"
  5. const ctx = {
  6. sessionID: "test-session",
  7. messageID: "test-message",
  8. callID: "test-call",
  9. agent: "test-agent",
  10. abort: AbortSignal.any([]),
  11. metadata: () => {},
  12. ask: async () => {},
  13. }
  14. describe("tool.question", () => {
  15. let askSpy: any
  16. beforeEach(() => {
  17. askSpy = spyOn(QuestionModule.Question, "ask").mockImplementation(async () => {
  18. return []
  19. })
  20. })
  21. afterEach(() => {
  22. askSpy.mockRestore()
  23. })
  24. test("should successfully execute with valid question parameters", async () => {
  25. const tool = await QuestionTool.init()
  26. const questions = [
  27. {
  28. question: "What is your favorite color?",
  29. header: "Color",
  30. options: [
  31. { label: "Red", description: "The color of passion" },
  32. { label: "Blue", description: "The color of sky" },
  33. ],
  34. multiple: false,
  35. },
  36. ]
  37. askSpy.mockResolvedValueOnce([["Red"]])
  38. const result = await tool.execute({ questions }, ctx)
  39. expect(askSpy).toHaveBeenCalledTimes(1)
  40. expect(result.title).toBe("Asked 1 question")
  41. })
  42. test("should now pass with a header longer than 12 but less than 30 chars", async () => {
  43. const tool = await QuestionTool.init()
  44. const questions = [
  45. {
  46. question: "What is your favorite animal?",
  47. header: "This Header is Over 12",
  48. options: [{ label: "Dog", description: "Man's best friend" }],
  49. },
  50. ]
  51. askSpy.mockResolvedValueOnce([["Dog"]])
  52. const result = await tool.execute({ questions }, ctx)
  53. expect(result.output).toContain(`"What is your favorite animal?"="Dog"`)
  54. })
  55. test("should throw an Error for header exceeding 30 characters", async () => {
  56. const tool = await QuestionTool.init()
  57. const questions = [
  58. {
  59. question: "What is your favorite animal?",
  60. header: "This Header is Definitely More Than Thirty Characters Long",
  61. options: [{ label: "Dog", description: "Man's best friend" }],
  62. },
  63. ]
  64. try {
  65. await tool.execute({ questions }, ctx)
  66. // If it reaches here, the test should fail
  67. expect(true).toBe(false)
  68. } catch (e: any) {
  69. expect(e).toBeInstanceOf(Error)
  70. expect(e.cause).toBeInstanceOf(z.ZodError)
  71. }
  72. })
  73. test("should throw an Error for label exceeding 30 characters", async () => {
  74. const tool = await QuestionTool.init()
  75. const questions = [
  76. {
  77. question: "A question with a very long label",
  78. header: "Long Label",
  79. options: [
  80. { label: "This is a very, very, very long label that will exceed the limit", description: "A description" },
  81. ],
  82. },
  83. ]
  84. try {
  85. await tool.execute({ questions }, ctx)
  86. // If it reaches here, the test should fail
  87. expect(true).toBe(false)
  88. } catch (e: any) {
  89. expect(e).toBeInstanceOf(Error)
  90. expect(e.cause).toBeInstanceOf(z.ZodError)
  91. }
  92. })
  93. })