diff --git a/packages/app/src/pages/session/composer/session-question-dock.test.ts b/packages/app/src/pages/session/composer/session-question-dock.test.ts new file mode 100644 index 000000000..5821bee68 --- /dev/null +++ b/packages/app/src/pages/session/composer/session-question-dock.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, test } from "bun:test" +import { resolveSkipAction } from "./session-question-dock" + +describe("resolveSkipAction", () => { + test("navigates to next unsettled question when one exists after current", () => { + // 3 questions: Q0 settled, Q1 unsettled, Q2 (current) just skipped → now settled + const isSettled = (i: number) => i !== 1 + const result = resolveSkipAction(2, isSettled, 3) + expect(result).toEqual({ type: "navigate", tab: 1 }) + }) + + test("navigates to first unsettled overall when nothing after current", () => { + // 3 questions: Q0 unsettled, Q1 settled, Q2 (current) just skipped → settled + const isSettled = (i: number) => i !== 0 + const result = resolveSkipAction(2, isSettled, 3) + expect(result).toEqual({ type: "navigate", tab: 0 }) + }) + + test("submits when there is only one question and it was just skipped", () => { + // Single question: Q0 just skipped → settled + const isSettled = () => true + const result = resolveSkipAction(0, isSettled, 1) + expect(result).toEqual({ type: "submit" }) + }) + + test("submits when all questions are settled after skipping the last one", () => { + // 3 questions: all settled (Q0 and Q1 answered, Q2 just skipped) + const isSettled = () => true + const result = resolveSkipAction(2, isSettled, 3) + expect(result).toEqual({ type: "submit" }) + }) + + test("navigates to next unsettled before current when current is not the last", () => { + // 3 questions: Q0 settled, Q1 (current) just skipped → settled, Q2 unsettled + const isSettled = (i: number) => i !== 2 + const result = resolveSkipAction(1, isSettled, 3) + expect(result).toEqual({ type: "navigate", tab: 2 }) + }) +}) diff --git a/packages/app/src/pages/session/composer/session-question-dock.tsx b/packages/app/src/pages/session/composer/session-question-dock.tsx index be6fb37c7..189631f4c 100644 --- a/packages/app/src/pages/session/composer/session-question-dock.tsx +++ b/packages/app/src/pages/session/composer/session-question-dock.tsx @@ -13,6 +13,27 @@ type DraftAnswer = QuestionAnswer | undefined const cache = new Map() +/** + * After skipping a question (setting its answer to []), decide the next action. + * Returns either the tab to navigate to, or a submit signal when all questions are settled. + */ +export function resolveSkipAction( + currentTab: number, + isSettled: (i: number) => boolean, + total: number, +): { type: "navigate"; tab: number } | { type: "submit" } { + // First, look for an unsettled question after the current tab. + for (let i = currentTab + 1; i < total; i++) { + if (!isSettled(i)) return { type: "navigate", tab: i } + } + // Then, look for any unsettled question before the current tab. + for (let i = 0; i < currentTab; i++) { + if (!isSettled(i)) return { type: "navigate", tab: i } + } + // All settled — time to submit. + return { type: "submit" } +} + function Mark(props: { multi: boolean; picked: boolean; onClick?: (event: MouseEvent) => void }) { return (