Skip to content

Commit bd7d952

Browse files
committed
test: adjust for prompts view
1 parent b700779 commit bd7d952

File tree

2 files changed

+94
-77
lines changed

2 files changed

+94
-77
lines changed

webview-ui/src/components/prompts/PromptsView.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
8989
const [isToolsEditMode, setIsToolsEditMode] = useState(false)
9090
const [showConfigMenu, setShowConfigMenu] = useState(false)
9191
const [isCreateModeDialogOpen, setIsCreateModeDialogOpen] = useState(false)
92-
const [activeSupportTab, setActiveSupportTab] = useState<SupportPromptType>("ENHANCE")
92+
const [activeSupportOption, setActiveSupportOption] = useState<SupportPromptType>("ENHANCE")
9393
const [isSystemPromptDisclosureOpen, setIsSystemPromptDisclosureOpen] = useState(false)
9494

9595
// State for mode selection popover and search
@@ -975,7 +975,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
975975
})}
976976
</div>
977977
<Textarea
978-
value={customInstructions ?? ""}
978+
value={customInstructions}
979979
onChange={(e) => {
980980
const value =
981981
(e as unknown as CustomEvent)?.detail?.target?.value ||
@@ -1018,14 +1018,14 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
10181018
<h3 className="text-vscode-foreground mb-3">{t("prompts:supportPrompts.title")}</h3>
10191019
<div className="flex gap-4 items-center flex-wrap py-1">
10201020
<Select
1021-
value={activeSupportTab}
1022-
onValueChange={(type) => setActiveSupportTab(type as SupportPromptType)}>
1023-
<SelectTrigger className="w-full">
1021+
value={activeSupportOption}
1022+
onValueChange={(type) => setActiveSupportOption(type as SupportPromptType)}>
1023+
<SelectTrigger className="w-full" data-testid="support-prompt-select-trigger">
10241024
<SelectValue placeholder={t("settings:common.select")} />
10251025
</SelectTrigger>
10261026
<SelectContent>
10271027
{Object.keys(supportPrompt.default).map((type) => (
1028-
<SelectItem key={type} value={type}>
1028+
<SelectItem key={type} value={type} data-testid={`${type}-option`}>
10291029
{t(`prompts:supportPrompts.types.${type}.label`)}
10301030
</SelectItem>
10311031
))}
@@ -1035,38 +1035,37 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
10351035

10361036
{/* Support prompt description */}
10371037
<div className="text-[13px] text-vscode-descriptionForeground my-2 mb-4">
1038-
{t(`prompts:supportPrompts.types.${activeSupportTab}.description`)}
1038+
{t(`prompts:supportPrompts.types.${activeSupportOption}.description`)}
10391039
</div>
10401040

1041-
{/* Show active tab content */}
1042-
<div key={activeSupportTab}>
1041+
<div key={activeSupportOption}>
10431042
<div className="flex justify-between items-center mb-1">
10441043
<div className="font-bold">{t("prompts:supportPrompts.prompt")}</div>
10451044
<Button
10461045
variant="ghost"
10471046
size="icon"
1048-
onClick={() => handleSupportReset(activeSupportTab)}
1047+
onClick={() => handleSupportReset(activeSupportOption)}
10491048
title={t("prompts:supportPrompts.resetPrompt", {
1050-
promptType: activeSupportTab,
1049+
promptType: activeSupportOption,
10511050
})}>
10521051
<span className="codicon codicon-discard"></span>
10531052
</Button>
10541053
</div>
10551054

10561055
<Textarea
1057-
value={getSupportPromptValue(activeSupportTab)}
1056+
value={getSupportPromptValue(activeSupportOption)}
10581057
onChange={(e) => {
10591058
const value =
10601059
(e as unknown as CustomEvent)?.detail?.target?.value ||
10611060
((e as any).target as HTMLTextAreaElement).value
10621061
const trimmedValue = value.trim()
1063-
updateSupportPrompt(activeSupportTab, trimmedValue || undefined)
1062+
updateSupportPrompt(activeSupportOption, trimmedValue || undefined)
10641063
}}
10651064
rows={6}
10661065
className="resize-y w-full"
10671066
/>
10681067

1069-
{activeSupportTab === "ENHANCE" && (
1068+
{activeSupportOption === "ENHANCE" && (
10701069
<>
10711070
<div>
10721071
<div className="text-vscode-foreground text-[13px] mb-5 mt-1.5"></div>
@@ -1100,7 +1099,10 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
11001099
{t("prompts:supportPrompts.enhance.useCurrentConfig")}
11011100
</SelectItem>
11021101
{(listApiConfigMeta || []).map((config) => (
1103-
<SelectItem key={config.id} value={config.id}>
1102+
<SelectItem
1103+
key={config.id}
1104+
value={config.id}
1105+
data-testid={`${config.id}-option`}>
11041106
{config.name}
11051107
</SelectItem>
11061108
))}

webview-ui/src/components/prompts/__tests__/PromptsView.test.tsx

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ jest.mock("@src/utils/vscode", () => ({
1010
},
1111
}))
1212

13+
// Mock all lucide-react icons with a proxy to handle any icon requested
14+
jest.mock("lucide-react", () => {
15+
return new Proxy(
16+
{},
17+
{
18+
get: function (obj, prop) {
19+
// Return a component factory for any icon that's requested
20+
if (prop === "__esModule") {
21+
return true
22+
}
23+
return () => <div data-testid={`${String(prop)}-icon`}>{String(prop)}</div>
24+
},
25+
},
26+
)
27+
})
28+
1329
const mockExtensionState = {
1430
customModePrompts: {},
1531
listApiConfigMeta: [
@@ -19,6 +35,9 @@ const mockExtensionState = {
1935
enhancementApiConfigId: "",
2036
setEnhancementApiConfigId: jest.fn(),
2137
mode: "code",
38+
customModes: [],
39+
customSupportPrompts: [],
40+
currentApiConfigName: "",
2241
customInstructions: "Initial instructions",
2342
setCustomInstructions: jest.fn(),
2443
}
@@ -32,69 +51,67 @@ const renderPromptsView = (props = {}) => {
3251
)
3352
}
3453

54+
class MockResizeObserver {
55+
observe() {}
56+
unobserve() {}
57+
disconnect() {}
58+
}
59+
60+
global.ResizeObserver = MockResizeObserver
61+
62+
Element.prototype.scrollIntoView = jest.fn()
63+
3564
describe("PromptsView", () => {
3665
beforeEach(() => {
3766
jest.clearAllMocks()
3867
})
3968

40-
it("renders all mode tabs", () => {
41-
renderPromptsView()
42-
expect(screen.getByTestId("code-tab")).toBeInTheDocument()
43-
expect(screen.getByTestId("ask-tab")).toBeInTheDocument()
44-
expect(screen.getByTestId("architect-tab")).toBeInTheDocument()
69+
it("displays the current mode name in the select trigger", () => {
70+
renderPromptsView({ mode: "code" })
71+
const selectTrigger = screen.getByTestId("mode-select-trigger")
72+
expect(selectTrigger).toHaveTextContent("Code")
4573
})
4674

47-
it("defaults to current mode as active tab", () => {
48-
renderPromptsView({ mode: "ask" })
49-
50-
const codeTab = screen.getByTestId("code-tab")
51-
const askTab = screen.getByTestId("ask-tab")
52-
const architectTab = screen.getByTestId("architect-tab")
53-
54-
expect(askTab).toHaveAttribute("data-active", "true")
55-
expect(codeTab).toHaveAttribute("data-active", "false")
56-
expect(architectTab).toHaveAttribute("data-active", "false")
75+
it("opens the mode selection popover when the trigger is clicked", async () => {
76+
renderPromptsView()
77+
const selectTrigger = screen.getByTestId("mode-select-trigger")
78+
fireEvent.click(selectTrigger)
79+
await waitFor(() => {
80+
expect(selectTrigger).toHaveAttribute("aria-expanded", "true")
81+
})
5782
})
5883

59-
it("switches between tabs correctly", async () => {
60-
const { rerender } = render(
61-
<ExtensionStateContext.Provider value={{ ...mockExtensionState, mode: "code" } as any}>
62-
<PromptsView onDone={jest.fn()} />
63-
</ExtensionStateContext.Provider>,
64-
)
65-
66-
const codeTab = screen.getByTestId("code-tab")
67-
const askTab = screen.getByTestId("ask-tab")
68-
const architectTab = screen.getByTestId("architect-tab")
84+
it("filters mode options based on search input", async () => {
85+
renderPromptsView()
86+
const selectTrigger = screen.getByTestId("mode-select-trigger")
87+
fireEvent.click(selectTrigger)
6988

70-
// Initial state matches current mode (code)
71-
expect(codeTab).toHaveAttribute("data-active", "true")
72-
expect(askTab).toHaveAttribute("data-active", "false")
73-
expect(architectTab).toHaveAttribute("data-active", "false")
89+
const searchInput = screen.getByTestId("mode-search-input")
90+
fireEvent.change(searchInput, { target: { value: "ask" } })
7491

75-
// Click Ask tab and update context
76-
fireEvent.click(askTab)
77-
rerender(
78-
<ExtensionStateContext.Provider value={{ ...mockExtensionState, mode: "ask" } as any}>
79-
<PromptsView onDone={jest.fn()} />
80-
</ExtensionStateContext.Provider>,
81-
)
92+
await waitFor(() => {
93+
expect(screen.getByTestId("mode-option-ask")).toBeInTheDocument()
94+
expect(screen.queryByTestId("mode-option-code")).not.toBeInTheDocument()
95+
expect(screen.queryByTestId("mode-option-architect")).not.toBeInTheDocument()
96+
})
97+
})
8298

83-
expect(askTab).toHaveAttribute("data-active", "true")
84-
expect(codeTab).toHaveAttribute("data-active", "false")
85-
expect(architectTab).toHaveAttribute("data-active", "false")
99+
it("selects a mode from the dropdown and sends update message", async () => {
100+
renderPromptsView()
101+
const selectTrigger = screen.getByTestId("mode-select-trigger")
102+
fireEvent.click(selectTrigger)
86103

87-
// Click Architect tab and update context
88-
fireEvent.click(architectTab)
89-
rerender(
90-
<ExtensionStateContext.Provider value={{ ...mockExtensionState, mode: "architect" } as any}>
91-
<PromptsView onDone={jest.fn()} />
92-
</ExtensionStateContext.Provider>,
93-
)
104+
const askOption = await waitFor(() => screen.getByTestId("mode-option-ask"))
105+
fireEvent.click(askOption)
94106

95-
expect(architectTab).toHaveAttribute("data-active", "true")
96-
expect(askTab).toHaveAttribute("data-active", "false")
97-
expect(codeTab).toHaveAttribute("data-active", "false")
107+
expect(mockExtensionState.setEnhancementApiConfigId).not.toHaveBeenCalled() // Ensure this is not called by mode switch
108+
expect(vscode.postMessage).toHaveBeenCalledWith({
109+
type: "mode",
110+
text: "ask",
111+
})
112+
await waitFor(() => {
113+
expect(selectTrigger).toHaveAttribute("aria-expanded", "false")
114+
})
98115
})
99116

100117
it("handles prompt changes correctly", async () => {
@@ -159,21 +176,19 @@ describe("PromptsView", () => {
159176
it("handles API configuration selection", async () => {
160177
renderPromptsView()
161178

162-
// Click the ENHANCE tab first to show the API config dropdown
163-
const enhanceTab = screen.getByTestId("ENHANCE-tab")
164-
fireEvent.click(enhanceTab)
179+
const trigger = screen.getByTestId("support-prompt-select-trigger")
180+
fireEvent.click(trigger)
165181

166-
// Wait for the ENHANCE tab click to take effect
167-
const dropdown = await waitFor(() => screen.getByTestId("api-config-dropdown"))
168-
fireEvent.change(dropdown, {
169-
target: { value: "config1" },
170-
})
182+
const enhanceOption = await waitFor(() => screen.getByTestId("ENHANCE-option"))
183+
fireEvent.click(enhanceOption)
171184

172-
expect(mockExtensionState.setEnhancementApiConfigId).toHaveBeenCalledWith("config1")
173-
expect(vscode.postMessage).toHaveBeenCalledWith({
174-
type: "enhancementApiConfigId",
175-
text: "config1",
176-
})
185+
const apiConfig = await waitFor(() => screen.getByTestId("api-config-select"))
186+
fireEvent.click(apiConfig)
187+
188+
const config1 = await waitFor(() => screen.getByTestId("config1-option"))
189+
fireEvent.click(config1)
190+
191+
expect(mockExtensionState.setEnhancementApiConfigId).toHaveBeenCalledWith("config1") // Ensure this is not called by mode switch
177192
})
178193

179194
it("handles clearing custom instructions correctly", async () => {

0 commit comments

Comments
 (0)