import { test, expect } from "bun:test" import { Question } from "../../src/question" import { Instance } from "../../src/project/instance" import { tmpdir } from "../fixture/fixture" test("ask - returns pending promise", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const promise = Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) expect(promise).toBeInstanceOf(Promise) }, }) }) test("ask - adds to pending list", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const questions = [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ] Question.ask({ sessionID: "ses_test", questions, }) const pending = await Question.list() expect(pending.length).toBe(1) expect(pending[0].questions).toEqual(questions) }, }) }) // reply tests test("reply - resolves the pending ask with answers", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const questions = [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ] const askPromise = Question.ask({ sessionID: "ses_test", questions, }) const pending = await Question.list() const requestID = pending[0].id await Question.reply({ requestID, answers: [["Option 1"]], }) const answers = await askPromise expect(answers).toEqual([["Option 1"]]) }, }) }) test("reply - removes from pending list", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) const pending = await Question.list() expect(pending.length).toBe(1) await Question.reply({ requestID: pending[0].id, answers: [["Option 1"]], }) const pendingAfter = await Question.list() expect(pendingAfter.length).toBe(0) }, }) }) test("reply - does nothing for unknown requestID", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { await Question.reply({ requestID: "que_unknown", answers: [["Option 1"]], }) // Should not throw }, }) }) // reject tests test("reject - throws RejectedError", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const askPromise = Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) const pending = await Question.list() await Question.reject(pending[0].id) await expect(askPromise).rejects.toBeInstanceOf(Question.RejectedError) }, }) }) test("reject - removes from pending list", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const askPromise = Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) const pending = await Question.list() expect(pending.length).toBe(1) await Question.reject(pending[0].id) askPromise.catch(() => {}) // Ignore rejection const pendingAfter = await Question.list() expect(pendingAfter.length).toBe(0) }, }) }) test("reject - does nothing for unknown requestID", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { await Question.reject("que_unknown") // Should not throw }, }) }) // multiple questions tests test("ask - handles multiple questions", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const questions = [ { question: "What would you like to do?", header: "Action", options: [ { label: "Build", description: "Build the project" }, { label: "Test", description: "Run tests" }, ], }, { question: "Which environment?", header: "Env", options: [ { label: "Dev", description: "Development" }, { label: "Prod", description: "Production" }, ], }, ] const askPromise = Question.ask({ sessionID: "ses_test", questions, }) const pending = await Question.list() await Question.reply({ requestID: pending[0].id, answers: [["Build"], ["Dev"]], }) const answers = await askPromise expect(answers).toEqual([["Build"], ["Dev"]]) }, }) }) // list tests test("list - returns all pending requests", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { Question.ask({ sessionID: "ses_test1", questions: [ { question: "Question 1?", header: "Q1", options: [{ label: "A", description: "A" }], }, ], }) Question.ask({ sessionID: "ses_test2", questions: [ { question: "Question 2?", header: "Q2", options: [{ label: "B", description: "B" }], }, ], }) const pending = await Question.list() expect(pending.length).toBe(2) }, }) }) test("list - returns empty when no pending", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const pending = await Question.list() expect(pending.length).toBe(0) }, }) })