import test from 'node:test'; import assert from 'node:assert/strict'; import {getGoogleConfig,loginWithGoogle,restoreSession,setSession,getToken,getStoredUser} from '../src/services/auth.js'; const memory=new Map();globalThis.localStorage={getItem:key=>memory.get(key)||null,setItem:(key,value)=>memory.set(key,value),removeItem:key=>memory.delete(key)}; test('Google config distinguishes unavailable endpoint from explicitly unconfigured service',async()=>{ const original=globalThis.fetch; try{ globalThis.fetch=async()=>({ok:false,json:async()=>({error:'Service unavailable'})});await assert.rejects(getGoogleConfig(),/Service unavailable/); globalThis.fetch=async()=>({ok:true,json:async()=>({clientId:null})});assert.deepEqual(await getGoogleConfig(),{clientId:null}); globalThis.fetch=async()=>({ok:true,json:async()=>({})});await assert.rejects(getGoogleConfig(),/doğrulanamadı/); }finally{globalThis.fetch=original;} }); test('invalid or cancelled Google sign-in cannot create a browser session',async()=>{ const original=globalThis.fetch;memory.clear(); try{ globalThis.fetch=async()=>({ok:true,json:async()=>({success:true,token:'',user:{email:'qa@example.test'}})}); await assert.rejects(loginWithGoogle('synthetic'),/doğrulanamadı/);assert.equal(memory.size,0); const controller=new AbortController(); globalThis.fetch=async()=>({ok:true,json:async()=>{controller.abort();return {success:true,token:'synthetic',user:{email:'qa@example.test'}};}}); await assert.rejects(loginWithGoogle('synthetic',{signal:controller.signal}));assert.equal(memory.size,0); }finally{globalThis.fetch=original;} }); test('restore preserves credentials on transient and malformed responses but expires rejected credentials',async()=>{ const original=globalThis.fetch; try{ for(const response of [ {ok:false,status:503,json:async()=>({error:'Unavailable'})}, {ok:false,status:502,json:async()=>{throw new Error('HTML response');}}, {ok:true,status:200,json:async()=>({success:true,user:{}})}, ]){ setSession('old-token',{email:'old@example.test'});globalThis.fetch=async()=>response; assert.equal((await restoreSession()).email,'old@example.test');assert.equal(getToken(),'old-token'); } for(const status of [401,403]){ setSession('old-token',{email:'old@example.test'}); globalThis.fetch=async()=>({ok:false,status,json:async()=>{throw new Error('Invalid JSON');}}); assert.equal(await restoreSession(),null);assert.equal(getToken(),null); } }finally{globalThis.fetch=original;memory.clear();} }); test('late restoration cannot replace or clear a newer login',async()=>{ const original=globalThis.fetch; try{ for(const ok of [true,false]){ setSession('old-token',{email:'old@example.test'}); globalThis.fetch=async()=>({ok,status:ok?200:401,json:async()=>{ setSession('new-token',{email:'new@example.test'}); return {success:ok,user:{email:'old@example.test'}}; }}); assert.equal((await restoreSession()).email,'new@example.test'); assert.equal(getToken(),'new-token');assert.equal(getStoredUser().email,'new@example.test'); } }finally{globalThis.fetch=original;memory.clear();} }); test('partial browser storage failure does not leave a usable half-session',async()=>{ const original=globalThis.fetch,storage=globalThis.localStorage;memory.clear(); try{ globalThis.localStorage={...storage,setItem:(key,value)=>{if(key==='ihaleist_user')throw new Error('Quota');storage.setItem(key,value);}}; globalThis.fetch=async()=>({ok:true,json:async()=>({success:true,token:'synthetic',user:{email:'qa@example.test'}})}); await assert.rejects(loginWithGoogle('synthetic'),/saklayamadı/);assert.equal(getToken(),null); }finally{globalThis.fetch=original;globalThis.localStorage=storage;memory.clear();} }); test('restoration timeout releases a stalled body without erasing the session',async t=>{ const original=globalThis.fetch; t.mock.timers.enable({apis:['setTimeout']}); try{ setSession('old-token',{email:'old@example.test'}); let bodyStarted; const started=new Promise(resolve=>{bodyStarted=resolve;}); globalThis.fetch=async()=>({ok:true,json:()=>{bodyStarted();return new Promise(()=>{});}}); const restoring=restoreSession();await started;t.mock.timers.tick(30000); assert.equal((await restoring).email,'old@example.test');assert.equal(getToken(),'old-token'); }finally{globalThis.fetch=original;memory.clear();t.mock.timers.reset();} });