@@ -5,7 +5,6 @@ import SettingsMenu from '../SettingsMenu'
5
5
import { useNavigate , useMatches } from '@tanstack/react-router'
6
6
import { useGeneralSetting } from '@/hooks/useGeneralSetting'
7
7
import { useModelProvider } from '@/hooks/useModelProvider'
8
- import { useAppState } from '@/hooks/useAppState'
9
8
10
9
// Mock dependencies
11
10
vi . mock ( '@tanstack/react-router' , ( ) => ( {
@@ -25,9 +24,7 @@ vi.mock('@/i18n/react-i18next-compat', () => ({
25
24
} ) )
26
25
27
26
vi . mock ( '@/hooks/useGeneralSetting' , ( ) => ( {
28
- useGeneralSetting : vi . fn ( ( ) => ( {
29
- experimentalFeatures : false ,
30
- } ) ) ,
27
+ useGeneralSetting : vi . fn ( ( ) => ( { } ) ) ,
31
28
} ) )
32
29
33
30
vi . mock ( '@/hooks/useModelProvider' , ( ) => ( {
@@ -71,14 +68,14 @@ describe('SettingsMenu', () => {
71
68
72
69
beforeEach ( ( ) => {
73
70
vi . clearAllMocks ( )
74
-
71
+
75
72
vi . mocked ( useNavigate ) . mockReturnValue ( mockNavigate )
76
73
vi . mocked ( useMatches ) . mockReturnValue ( mockMatches )
77
74
} )
78
75
79
76
it ( 'renders all menu items' , ( ) => {
80
77
render ( < SettingsMenu /> )
81
-
78
+
82
79
expect ( screen . getByText ( 'common:general' ) ) . toBeInTheDocument ( )
83
80
expect ( screen . getByText ( 'common:appearance' ) ) . toBeInTheDocument ( )
84
81
expect ( screen . getByText ( 'common:privacy' ) ) . toBeInTheDocument ( )
@@ -88,29 +85,14 @@ describe('SettingsMenu', () => {
88
85
expect ( screen . getByText ( 'common:local_api_server' ) ) . toBeInTheDocument ( )
89
86
expect ( screen . getByText ( 'common:https_proxy' ) ) . toBeInTheDocument ( )
90
87
expect ( screen . getByText ( 'common:extensions' ) ) . toBeInTheDocument ( )
91
- } )
92
-
93
- it ( 'does not show MCP Servers when experimental features disabled' , ( ) => {
94
- render ( < SettingsMenu /> )
95
-
96
- expect ( screen . queryByText ( 'common:mcp-servers' ) ) . not . toBeInTheDocument ( )
97
- } )
98
-
99
- it ( 'shows MCP Servers when experimental features enabled' , ( ) => {
100
- vi . mocked ( useGeneralSetting ) . mockReturnValue ( {
101
- experimentalFeatures : true ,
102
- } )
103
-
104
- render ( < SettingsMenu /> )
105
-
106
88
expect ( screen . getByText ( 'common:mcp-servers' ) ) . toBeInTheDocument ( )
107
89
} )
108
90
109
91
it ( 'shows provider expansion chevron when providers are active' , ( ) => {
110
92
render ( < SettingsMenu /> )
111
-
93
+
112
94
const chevronButtons = screen . getAllByRole ( 'button' )
113
- const chevron = chevronButtons . find ( button =>
95
+ const chevron = chevronButtons . find ( ( button ) =>
114
96
button . querySelector ( 'svg.tabler-icon-chevron-right' )
115
97
)
116
98
expect ( chevron ) . toBeInTheDocument ( )
@@ -119,14 +101,14 @@ describe('SettingsMenu', () => {
119
101
it ( 'expands providers submenu when chevron is clicked' , async ( ) => {
120
102
const user = userEvent . setup ( )
121
103
render ( < SettingsMenu /> )
122
-
104
+
123
105
const chevronButtons = screen . getAllByRole ( 'button' )
124
- const chevron = chevronButtons . find ( button =>
106
+ const chevron = chevronButtons . find ( ( button ) =>
125
107
button . querySelector ( 'svg.tabler-icon-chevron-right' )
126
108
)
127
109
if ( ! chevron ) throw new Error ( 'Chevron button not found' )
128
110
await user . click ( chevron )
129
-
111
+
130
112
expect ( screen . getByTestId ( 'provider-avatar-openai' ) ) . toBeInTheDocument ( )
131
113
expect ( screen . getByTestId ( 'provider-avatar-llama.cpp' ) ) . toBeInTheDocument ( )
132
114
} )
@@ -138,52 +120,56 @@ describe('SettingsMenu', () => {
138
120
params : { providerName : 'openai' } ,
139
121
} ,
140
122
] )
141
-
123
+
142
124
render ( < SettingsMenu /> )
143
-
125
+
144
126
expect ( screen . getByTestId ( 'provider-avatar-openai' ) ) . toBeInTheDocument ( )
145
127
expect ( screen . getByTestId ( 'provider-avatar-llama.cpp' ) ) . toBeInTheDocument ( )
146
128
} )
147
129
148
130
it ( 'highlights active provider in submenu' , async ( ) => {
149
131
const user = userEvent . setup ( )
150
-
132
+
151
133
vi . mocked ( useMatches ) . mockReturnValue ( [
152
134
{
153
135
routeId : '/settings/providers/$providerName' ,
154
136
params : { providerName : 'openai' } ,
155
137
} ,
156
138
] )
157
-
139
+
158
140
render ( < SettingsMenu /> )
159
-
141
+
160
142
// First expand the providers submenu
161
143
const chevronButtons = screen . getAllByRole ( 'button' )
162
- const chevron = chevronButtons . find ( button =>
144
+ const chevron = chevronButtons . find ( ( button ) =>
163
145
button . querySelector ( 'svg.tabler-icon-chevron-right' )
164
146
)
165
147
if ( chevron ) await user . click ( chevron )
166
-
167
- const openaiProvider = screen . getByTestId ( 'provider-avatar-openai' ) . closest ( 'div' )
148
+
149
+ const openaiProvider = screen
150
+ . getByTestId ( 'provider-avatar-openai' )
151
+ . closest ( 'div' )
168
152
expect ( openaiProvider ) . toBeInTheDocument ( )
169
153
} )
170
154
171
155
it ( 'navigates to provider when provider is clicked' , async ( ) => {
172
156
const user = userEvent . setup ( )
173
157
render ( < SettingsMenu /> )
174
-
158
+
175
159
// First expand the providers
176
160
const chevronButtons = screen . getAllByRole ( 'button' )
177
- const chevron = chevronButtons . find ( button =>
161
+ const chevron = chevronButtons . find ( ( button ) =>
178
162
button . querySelector ( 'svg.tabler-icon-chevron-right' )
179
163
)
180
164
if ( ! chevron ) throw new Error ( 'Chevron button not found' )
181
165
await user . click ( chevron )
182
-
166
+
183
167
// Then click on a provider
184
- const openaiProvider = screen . getByTestId ( 'provider-avatar-openai' ) . closest ( 'div' )
168
+ const openaiProvider = screen
169
+ . getByTestId ( 'provider-avatar-openai' )
170
+ . closest ( 'div' )
185
171
await user . click ( openaiProvider ! )
186
-
172
+
187
173
expect ( mockNavigate ) . toHaveBeenCalledWith ( {
188
174
to : '/settings/providers/$providerName' ,
189
175
params : { providerName : 'openai' } ,
@@ -192,18 +178,22 @@ describe('SettingsMenu', () => {
192
178
193
179
it ( 'shows mobile menu toggle button' , ( ) => {
194
180
render ( < SettingsMenu /> )
195
-
196
- const menuToggle = screen . getByRole ( 'button' , { name : 'Toggle settings menu' } )
181
+
182
+ const menuToggle = screen . getByRole ( 'button' , {
183
+ name : 'Toggle settings menu' ,
184
+ } )
197
185
expect ( menuToggle ) . toBeInTheDocument ( )
198
186
} )
199
187
200
188
it ( 'opens mobile menu when toggle is clicked' , async ( ) => {
201
189
const user = userEvent . setup ( )
202
190
render ( < SettingsMenu /> )
203
-
204
- const menuToggle = screen . getByRole ( 'button' , { name : 'Toggle settings menu' } )
191
+
192
+ const menuToggle = screen . getByRole ( 'button' , {
193
+ name : 'Toggle settings menu' ,
194
+ } )
205
195
await user . click ( menuToggle )
206
-
196
+
207
197
// Menu should now be visible
208
198
const menu = screen . getByText ( 'common:general' ) . closest ( 'div' )
209
199
expect ( menu ) . toHaveClass ( 'flex' )
@@ -212,38 +202,40 @@ describe('SettingsMenu', () => {
212
202
it ( 'closes mobile menu when X is clicked' , async ( ) => {
213
203
const user = userEvent . setup ( )
214
204
render ( < SettingsMenu /> )
215
-
205
+
216
206
// Open menu first
217
- const menuToggle = screen . getByRole ( 'button' , { name : 'Toggle settings menu' } )
207
+ const menuToggle = screen . getByRole ( 'button' , {
208
+ name : 'Toggle settings menu' ,
209
+ } )
218
210
await user . click ( menuToggle )
219
-
211
+
220
212
// Then close it
221
213
await user . click ( menuToggle )
222
-
214
+
223
215
// Just verify the toggle button is still there after clicking twice
224
216
expect ( menuToggle ) . toBeInTheDocument ( )
225
217
} )
226
218
227
219
it ( 'hides llamacpp provider during setup remote provider step' , async ( ) => {
228
220
const user = userEvent . setup ( )
229
-
221
+
230
222
vi . mocked ( useMatches ) . mockReturnValue ( [
231
223
{
232
224
routeId : '/settings/providers/' ,
233
225
params : { } ,
234
226
search : { step : 'setup_remote_provider' } ,
235
227
} ,
236
228
] )
237
-
229
+
238
230
render ( < SettingsMenu /> )
239
-
231
+
240
232
// First expand the providers submenu
241
233
const chevronButtons = screen . getAllByRole ( 'button' )
242
- const chevron = chevronButtons . find ( button =>
234
+ const chevron = chevronButtons . find ( ( button ) =>
243
235
button . querySelector ( 'svg.tabler-icon-chevron-right' )
244
236
)
245
237
if ( chevron ) await user . click ( chevron )
246
-
238
+
247
239
// llamacpp provider div should have hidden class
248
240
const llamacppElement = screen . getByTestId ( 'provider-avatar-llama.cpp' )
249
241
expect ( llamacppElement . parentElement ) . toHaveClass ( 'hidden' )
@@ -253,7 +245,7 @@ describe('SettingsMenu', () => {
253
245
254
246
it ( 'filters out inactive providers from submenu' , async ( ) => {
255
247
const user = userEvent . setup ( )
256
-
248
+
257
249
vi . mocked ( useModelProvider ) . mockReturnValue ( {
258
250
providers : [
259
251
{
@@ -268,17 +260,19 @@ describe('SettingsMenu', () => {
268
260
} ,
269
261
] ,
270
262
} )
271
-
263
+
272
264
render ( < SettingsMenu /> )
273
-
265
+
274
266
// Expand providers
275
267
const chevronButtons = screen . getAllByRole ( 'button' )
276
- const chevron = chevronButtons . find ( button =>
268
+ const chevron = chevronButtons . find ( ( button ) =>
277
269
button . querySelector ( 'svg.tabler-icon-chevron-right' )
278
270
)
279
271
if ( chevron ) await user . click ( chevron )
280
-
272
+
281
273
expect ( screen . getByTestId ( 'provider-avatar-openai' ) ) . toBeInTheDocument ( )
282
- expect ( screen . queryByTestId ( 'provider-avatar-anthropic' ) ) . not . toBeInTheDocument ( )
274
+ expect (
275
+ screen . queryByTestId ( 'provider-avatar-anthropic' )
276
+ ) . not . toBeInTheDocument ( )
283
277
} )
284
- } )
278
+ } )
0 commit comments