fix: bound document downloads and cancel stale sessions
This commit is contained in:
@@ -22,3 +22,48 @@ test('account switch during file reading prevents upload and download delivery',
|
||||
if(storage) Object.defineProperty(globalThis,'localStorage',storage);else delete globalThis.localStorage;
|
||||
}
|
||||
});
|
||||
|
||||
test('download timeouts bound both successful and failed response bodies',async t=>{
|
||||
const storage=Object.getOwnPropertyDescriptor(globalThis,'localStorage'),originalFetch=globalThis.fetch;
|
||||
Object.defineProperty(globalThis,'localStorage',{configurable:true,value:{getItem:()=> 'qa-token'}});
|
||||
t.mock.timers.enable({apis:['setTimeout']});
|
||||
try {
|
||||
for(const ok of [true,false]){
|
||||
let started;const reading=new Promise(resolve=>{started=resolve;});let fetchSignal;
|
||||
const body=()=>{started();return new Promise(()=>{});};
|
||||
globalThis.fetch=async(_url,options)=>{fetchSignal=options.signal;return {ok,status:503,blob:body,json:body};};
|
||||
const downloading=downloadDocument('qa','qa.txt',{timeoutMs:50});await reading;t.mock.timers.tick(50);
|
||||
await assert.rejects(downloading,/zamanında indirilemedi/);assert.equal(fetchSignal.aborted,true);
|
||||
}
|
||||
}finally{globalThis.fetch=originalFetch;t.mock.timers.reset();if(storage)Object.defineProperty(globalThis,'localStorage',storage);else delete globalThis.localStorage;}
|
||||
});
|
||||
test('cancelled or unauthenticated downloads cannot start or deliver a file',async()=>{
|
||||
const storage=Object.getOwnPropertyDescriptor(globalThis,'localStorage'),originalFetch=globalThis.fetch;
|
||||
let token=null,calls=0;
|
||||
Object.defineProperty(globalThis,'localStorage',{configurable:true,value:{getItem:()=>token}});
|
||||
try{
|
||||
globalThis.fetch=async()=>{calls++;return {ok:true,blob:async()=>new Blob(['QA'])};};
|
||||
await assert.rejects(downloadDocument('qa','qa.txt'),/giriş yapın/);assert.equal(calls,0);
|
||||
token='qa-token';const controller=new AbortController();controller.abort();
|
||||
await assert.rejects(downloadDocument('qa','qa.txt',{signal:controller.signal}),{name:'AbortError'});assert.equal(calls,0);
|
||||
const later=new AbortController();
|
||||
globalThis.fetch=async()=>({ok:true,blob:async()=>{later.abort();return new Blob(['QA']);}});
|
||||
await assert.rejects(downloadDocument('qa','qa.txt',{signal:later.signal}),{name:'AbortError'});
|
||||
}finally{globalThis.fetch=originalFetch;if(storage)Object.defineProperty(globalThis,'localStorage',storage);else delete globalThis.localStorage;}
|
||||
});
|
||||
test('download delivers original bytes and releases URL and link if clicking fails',async t=>{
|
||||
const storage=Object.getOwnPropertyDescriptor(globalThis,'localStorage'),originalFetch=globalThis.fetch,originalDocument=globalThis.document;
|
||||
const create=URL.createObjectURL,revoke=URL.revokeObjectURL;let removed=0,revoked=0,clicks=0,receivedBlob,link,fail=false;
|
||||
Object.defineProperty(globalThis,'localStorage',{configurable:true,value:{getItem:()=> 'qa-token'}});
|
||||
t.mock.timers.enable({apis:['setTimeout']});
|
||||
try{
|
||||
globalThis.fetch=async()=>({ok:true,blob:async()=>new Blob(['Özgün test belgesi'])});
|
||||
URL.createObjectURL=blob=>{receivedBlob=blob;return 'blob:qa';};URL.revokeObjectURL=url=>{assert.equal(url,'blob:qa');revoked++;};
|
||||
globalThis.document={body:{appendChild:()=>{}},createElement:()=>link={click:()=>{clicks++;if(fail)throw new Error('click failed');},remove:()=>{removed++;}}};
|
||||
await downloadDocument('qa','Türkçe belge.txt');
|
||||
assert.equal(link.download,'Türkçe belge.txt');assert.equal(await receivedBlob.text(),'Özgün test belgesi');
|
||||
t.mock.timers.tick(5000);assert.equal(clicks,1);assert.equal(removed,1);assert.equal(revoked,1);
|
||||
fail=true;await assert.rejects(downloadDocument('qa','qa.txt'),/click failed/);
|
||||
t.mock.timers.tick(5000);assert.equal(removed,2);assert.equal(revoked,2);
|
||||
}finally{globalThis.fetch=originalFetch;globalThis.document=originalDocument;URL.createObjectURL=create;URL.revokeObjectURL=revoke;t.mock.timers.reset();if(storage)Object.defineProperty(globalThis,'localStorage',storage);else delete globalThis.localStorage;}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user