@@ -421,4 +421,76 @@ describe('coreRpcClient', () => {
421421 expect ( tokenCalls ) . toBe ( 1 ) ;
422422 expect ( fetch ) . not . toHaveBeenCalled ( ) ;
423423 } ) ;
424+
425+ describe ( 'testCoreRpcConnection' , ( ) => {
426+ test ( 'POSTs an openhuman.ping JSON-RPC envelope to the supplied URL' , async ( ) => {
427+ vi . resetModules ( ) ;
428+ vi . mocked ( isTauri ) . mockReturnValue ( false ) ;
429+ const { testCoreRpcConnection } = await import ( '../coreRpcClient' ) ;
430+ const fetchMock = vi . mocked ( fetch ) ;
431+ fetchMock . mockResolvedValueOnce ( { ok : true , status : 200 } as Response ) ;
432+
433+ await testCoreRpcConnection ( 'http://example.test:7788/rpc' ) ;
434+
435+ expect ( fetchMock ) . toHaveBeenCalledTimes ( 1 ) ;
436+ const [ url , init ] = fetchMock . mock . calls [ 0 ] ;
437+ expect ( url ) . toBe ( 'http://example.test:7788/rpc' ) ;
438+ const requestInit = init as RequestInit ;
439+ expect ( requestInit . method ) . toBe ( 'POST' ) ;
440+ expect ( JSON . parse ( requestInit . body as string ) ) . toMatchObject ( {
441+ jsonrpc : '2.0' ,
442+ id : 1 ,
443+ method : 'openhuman.ping' ,
444+ params : { } ,
445+ } ) ;
446+ } ) ;
447+
448+ test ( 'omits Authorization header when no bearer token is available (non-Tauri)' , async ( ) => {
449+ vi . resetModules ( ) ;
450+ vi . mocked ( isTauri ) . mockReturnValue ( false ) ;
451+ const { testCoreRpcConnection } = await import ( '../coreRpcClient' ) ;
452+ const fetchMock = vi . mocked ( fetch ) ;
453+ fetchMock . mockResolvedValueOnce ( { ok : true , status : 200 } as Response ) ;
454+
455+ await testCoreRpcConnection ( 'http://example.test:7788/rpc' ) ;
456+
457+ const requestInit = fetchMock . mock . calls [ 0 ] [ 1 ] as RequestInit ;
458+ const headers = requestInit . headers as Record < string , string > ;
459+ expect ( headers ) . toMatchObject ( { 'Content-Type' : 'application/json' } ) ;
460+ expect ( headers ) . not . toHaveProperty ( 'Authorization' ) ;
461+ } ) ;
462+
463+ test ( 'attaches Authorization: Bearer when the Tauri bearer token resolves' , async ( ) => {
464+ vi . resetModules ( ) ;
465+ vi . mocked ( isTauri ) . mockReturnValue ( true ) ;
466+ vi . mocked ( invoke ) . mockImplementation ( async ( cmd : string ) => {
467+ if ( cmd === 'core_rpc_token' ) return 'deadbeef' ;
468+ throw new Error ( `unexpected command: ${ cmd } ` ) ;
469+ } ) ;
470+ const { testCoreRpcConnection } = await import ( '../coreRpcClient' ) ;
471+ const fetchMock = vi . mocked ( fetch ) ;
472+ fetchMock . mockResolvedValueOnce ( { ok : true , status : 200 } as Response ) ;
473+
474+ await testCoreRpcConnection ( 'http://example.test:7788/rpc' ) ;
475+
476+ const requestInit = fetchMock . mock . calls [ 0 ] [ 1 ] as RequestInit ;
477+ const headers = requestInit . headers as Record < string , string > ;
478+ expect ( headers . Authorization ) . toBe ( 'Bearer deadbeef' ) ;
479+ expect ( headers [ 'Content-Type' ] ) . toBe ( 'application/json' ) ;
480+ } ) ;
481+
482+ test ( 'returns the raw fetch Response so callers can inspect status/ok' , async ( ) => {
483+ vi . resetModules ( ) ;
484+ vi . mocked ( isTauri ) . mockReturnValue ( false ) ;
485+ const { testCoreRpcConnection } = await import ( '../coreRpcClient' ) ;
486+ const fetchMock = vi . mocked ( fetch ) ;
487+ const probe = { ok : false , status : 405 , statusText : 'Method Not Allowed' } as Response ;
488+ fetchMock . mockResolvedValueOnce ( probe ) ;
489+
490+ const response = await testCoreRpcConnection ( 'http://example.test:7788/rpc' ) ;
491+
492+ expect ( response ) . toBe ( probe ) ;
493+ expect ( response . status ) . toBe ( 405 ) ;
494+ } ) ;
495+ } ) ;
424496} ) ;
0 commit comments