import test from 'node:test'; import assert from 'node:assert/strict'; import {applyTenderStates,tenderSnapshot,tenderSourceChanges,resolveCurrentTender} from '../src/services/tenderState.js'; import {bidSourceSnapshot} from '../src/services/bidSource.js'; test('fresh deadline and cancellation changes remain visible without overwriting saved work',()=>{ const original={id:'old-id',ikn:'2026/1',tarih:'10.09.2026',saat:'10:00',durum:'Açık',documentVersion:'v1'}; const current={...original,id:'new-source-id',tarih:'12.09.2026',saat:'11:00',durum:'İptal',documentVersion:'v2'}; const data={takipte:true,notes:[{text:'Firma notu'}],bidDraft:{pricesBySource:{kit:'100'}}}; const result=applyTenderStates([current],{'2026/1':{snapshot:tenderSnapshot(original),data}})[0]; assert.equal(result.id,'new-source-id');assert.equal(result.durum,'İptal'); assert.deepEqual(result.notes,data.notes);assert.deepEqual(result.bidDraft,data.bidDraft); assert.deepEqual(result.sourceChanges.map(x=>x.field),['tarih','saat','durum','documentVersion']); assert.notEqual(bidSourceSnapshot(original),bidSourceSnapshot({...original,durum:'İptal'})); }); test('unknown legacy fields do not invent a change and a new saved baseline clears comparisons',()=>{ assert.deepEqual(tenderSourceChanges({tarih:''},{tarih:'12.09.2026',durum:'Açık'}),[]); const current={ikn:'2026/2',tarih:'12.09.2026',saat:'11:00',durum:'Açık'}; const result=applyTenderStates([current],{'2026/2':{snapshot:tenderSnapshot(current),data:{takipte:true}}}); assert.deepEqual(result[0].sourceChanges,[]); }); test('winner publication changes the reviewed bid source without destroying saved prices',()=>{ const original={ikn:'2026/winner',tarih:'10.09.2026',saat:'10:00',durum:'Açık'}; const draft={pricesBySource:{kit:'100'},reviewedSource:bidSourceSnapshot(original)}; const awarded={...original,kazananFirma:'QA Kazanan'}; const result=applyTenderStates([awarded],{[original.ikn]:{snapshot:tenderSnapshot(original),data:{bidDraft:draft,takipte:true}}})[0]; assert.notEqual(bidSourceSnapshot(result),draft.reviewedSource); assert.deepEqual(result.bidDraft,draft); const restored=applyTenderStates([],{[original.ikn]:{snapshot:tenderSnapshot(awarded),data:{bidDraft:draft,takipte:true}}})[0]; assert.equal(restored.kazananFirma,'QA Kazanan'); assert.equal(bidSourceSnapshot(original),bidSourceSnapshot({...original,kazananFirma:''})); }); test('preparation resolves rotating source ids by IKN without merging a different procurement',()=>{ const selected={id:'old-response',ikn:'2026/42',baslik:'Eski başlık',bidDraft:{pricesBySource:{kit:'10'}}}; const updated={id:'new-response',ikn:'2026/42',baslik:'Güncel başlık',kazananFirma:'QA Kazanan'}; const result=resolveCurrentTender(selected,[{id:'old-response',ikn:'2026/99',baslik:'Başka ihale'},updated]); assert.equal(result.id,'new-response');assert.equal(result.kazananFirma,'QA Kazanan'); assert.equal(result.baslik,'Güncel başlık');assert.deepEqual(result.bidDraft,selected.bidDraft); assert.deepEqual(resolveCurrentTender(selected,[{id:'old-response',ikn:'2026/99'}]),selected); assert.deepEqual(resolveCurrentTender(selected,[]),selected); assert.equal(resolveCurrentTender({id:'local-id'},[{id:'local-id',ikn:'2026/42'}]).ikn,'2026/42'); }); test('output header changes invalidate source review, while rotating response ids do not',()=>{ const tender={id:'response-1',ikn:'2026/42',baslik:'Laboratuvar alımı',kurum:'QA Hastane',tarih:'10.09.2026',saat:'10:00'}; const original=bidSourceSnapshot(tender); for(const patch of [{baslik:'Düzeltilmiş alım'},{kurum:'Düzeltilmiş idare'},{ihaleTarihi:'11.09.2026'}]) assert.notEqual(bidSourceSnapshot({...tender,...patch}),original); assert.equal(bidSourceSnapshot({...tender,id:'response-2'}),original); });