@@ -102,6 +102,8 @@ describe('CloudVmManager', () => {
102102 provider : 'gcp' ,
103103 apiToken : 'secret-token' ,
104104 serverId : 'pane-user123' ,
105+ projectId : 'pane-project' ,
106+ zone : 'us-central1-a' ,
105107 vncPassword : 'vnc-password' ,
106108 tunnelPort : 8080 ,
107109 daemonStatus : 'ready' ,
@@ -159,4 +161,59 @@ describe('CloudVmManager', () => {
159161 error : null ,
160162 } ) ;
161163 } ) ;
164+
165+ it ( 'surfaces daemon-backed hosted workspace state when lifecycle fields are incomplete' , async ( ) => {
166+ const manager = new CloudVmManager ( new ConfigManagerStub ( normalizeCloudVmConfig ( {
167+ provider : 'gcp' ,
168+ apiToken : 'stale-token' ,
169+ serverId : 'pane-user123' ,
170+ daemonStatus : 'ready' ,
171+ daemonBaseUrl : 'https://pane.example.com/daemon/' ,
172+ linkedRemoteProfileId : 'remote-profile-1' ,
173+ } ) ) as never ) ;
174+
175+ const fetchVmStatusSpy = vi . spyOn ( manager as never , 'fetchVmStatus' ) ;
176+
177+ const state = await manager . getState ( ) ;
178+
179+ expect ( fetchVmStatusSpy ) . not . toHaveBeenCalled ( ) ;
180+ expect ( state ) . toMatchObject ( {
181+ status : 'running' ,
182+ provider : 'gcp' ,
183+ serverId : 'pane-user123' ,
184+ daemonStatus : 'ready' ,
185+ daemonBaseUrl : 'https://pane.example.com/daemon/' ,
186+ linkedRemoteProfileId : 'remote-profile-1' ,
187+ tunnelStatus : 'off' ,
188+ error : null ,
189+ } ) ;
190+ } ) ;
191+
192+ it ( 'falls back to daemon-backed hosted workspace state when lifecycle status fetch fails' , async ( ) => {
193+ const manager = new CloudVmManager ( new ConfigManagerStub ( normalizeCloudVmConfig ( {
194+ provider : 'gcp' ,
195+ apiToken : 'stale-token' ,
196+ serverId : 'pane-user123' ,
197+ projectId : 'pane-project' ,
198+ zone : 'us-central1-a' ,
199+ daemonStatus : 'ready' ,
200+ daemonBaseUrl : 'https://pane.example.com/daemon/' ,
201+ linkedRemoteProfileId : 'remote-profile-1' ,
202+ } ) ) as never ) ;
203+
204+ vi . spyOn ( manager as never , 'fetchVmStatus' ) . mockRejectedValue ( new Error ( '401 Unauthorized' ) ) ;
205+
206+ const state = await manager . getState ( ) ;
207+
208+ expect ( state ) . toMatchObject ( {
209+ status : 'running' ,
210+ provider : 'gcp' ,
211+ serverId : 'pane-user123' ,
212+ daemonStatus : 'ready' ,
213+ daemonBaseUrl : 'https://pane.example.com/daemon/' ,
214+ linkedRemoteProfileId : 'remote-profile-1' ,
215+ tunnelStatus : 'off' ,
216+ error : null ,
217+ } ) ;
218+ } ) ;
162219} ) ;
0 commit comments