fix: reject stale company profile and filter updates
This commit is contained in:
@@ -199,3 +199,21 @@ test('outbox review endpoint requires administrator and rejects unsupported or i
|
||||
assert.equal((await request('/api/admin/notify/outbox','POST',{id:'x',action:'skip',note:'short'},admin)).status,400);
|
||||
assert.equal((await request('/api/admin/notify/outbox','POST',{id:'missing',action:'skip',note:'Sağlayıcı kaydı kontrol edildi ve kapatılıyor.'},admin)).status,409);
|
||||
});
|
||||
|
||||
test('profile and saved-filter writes require the loaded revision and reject concurrent overwrites',async()=>{
|
||||
for(const anahtar of ['firma_profil','saved_filters']){
|
||||
const deger=anahtar==='firma_profil'?{company:'QA başlangıç'}:[{id:'qa',name:'Başlangıç'}];
|
||||
assert.equal((await request('/api/me/data','PUT',{anahtar,deger})).status,428);
|
||||
const initial=await request('/api/me/data');const revision=initial.data.revisions[anahtar] ?? null;
|
||||
const first=await request('/api/me/data','PUT',{anahtar,deger,revision});assert.equal(first.status,200);assert.match(first.data.revision,/^[a-f0-9]{64}$/);
|
||||
const attempts=await Promise.all(Array.from({length:8},(_,i)=>request('/api/me/data','PUT',{anahtar,deger:anahtar==='firma_profil'?{company:'QA '+i}:[{id:'qa'+i}],revision:first.data.revision})));
|
||||
assert.equal(attempts.filter(x=>x.status===200).length,1);
|
||||
assert.equal(attempts.filter(x=>x.status===409&&x.data.kod==='VERSION_CONFLICT').length,7);
|
||||
const after=await request('/api/me/data');assert.equal(after.data.revisions[anahtar],attempts.find(x=>x.status===200).data.revision);
|
||||
const stale=await request('/api/me/data','PUT',{anahtar,deger,revision:first.data.revision});assert.equal(stale.status,409);
|
||||
assert.deepEqual((await request('/api/me/data')).data.veri[anahtar],after.data.veri[anahtar]);
|
||||
// A revision read under another owner cannot grant write access to this record.
|
||||
const foreign=await request('/api/me/data','PUT',{anahtar,deger,revision:after.data.revisions[anahtar]},other);assert.equal(foreign.status,409);
|
||||
assert.equal((await request('/api/me/data','PUT',{anahtar,deger,revision:null},other)).status,200);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -43,7 +43,8 @@ test('database write failure propagates instead of pretending success', () => {
|
||||
const db = store.openDb();
|
||||
db.exec(`CREATE TRIGGER reject_write BEFORE INSERT ON kullanici_verisi BEGIN SELECT RAISE(FAIL,'test write failure'); END;`);
|
||||
db.close();
|
||||
assert.throws(() => store.setData('a@example.test','takip',[]), /test write failure/);
|
||||
try { assert.throws(() => store.setData('a@example.test','takip',[]), /test write failure/); }
|
||||
finally { const cleanup=store.openDb();cleanup.exec('DROP TRIGGER reject_write');cleanup.close(); }
|
||||
});
|
||||
test('per-tender versions prevent stale updates; five tasks persist', () => {
|
||||
for (const id of ['1573235','1582991','1523851','1499061','1534665']) {
|
||||
@@ -97,3 +98,16 @@ test('committed deletion remains inaccessible and pending physical cleanup survi
|
||||
const reopened=store.openDb();assert.equal(reopened.prepare('SELECT COUNT(*) n FROM document_file_cleanup').get().n,0);reopened.close();
|
||||
assert.equal(existsSync(file),false);
|
||||
});
|
||||
|
||||
test('data revision snapshots preserve legacy records and reject stale changes atomically',()=>{
|
||||
const owner='revision@example.test',key='firma_profil';
|
||||
store.setData(owner,key,{company:'Legacy'});
|
||||
const first=store.getDataSnapshot(owner);
|
||||
assert.deepEqual(first.veri[key],{company:'Legacy'});assert.match(first.revisions[key],/^[a-f0-9]{64}$/);
|
||||
const next=store.setData(owner,key,{company:'Updated'},first.revisions[key]);assert.notEqual(next,first.revisions[key]);
|
||||
assert.throws(()=>store.setData(owner,key,{company:'Stale'},first.revisions[key]),e=>e.kod==='VERSION_CONFLICT');
|
||||
assert.equal(store.getAllData(owner)[key].company,'Updated');
|
||||
const reopened=store.getDataSnapshot(owner);assert.equal(reopened.revisions[key],next);
|
||||
assert.equal(store.setData(owner,key,{company:'Updated'},next),next);
|
||||
assert.throws(()=>store.setData(owner,key,{company:'New'},null),e=>e.kod==='VERSION_CONFLICT');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user