@@ -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