@@ -8,15 +8,25 @@ import type { CommandContext } from "../core/types.js"
88import type { Theme } from "../../types/theme.js"
99import type { CLIConfig } from "../../config/types.js"
1010
11+ // Mock the generateMessage utility
12+ vi . mock ( "../../ui/utils/messages.js" , ( ) => ( {
13+ generateMessage : vi . fn ( ( ) => ( {
14+ id : "mock-id" ,
15+ createdAt : Date . now ( ) ,
16+ } ) ) ,
17+ } ) )
18+
1119describe ( "/theme command" , ( ) => {
1220 let mockContext : CommandContext
1321 let addMessageMock : ReturnType < typeof vi . fn >
1422 let setThemeMock : ReturnType < typeof vi . fn >
23+ let refreshTerminalMock : ReturnType < typeof vi . fn >
24+ let mockConfig : CLIConfig
1525
1626 const mockTheme : Theme = {
1727 id : "custom-theme" ,
1828 name : "Test Theme" ,
19- type : "Custom " ,
29+ type : "custom " ,
2030 brand : {
2131 primary : "#007acc" ,
2232 secondary : "#005a9e" ,
@@ -83,6 +93,19 @@ describe("/theme command", () => {
8393 beforeEach ( ( ) => {
8494 addMessageMock = vi . fn ( )
8595 setThemeMock = vi . fn ( ) . mockResolvedValue ( undefined )
96+ refreshTerminalMock = vi . fn ( ) . mockResolvedValue ( undefined )
97+
98+ // Create mock config
99+ mockConfig = {
100+ version : "1.0.0" ,
101+ mode : "code" ,
102+ telemetry : true ,
103+ provider : "test-provider" ,
104+ providers : [ ] ,
105+ customThemes : {
106+ "custom-theme" : mockTheme ,
107+ } ,
108+ }
86109
87110 // Mock config loading
88111 vi . doMock ( "../../config/persistence.js" , ( ) => ( {
@@ -111,7 +134,7 @@ describe("/theme command", () => {
111134 dark : {
112135 id : "dark" ,
113136 name : "Dark" ,
114- type : "Dark " ,
137+ type : "dark " ,
115138 brand : { primary : "#3b82f6" , secondary : "#1d4ed8" } ,
116139 semantic : {
117140 success : "#4ade80" ,
@@ -146,7 +169,7 @@ describe("/theme command", () => {
146169 light : {
147170 id : "light" ,
148171 name : "Light" ,
149- type : "Light " ,
172+ type : "light " ,
150173 brand : { primary : "#3b82f6" , secondary : "#1d4ed8" } ,
151174 semantic : {
152175 success : "#4ade80" ,
@@ -184,7 +207,7 @@ describe("/theme command", () => {
184207 themes [ id ] || {
185208 id : "unknown" ,
186209 name : "Unknown Theme" ,
187- type : "Dark " ,
210+ type : "dark " ,
188211 brand : { primary : "#000000" , secondary : "#000000" } ,
189212 semantic : {
190213 success : "#000000" ,
@@ -230,14 +253,19 @@ describe("/theme command", () => {
230253 input : "/theme" ,
231254 args : [ ] ,
232255 options : { } ,
256+ config : mockConfig ,
233257 sendMessage : vi . fn ( ) . mockResolvedValue ( undefined ) ,
234258 addMessage : addMessageMock ,
235259 clearMessages : vi . fn ( ) ,
236260 replaceMessages : vi . fn ( ) ,
261+ setMessageCutoffTimestamp : vi . fn ( ) ,
237262 clearTask : vi . fn ( ) . mockResolvedValue ( undefined ) ,
238263 setMode : vi . fn ( ) ,
239264 exit : vi . fn ( ) ,
240265 setTheme : setThemeMock ,
266+ setCommittingParallelMode : vi . fn ( ) ,
267+ isParallelMode : false ,
268+ refreshTerminal : refreshTerminalMock ,
241269 // Model-related context
242270 routerModels : null ,
243271 currentProvider : null ,
@@ -251,6 +279,21 @@ describe("/theme command", () => {
251279 balanceData : null ,
252280 profileLoading : false ,
253281 balanceLoading : false ,
282+ // Task history context
283+ taskHistoryData : null ,
284+ taskHistoryFilters : {
285+ workspace : "current" ,
286+ sort : "newest" ,
287+ favoritesOnly : false ,
288+ } ,
289+ taskHistoryLoading : false ,
290+ taskHistoryError : null ,
291+ fetchTaskHistory : vi . fn ( ) . mockResolvedValue ( undefined ) ,
292+ updateTaskHistoryFilters : vi . fn ( ) . mockResolvedValue ( null ) ,
293+ changeTaskHistoryPage : vi . fn ( ) . mockResolvedValue ( null ) ,
294+ nextTaskHistoryPage : vi . fn ( ) . mockResolvedValue ( null ) ,
295+ previousTaskHistoryPage : vi . fn ( ) . mockResolvedValue ( null ) ,
296+ sendWebviewMessage : vi . fn ( ) . mockResolvedValue ( undefined ) ,
254297 }
255298 } )
256299
@@ -308,17 +351,17 @@ describe("/theme command", () => {
308351 const message = addMessageMock . mock . calls [ 0 ] [ 0 ]
309352 expect ( message . type ) . toBe ( "system" )
310353 expect ( message . content ) . toContain ( "Available Themes:" )
311- expect ( message . content ) . toContain ( "**Dark :**" )
312- expect ( message . content ) . toContain ( "**Light :**" )
313- expect ( message . content ) . toContain ( "**Custom :**" )
354+ expect ( message . content ) . toContain ( "**dark :**" )
355+ expect ( message . content ) . toContain ( "**light :**" )
356+ expect ( message . content ) . toContain ( "**custom :**" )
314357 expect ( message . content ) . toContain ( "Usage: /theme <theme-name>" )
315358 } )
316359
317360 it ( "should show custom themes when present" , async ( ) => {
318361 await themeCommand . handler ( mockContext )
319362
320363 const message = addMessageMock . mock . calls [ 0 ] [ 0 ]
321- expect ( message . content ) . toContain ( "**Custom :**" )
364+ expect ( message . content ) . toContain ( "**custom :**" )
322365 expect ( message . content ) . toContain ( "Test Theme" )
323366 expect ( message . content ) . toContain ( "(custom-theme)" )
324367 } )
@@ -330,27 +373,29 @@ describe("/theme command", () => {
330373
331374 await themeCommand . handler ( mockContext )
332375
333- expect ( setThemeMock ) . toHaveBeenCalledTimes ( 1 )
334- expect ( setThemeMock ) . toHaveBeenCalledWith ( "dark" )
335-
336376 expect ( addMessageMock ) . toHaveBeenCalledTimes ( 1 )
337377 const message = addMessageMock . mock . calls [ 0 ] [ 0 ]
338378 expect ( message . type ) . toBe ( "system" )
339379 expect ( message . content ) . toContain ( "Switched to **Dark** theme." )
380+
381+ expect ( setThemeMock ) . toHaveBeenCalledTimes ( 1 )
382+ expect ( setThemeMock ) . toHaveBeenCalledWith ( "dark" )
383+ expect ( refreshTerminalMock ) . toHaveBeenCalledTimes ( 1 )
340384 } )
341385
342386 it ( "should switch to a custom theme" , async ( ) => {
343387 mockContext . args = [ "custom-theme" ]
344388
345389 await themeCommand . handler ( mockContext )
346390
347- expect ( setThemeMock ) . toHaveBeenCalledTimes ( 1 )
348- expect ( setThemeMock ) . toHaveBeenCalledWith ( "custom-theme" )
349-
350391 expect ( addMessageMock ) . toHaveBeenCalledTimes ( 1 )
351392 const message = addMessageMock . mock . calls [ 0 ] [ 0 ]
352393 expect ( message . type ) . toBe ( "system" )
353394 expect ( message . content ) . toContain ( "Switched to **Test Theme** theme." )
395+
396+ expect ( setThemeMock ) . toHaveBeenCalledTimes ( 1 )
397+ expect ( setThemeMock ) . toHaveBeenCalledWith ( "custom-theme" )
398+ expect ( refreshTerminalMock ) . toHaveBeenCalledTimes ( 1 )
354399 } )
355400
356401 it ( "should show error for invalid theme" , async ( ) => {
@@ -375,13 +420,18 @@ describe("/theme command", () => {
375420
376421 await themeCommand . handler ( mockContext )
377422
378- expect ( setThemeMock ) . toHaveBeenCalledWith ( "dark" )
423+ // Message is added before setTheme, then error message is added
424+ expect ( addMessageMock ) . toHaveBeenCalledTimes ( 2 )
425+ const successMessage = addMessageMock . mock . calls [ 0 ] [ 0 ]
426+ expect ( successMessage . type ) . toBe ( "system" )
427+ expect ( successMessage . content ) . toContain ( "Switched to **Dark** theme." )
379428
380- expect ( addMessageMock ) . toHaveBeenCalledTimes ( 1 )
381- const message = addMessageMock . mock . calls [ 0 ] [ 0 ]
382- expect ( message . type ) . toBe ( "error" )
383- expect ( message . content ) . toContain ( "Failed to switch to **Dark** theme" )
384- expect ( message . content ) . toContain ( "Theme switching failed" )
429+ const errorMessage = addMessageMock . mock . calls [ 1 ] [ 0 ]
430+ expect ( errorMessage . type ) . toBe ( "error" )
431+ expect ( errorMessage . content ) . toContain ( "Failed to switch to **Dark** theme" )
432+ expect ( errorMessage . content ) . toContain ( "Theme switching failed" )
433+
434+ expect ( setThemeMock ) . toHaveBeenCalledWith ( "dark" )
385435 } )
386436
387437 it ( "should handle case insensitive theme names" , async ( ) => {
@@ -476,9 +526,9 @@ describe("/theme command", () => {
476526 expect ( firstSuggestion ) . toHaveProperty ( "matchScore" )
477527
478528 // Check that we have themes of different types
479- const hasDark = suggestions . some ( ( s ) => typeof s !== "string" && s . description === "Dark " )
480- const hasLight = suggestions . some ( ( s ) => typeof s !== "string" && s . description === "Light " )
481- const hasCustom = suggestions . some ( ( s ) => typeof s !== "string" && s . description === "Custom " )
529+ const hasDark = suggestions . some ( ( s ) => typeof s !== "string" && s . description === "dark " )
530+ const hasLight = suggestions . some ( ( s ) => typeof s !== "string" && s . description === "light " )
531+ const hasCustom = suggestions . some ( ( s ) => typeof s !== "string" && s . description === "custom " )
482532
483533 expect ( hasDark ) . toBe ( true )
484534 expect ( hasLight ) . toBe ( true )
@@ -517,7 +567,7 @@ describe("/theme command", () => {
517567 command : themeCommand ,
518568 commandContext : {
519569 ...mockContext ,
520- config : { } as Record < string , unknown > , // Using an empty object to simulate config loading issues
570+ config : { } as CLIConfig ,
521571 } ,
522572 }
523573
0 commit comments