70 lines
4.9 KiB
JavaScript
70 lines
4.9 KiB
JavaScript
import {test} from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import {uploadDocument,downloadDocument} from '../src/services/account.js';
|
||
|
||
test('account switch during file reading prevents upload and download delivery',async()=>{
|
||
const storage=Object.getOwnPropertyDescriptor(globalThis,'localStorage');
|
||
const originalFetch=globalThis.fetch, originalReader=globalThis.FileReader;
|
||
let token='first', calls=0;
|
||
Object.defineProperty(globalThis,'localStorage',{configurable:true,value:{getItem:()=>token}});
|
||
try {
|
||
globalThis.FileReader=class {
|
||
readAsDataURL(){token='second';this.result='data:text/plain;base64,VGVzdA==';this.onload();}
|
||
};
|
||
globalThis.fetch=async()=>{calls++;return Response.json({success:true});};
|
||
await assert.rejects(uploadDocument({name:'test.txt',type:'text/plain'},'Test'),/Oturum değişti/);
|
||
assert.equal(calls,0);
|
||
token='first';
|
||
globalThis.fetch=async()=>({ok:true,blob:async()=>{token='second';return new Blob(['private document']);}});
|
||
await assert.rejects(downloadDocument('id','test.txt'),/Oturum değişti/);
|
||
} finally {
|
||
globalThis.fetch=originalFetch;globalThis.FileReader=originalReader;
|
||
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;}
|
||
});
|