| ... | ... | @@ -1,6 +1,64 @@ |
| 1 | | import { describe, expect, it } from "vite-plus/test"; |
| 1 | import { createElement } from "react"; |
| 2 | import { renderToStaticMarkup } from "react-dom/server"; |
| 3 | import { describe, expect, it, vi } from "vite-plus/test"; |
| 2 | 4 | |
| 3 | | import { formatPendingPrimaryActionLabel } from "./ComposerPrimaryActions"; |
| 5 | vi.mock("~/hooks/useSettings", () => ({ |
| 6 | useEnvironmentIdentificationMode: () => "none", |
| 7 | })); |
| 8 | vi.mock("../SidebarStageBackdrop", () => ({ |
| 9 | StageBackdropButtonArt: () => null, |
| 10 | useSidebarStageBackdropVariant: () => null, |
| 11 | })); |
| 12 | |
| 13 | import { ComposerPrimaryActions, formatPendingPrimaryActionLabel } from "./ComposerPrimaryActions"; |
| 14 | |
| 15 | function renderPendingActions(isRunning: boolean) { |
| 16 | return renderToStaticMarkup( |
| 17 | createElement(ComposerPrimaryActions, { |
| 18 | compact: true, |
| 19 | pendingAction: { |
| 20 | questionIndex: 0, |
| 21 | isLastQuestion: true, |
| 22 | canAdvance: true, |
| 23 | isResponding: false, |
| 24 | isComplete: true, |
| 25 | }, |
| 26 | isRunning, |
| 27 | showPlanFollowUpPrompt: false, |
| 28 | promptHasText: false, |
| 29 | isSendBusy: false, |
| 30 | sendDisabledReason: null, |
| 31 | isConnecting: false, |
| 32 | isEnvironmentUnavailable: false, |
| 33 | isPreparingWorktree: false, |
| 34 | hasSendableContent: false, |
| 35 | onPreviousPendingQuestion: () => {}, |
| 36 | onInterrupt: () => {}, |
| 37 | onImplementPlanInNewThread: () => {}, |
| 38 | }), |
| 39 | ); |
| 40 | } |
| 41 | |
| 42 | function renderStandaloneStop() { |
| 43 | return renderToStaticMarkup( |
| 44 | createElement(ComposerPrimaryActions, { |
| 45 | compact: true, |
| 46 | pendingAction: null, |
| 47 | isRunning: true, |
| 48 | showPlanFollowUpPrompt: false, |
| 49 | promptHasText: false, |
| 50 | isSendBusy: false, |
| 51 | sendDisabledReason: null, |
| 52 | isConnecting: false, |
| 53 | isEnvironmentUnavailable: false, |
| 54 | isPreparingWorktree: false, |
| 55 | hasSendableContent: false, |
| 56 | onPreviousPendingQuestion: () => {}, |
| 57 | onInterrupt: () => {}, |
| 58 | onImplementPlanInNewThread: () => {}, |
| 59 | }), |
| 60 | ); |
| 61 | } |
| 4 | 62 | |
| 5 | 63 | describe("formatPendingPrimaryActionLabel", () => { |
| 6 | 64 | it("returns 'Submitting...' while responding", () => { |
| ... | ... | @@ -91,3 +149,19 @@ describe("formatPendingPrimaryActionLabel", () => { |
| 91 | 149 | ).toBe("Submit answers"); |
| 92 | 150 | }); |
| 93 | 151 | }); |
| 152 | |
| 153 | describe("ComposerPrimaryActions", () => { |
| 154 | it("offers Stop generation while a running turn is waiting for user input", () => { |
| 155 | expect(renderPendingActions(true)).toContain('aria-label="Stop generation"'); |
| 156 | }); |
| 157 | |
| 158 | it("does not offer Stop generation for a pending request without a running turn", () => { |
| 159 | expect(renderPendingActions(false)).not.toContain('aria-label="Stop generation"'); |
| 160 | }); |
| 161 | |
| 162 | it("matches the small pending action size without changing the standalone size", () => { |
| 163 | expect(renderPendingActions(true)).toContain("size-8 sm:size-7"); |
| 164 | expect(renderStandaloneStop()).toContain("size-8 sm:h-8 sm:w-8"); |
| 165 | expect(renderStandaloneStop()).not.toContain("sm:size-7"); |
| 166 | }); |
| 167 | }); |