1+ import { describe , it , expect , beforeEach , vi } from 'vitest'
2+ import { render , screen , waitFor } from '@testing-library/react'
3+ import '@testing-library/jest-dom'
4+
5+ // Mock all the dependencies with minimal implementation
6+ vi . mock ( '@/containers/SettingsMenu' , ( ) => ( {
7+ default : ( ) => < div data-testid = "settings-menu" > Settings Menu</ div > ,
8+ } ) )
9+
10+ vi . mock ( '@/containers/HeaderPage' , ( ) => ( {
11+ default : ( { children } : { children : React . ReactNode } ) => (
12+ < div data-testid = "header-page" > { children } </ div >
13+ ) ,
14+ } ) )
15+
16+ vi . mock ( '@/containers/Card' , ( ) => ( {
17+ Card : ( { title, children } : { title ?: string ; children : React . ReactNode } ) => (
18+ < div data-testid = "card" >
19+ { title && < div > { title } </ div > }
20+ { children }
21+ </ div >
22+ ) ,
23+ CardItem : ( { title, actions } : { title ?: string ; actions ?: React . ReactNode } ) => (
24+ < div data-testid = "card-item" >
25+ { title && < div > { title } </ div > }
26+ { actions }
27+ </ div >
28+ ) ,
29+ } ) )
30+
31+ vi . mock ( '@/components/ui/switch' , ( ) => ( {
32+ Switch : ( { checked } : { checked : boolean } ) => (
33+ < input data-testid = "switch" type = "checkbox" checked = { checked } readOnly />
34+ ) ,
35+ } ) )
36+
37+ vi . mock ( '@/components/ui/progress' , ( ) => ( {
38+ Progress : ( { value } : { value : number } ) => (
39+ < div data-testid = "progress" > Progress: { value } %</ div >
40+ ) ,
41+ } ) )
42+
43+ vi . mock ( '@/i18n/react-i18next-compat' , ( ) => ( {
44+ useTranslation : ( ) => ( { t : ( key : string ) => key } ) ,
45+ } ) )
46+
47+ vi . mock ( '@/hooks/useHardware' , ( ) => ( {
48+ useHardware : ( ) => ( {
49+ hardwareData : {
50+ os_type : 'windows' ,
51+ os_name : 'Windows 11' ,
52+ cpu : { name : 'Intel i7' , arch : 'x64' , core_count : 8 , extensions : [ 'SSE' ] } ,
53+ total_memory : 16384 ,
54+ } ,
55+ systemUsage : { cpu : 50 , used_memory : 8192 } ,
56+ setHardwareData : vi . fn ( ) ,
57+ updateSystemUsage : vi . fn ( ) ,
58+ pollingPaused : false ,
59+ } ) ,
60+ } ) )
61+
62+ vi . mock ( '@/hooks/useLlamacppDevices' , ( ) => ( {
63+ useLlamacppDevices : ( ) => ( {
64+ devices : [ { id : 'gpu0' , name : 'RTX 3080' , mem : 10240 , free : 8192 } ] ,
65+ loading : false ,
66+ error : null ,
67+ activatedDevices : new Set ( [ 'gpu0' ] ) ,
68+ toggleDevice : vi . fn ( ) ,
69+ fetchDevices : vi . fn ( ) ,
70+ } ) ,
71+ getState : ( ) => ( { setActivatedDevices : vi . fn ( ) } ) ,
72+ } ) )
73+
74+ vi . mock ( '@/hooks/useModelProvider' , ( ) => ( {
75+ useModelProvider : ( ) => ( {
76+ providers : [ { provider : 'llamacpp' } ] ,
77+ getProviderByName : vi . fn ( ( ) => ( { settings : [ { key : 'device' , controller_props : { value : 'gpu0' } } ] } ) ) ,
78+ } ) ,
79+ } ) )
80+
81+ vi . mock ( '@/services/hardware' , ( ) => ( {
82+ getHardwareInfo : vi . fn ( ( ) => Promise . resolve ( { } ) ) ,
83+ getSystemUsage : vi . fn ( ( ) => Promise . resolve ( { } ) ) ,
84+ } ) )
85+
86+ vi . mock ( '@/services/models' , ( ) => ( { stopAllModels : vi . fn ( ) } ) )
87+ vi . mock ( '@/lib/utils' , ( ) => ( { formatMegaBytes : ( mb : number ) => `${ mb } MB` } ) )
88+ vi . mock ( '@/utils/number' , ( ) => ( { toNumber : ( n : number ) => n } ) )
89+ vi . mock ( '@tauri-apps/api/webviewWindow' , ( ) => ( { WebviewWindow : vi . fn ( ) } ) )
90+ vi . mock ( '@/constants/routes' , ( ) => ( {
91+ route : {
92+ settings : {
93+ hardware : '/settings/hardware'
94+ } ,
95+ systemMonitor : '/monitor'
96+ }
97+ } ) )
98+ vi . mock ( '@/constants/windows' , ( ) => ( { windowKey : { systemMonitorWindow : 'monitor' } } ) )
99+ vi . mock ( '@tabler/icons-react' , ( ) => ( { IconDeviceDesktopAnalytics : ( ) => < div data-testid = "icon" /> } ) )
100+
101+ // Mock the route structure properly
102+ vi . mock ( '@tanstack/react-router' , ( ) => ( {
103+ createFileRoute : ( ) => ( config : any ) => config ,
104+ } ) )
105+
106+ global . IS_MACOS = false
107+
108+ // Import the actual component after all mocks are set up
109+ import { Route } from '../hardware'
110+
111+ describe ( 'Hardware Settings' , ( ) => {
112+ beforeEach ( ( ) => {
113+ vi . clearAllMocks ( )
114+ global . IS_MACOS = false
115+ } )
116+
117+ it ( 'renders hardware settings page' , ( ) => {
118+ const Component = Route . component as React . ComponentType
119+ render ( < Component /> )
120+
121+ expect ( screen . getByTestId ( 'header-page' ) ) . toBeInTheDocument ( )
122+ expect ( screen . getByTestId ( 'settings-menu' ) ) . toBeInTheDocument ( )
123+ } )
124+
125+ it ( 'displays OS information' , async ( ) => {
126+ const Component = Route . component as React . ComponentType
127+ render ( < Component /> )
128+
129+ await waitFor ( ( ) => {
130+ expect ( screen . getByText ( 'settings:hardware.os' ) ) . toBeInTheDocument ( )
131+ expect ( screen . getByText ( 'windows' ) ) . toBeInTheDocument ( )
132+ } )
133+ } )
134+
135+ it ( 'displays CPU information' , async ( ) => {
136+ const Component = Route . component as React . ComponentType
137+ render ( < Component /> )
138+
139+ await waitFor ( ( ) => {
140+ expect ( screen . getByText ( 'settings:hardware.cpu' ) ) . toBeInTheDocument ( )
141+ expect ( screen . getByText ( 'Intel i7' ) ) . toBeInTheDocument ( )
142+ } )
143+ } )
144+
145+ it ( 'displays memory information' , async ( ) => {
146+ const Component = Route . component as React . ComponentType
147+ render ( < Component /> )
148+
149+ await waitFor ( ( ) => {
150+ expect ( screen . getByText ( 'settings:hardware.memory' ) ) . toBeInTheDocument ( )
151+ } )
152+ } )
153+
154+ it ( 'displays GPU devices on non-macOS' , async ( ) => {
155+ global . IS_MACOS = false
156+ const Component = Route . component as React . ComponentType
157+ render ( < Component /> )
158+
159+ await waitFor ( ( ) => {
160+ expect ( screen . getByText ( 'GPUs' ) ) . toBeInTheDocument ( )
161+ expect ( screen . getByText ( 'RTX 3080' ) ) . toBeInTheDocument ( )
162+ } )
163+ } )
164+
165+ it ( 'hides GPU devices on macOS' , async ( ) => {
166+ global . IS_MACOS = true
167+ const Component = Route . component as React . ComponentType
168+ render ( < Component /> )
169+
170+ await waitFor ( ( ) => {
171+ expect ( screen . queryByText ( 'GPUs' ) ) . not . toBeInTheDocument ( )
172+ } )
173+ } )
174+ } )
0 commit comments