Skip to content

Commit a0c25cc

Browse files
roomotedaniel-lxs
authored andcommitted
fix: update ContextManagementSettings tests to handle UI component mocks correctly
- Added role='combobox' to Select mock to fix accessibility test failures - Fixed checkbox assertions to target the input element instead of the wrapper - Added keyboard event handling to Slider mock for arrow key interactions - All 31 tests now pass successfully
1 parent 6b98b67 commit a0c25cc

File tree

1 file changed

+252
-1
lines changed

1 file changed

+252
-1
lines changed

webview-ui/src/components/settings/__tests__/ContextManagementSettings.spec.tsx

Lines changed: 252 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ vi.mock("@/components/ui", () => ({
2424
type="range"
2525
value={value?.[0] ?? 0}
2626
onChange={(e) => onValueChange([parseFloat(e.target.value)])}
27+
onKeyDown={(e) => {
28+
const currentValue = value?.[0] ?? 0
29+
if (e.key === "ArrowRight") {
30+
onValueChange([currentValue + 1])
31+
} else if (e.key === "ArrowLeft") {
32+
onValueChange([currentValue - 1])
33+
}
34+
}}
2735
data-testid={dataTestId}
2836
disabled={disabled}
2937
role="slider"
@@ -37,7 +45,11 @@ vi.mock("@/components/ui", () => ({
3745
{children}
3846
</button>
3947
),
40-
Select: ({ children, ...props }: any) => <div {...props}>{children}</div>,
48+
Select: ({ children, ...props }: any) => (
49+
<div role="combobox" {...props}>
50+
{children}
51+
</div>
52+
),
4153
SelectTrigger: ({ children, ...props }: any) => <div {...props}>{children}</div>,
4254
SelectValue: ({ children, ...props }: any) => <div {...props}>{children}</div>,
4355
SelectContent: ({ children, ...props }: any) => <div {...props}>{children}</div>,
@@ -303,4 +315,243 @@ describe("ContextManagementSettings", () => {
303315
})
304316
})
305317
})
318+
319+
320+
it("renders max read file line controls", () => {
321+
const propsWithMaxReadFileLine = {
322+
...defaultProps,
323+
maxReadFileLine: 500,
324+
}
325+
render(<ContextManagementSettings {...propsWithMaxReadFileLine} />)
326+
327+
// Max read file line input
328+
const maxReadFileInput = screen.getByTestId("max-read-file-line-input")
329+
expect(maxReadFileInput).toBeInTheDocument()
330+
expect(maxReadFileInput).toHaveValue(500)
331+
332+
// Always full read checkbox
333+
const alwaysFullReadCheckbox = screen.getByTestId("max-read-file-always-full-checkbox")
334+
expect(alwaysFullReadCheckbox).toBeInTheDocument()
335+
expect(alwaysFullReadCheckbox).not.toBeChecked()
336+
})
337+
338+
it("updates max read file line setting", () => {
339+
const propsWithMaxReadFileLine = {
340+
...defaultProps,
341+
maxReadFileLine: 500,
342+
}
343+
render(<ContextManagementSettings {...propsWithMaxReadFileLine} />)
344+
345+
const input = screen.getByTestId("max-read-file-line-input")
346+
fireEvent.change(input, { target: { value: "1000" } })
347+
348+
expect(defaultProps.setCachedStateField).toHaveBeenCalledWith("maxReadFileLine", 1000)
349+
})
350+
351+
it("toggles always full read setting", () => {
352+
const propsWithMaxReadFileLine = {
353+
...defaultProps,
354+
maxReadFileLine: 500,
355+
}
356+
render(<ContextManagementSettings {...propsWithMaxReadFileLine} />)
357+
358+
const checkbox = screen.getByTestId("max-read-file-always-full-checkbox")
359+
fireEvent.click(checkbox)
360+
361+
expect(defaultProps.setCachedStateField).toHaveBeenCalledWith("maxReadFileLine", -1)
362+
})
363+
364+
it("renders with autoCondenseContext enabled", () => {
365+
const propsWithAutoCondense = {
366+
...defaultProps,
367+
autoCondenseContext: true,
368+
autoCondenseContextPercent: 75,
369+
}
370+
render(<ContextManagementSettings {...propsWithAutoCondense} />)
371+
372+
// Should render the auto condense section
373+
const autoCondenseCheckbox = screen.getByTestId("auto-condense-context-checkbox")
374+
expect(autoCondenseCheckbox).toBeInTheDocument()
375+
376+
// Should render the threshold slider with correct value
377+
const slider = screen.getByTestId("condense-threshold-slider")
378+
expect(slider).toBeInTheDocument()
379+
380+
// Should render the profile select dropdown
381+
const selects = screen.getAllByRole("combobox")
382+
expect(selects).toHaveLength(1)
383+
})
384+
385+
describe("Auto Condense Context functionality", () => {
386+
const autoCondenseProps = {
387+
...defaultProps,
388+
autoCondenseContext: true,
389+
autoCondenseContextPercent: 75,
390+
listApiConfigMeta: [
391+
{ id: "config-1", name: "Config 1" },
392+
{ id: "config-2", name: "Config 2" },
393+
],
394+
}
395+
396+
it("toggles auto condense context setting", () => {
397+
const mockSetCachedStateField = vitest.fn()
398+
const props = { ...autoCondenseProps, setCachedStateField: mockSetCachedStateField }
399+
render(<ContextManagementSettings {...props} />)
400+
401+
const checkbox = screen.getByTestId("auto-condense-context-checkbox")
402+
const input = checkbox.querySelector('input[type="checkbox"]')
403+
expect(input).toBeChecked()
404+
405+
// Toggle off
406+
fireEvent.click(checkbox)
407+
expect(mockSetCachedStateField).toHaveBeenCalledWith("autoCondenseContext", false)
408+
})
409+
410+
it("shows threshold settings when auto condense is enabled", () => {
411+
render(<ContextManagementSettings {...autoCondenseProps} />)
412+
413+
// Threshold settings should be visible
414+
expect(screen.getByTestId("condense-threshold-slider")).toBeInTheDocument()
415+
// One combobox for profile selection
416+
expect(screen.getAllByRole("combobox")).toHaveLength(1)
417+
})
418+
419+
it("updates auto condense context percent", () => {
420+
const mockSetCachedStateField = vitest.fn()
421+
const props = { ...autoCondenseProps, setCachedStateField: mockSetCachedStateField }
422+
render(<ContextManagementSettings {...props} />)
423+
424+
// Find the condense threshold slider
425+
const slider = screen.getByTestId("condense-threshold-slider")
426+
427+
// Test slider interaction
428+
slider.focus()
429+
fireEvent.keyDown(slider, { key: "ArrowRight" })
430+
431+
expect(mockSetCachedStateField).toHaveBeenCalledWith("autoCondenseContextPercent", 76)
432+
})
433+
434+
it("displays correct auto condense context percent value", () => {
435+
render(<ContextManagementSettings {...autoCondenseProps} />)
436+
expect(screen.getByText("75%")).toBeInTheDocument()
437+
})
438+
})
439+
440+
it("renders max read file line controls with -1 value", () => {
441+
const propsWithMaxReadFileLine = {
442+
...defaultProps,
443+
maxReadFileLine: -1,
444+
}
445+
render(<ContextManagementSettings {...propsWithMaxReadFileLine} />)
446+
447+
const checkbox = screen.getByTestId("max-read-file-always-full-checkbox")
448+
const input = checkbox.querySelector('input[type="checkbox"]')
449+
expect(input).toBeChecked()
450+
})
451+
452+
it("handles boundary values for sliders", () => {
453+
const mockSetCachedStateField = vitest.fn()
454+
const props = {
455+
...defaultProps,
456+
maxOpenTabsContext: 0,
457+
maxWorkspaceFiles: 500,
458+
setCachedStateField: mockSetCachedStateField,
459+
}
460+
render(<ContextManagementSettings {...props} />)
461+
462+
// Check boundary values are displayed
463+
expect(screen.getByText("0")).toBeInTheDocument() // min open tabs
464+
expect(screen.getByText("500")).toBeInTheDocument() // max workspace files
465+
})
466+
467+
it("handles undefined optional props gracefully", () => {
468+
const propsWithUndefined = {
469+
...defaultProps,
470+
showRooIgnoredFiles: undefined,
471+
maxReadFileLine: undefined,
472+
}
473+
474+
expect(() => {
475+
render(<ContextManagementSettings {...propsWithUndefined} />)
476+
}).not.toThrow()
477+
478+
// Should use default values
479+
expect(screen.getByText("20")).toBeInTheDocument() // default maxOpenTabsContext
480+
expect(screen.getByText("200")).toBeInTheDocument() // default maxWorkspaceFiles
481+
})
482+
483+
describe("Conditional rendering", () => {
484+
it("does not render threshold settings when autoCondenseContext is false", () => {
485+
const propsWithoutAutoCondense = {
486+
...defaultProps,
487+
autoCondenseContext: false,
488+
}
489+
render(<ContextManagementSettings {...propsWithoutAutoCondense} />)
490+
491+
// When auto condense is false, threshold slider should not be visible
492+
expect(screen.queryByTestId("condense-threshold-slider")).not.toBeInTheDocument()
493+
})
494+
495+
it("renders max read file controls with default value when maxReadFileLine is undefined", () => {
496+
const propsWithoutMaxReadFile = {
497+
...defaultProps,
498+
maxReadFileLine: undefined,
499+
}
500+
render(<ContextManagementSettings {...propsWithoutMaxReadFile} />)
501+
502+
// Controls should still be rendered with default value of -1
503+
const input = screen.getByTestId("max-read-file-line-input")
504+
const checkbox = screen.getByTestId("max-read-file-always-full-checkbox")
505+
506+
expect(input).toBeInTheDocument()
507+
expect(input).toHaveValue(-1)
508+
expect(input).not.toBeDisabled() // Input is not disabled when maxReadFileLine is undefined (only when explicitly set to -1)
509+
expect(checkbox).toBeInTheDocument()
510+
expect(checkbox).not.toBeChecked() // Checkbox is not checked when maxReadFileLine is undefined (only when explicitly set to -1)
511+
})
512+
})
513+
514+
describe("Accessibility", () => {
515+
it("has proper labels and descriptions", () => {
516+
render(<ContextManagementSettings {...defaultProps} />)
517+
518+
// Check that labels are present
519+
expect(screen.getByText("settings:contextManagement.openTabs.label")).toBeInTheDocument()
520+
expect(screen.getByText("settings:contextManagement.workspaceFiles.label")).toBeInTheDocument()
521+
expect(screen.getByText("settings:contextManagement.rooignore.label")).toBeInTheDocument()
522+
523+
// Check that descriptions are present
524+
expect(screen.getByText("settings:contextManagement.openTabs.description")).toBeInTheDocument()
525+
expect(screen.getByText("settings:contextManagement.workspaceFiles.description")).toBeInTheDocument()
526+
expect(screen.getByText("settings:contextManagement.rooignore.description")).toBeInTheDocument()
527+
})
528+
529+
it("has proper test ids for all interactive elements", () => {
530+
const propsWithMaxReadFile = {
531+
...defaultProps,
532+
maxReadFileLine: 500,
533+
}
534+
render(<ContextManagementSettings {...propsWithMaxReadFile} />)
535+
536+
expect(screen.getByTestId("open-tabs-limit-slider")).toBeInTheDocument()
537+
expect(screen.getByTestId("workspace-files-limit-slider")).toBeInTheDocument()
538+
expect(screen.getByTestId("show-rooignored-files-checkbox")).toBeInTheDocument()
539+
expect(screen.getByTestId("max-read-file-line-input")).toBeInTheDocument()
540+
expect(screen.getByTestId("max-read-file-always-full-checkbox")).toBeInTheDocument()
541+
})
542+
})
543+
544+
describe("Integration with translation system", () => {
545+
it("uses translation keys for all text content", () => {
546+
render(<ContextManagementSettings {...defaultProps} />)
547+
548+
// Verify that translation keys are being used (mocked to return the key)
549+
expect(screen.getByText("settings:sections.contextManagement")).toBeInTheDocument()
550+
expect(screen.getByText("settings:contextManagement.description")).toBeInTheDocument()
551+
expect(screen.getByText("settings:contextManagement.openTabs.label")).toBeInTheDocument()
552+
expect(screen.getByText("settings:contextManagement.workspaceFiles.label")).toBeInTheDocument()
553+
expect(screen.getByText("settings:contextManagement.rooignore.label")).toBeInTheDocument()
554+
})
555+
})
556+
306557
})

0 commit comments

Comments
 (0)