60 lines
4.1 KiB
JavaScript
60 lines
4.1 KiB
JavaScript
import test from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import {sourceRows,bidSourceSnapshot,restoreBidPrices,bidSourceOptions} from '../src/services/bidSource.js';
|
||
const tender = {ikn:'2026/test',aciklama:'120 gün',items:[{id:1,ad:'Kit',miktar:10,birim:'adet'},{id:2,ad:'Cihaz',miktar:2,birim:'adet'}]};
|
||
test('conflicting source inventories require explicit choice and invalidate that choice on change',()=>{
|
||
const results={itemsAndSpecs:[{name:'Kit',quantity:'20 adet'}],documentVersion:'v1'};
|
||
const options=bidSourceOptions(tender,results);
|
||
assert.equal(options.needsSelection,true);
|
||
const selection={source:'analysis',signature:options.signature};
|
||
assert.equal(bidSourceOptions(tender,results,selection).needsSelection,false);
|
||
assert.deepEqual(sourceRows(tender,results,'analysis').map(r=>r.quantity),['20 adet']);
|
||
assert.equal(bidSourceOptions(tender,{...results,documentVersion:'v2'},selection).needsSelection,true);
|
||
assert.equal(bidSourceOptions({...tender,items:[tender.items[0]]},results,selection).needsSelection,true);
|
||
assert.notEqual(bidSourceSnapshot(tender,results),bidSourceSnapshot(tender,{...results,itemsAndSpecs:[{name:'Kit',quantity:'30 adet'}]}));
|
||
const matching={itemsAndSpecs:[{name:'Cihaz',quantity:'2 adet'},{name:'Kit',quantity:'10 adet'}]};
|
||
assert.equal(bidSourceOptions(tender,matching).conflict,false);
|
||
assert.equal(bidSourceOptions({},results).conflict,false);
|
||
});
|
||
test('reordered source rows retain their own prices without invalidating identical content',()=>{
|
||
const original=sourceRows(tender);
|
||
const draft={priceSchema:1,pricesBySource:{[original[0].priceKey]:'15',[original[1].priceKey]:'900'}};
|
||
const reordered={...tender,items:[...tender.items].reverse()};
|
||
const rows=sourceRows(reordered),prices=restoreBidPrices(draft);
|
||
assert.equal(prices[rows[0].priceKey],'900');
|
||
assert.equal(prices[rows[1].priceKey],'15');
|
||
assert.equal(bidSourceSnapshot(tender),bidSourceSnapshot(reordered));
|
||
});
|
||
test('changed quantity, requirements and announcement invalidate reviewed source',()=>{
|
||
const original=sourceRows(tender),prices={[original[0].priceKey]:'15'};
|
||
const changed={...tender,items:[{...tender.items[0],miktar:20},tender.items[1]]};
|
||
assert.equal(prices[sourceRows(changed)[0].priceKey],undefined);
|
||
const snapshot=bidSourceSnapshot(tender);
|
||
for(const updated of [changed,{...tender,aciklama:'150 gün'},{...tender,saat:'10:30'}])
|
||
assert.notEqual(snapshot,bidSourceSnapshot(updated));
|
||
assert.notEqual(snapshot,bidSourceSnapshot(tender,{documentChecklist:['Numune']}));
|
||
});
|
||
test('legacy positional prices are not silently assigned to potentially changed source rows',()=>{
|
||
assert.deepEqual(restoreBidPrices({fiyatlar:{0:'15',1:'900'}}),{});
|
||
});
|
||
|
||
test('review revision changes invalidate the preparation source even with identical extracted rows',()=>{
|
||
const tender={ikn:'2026/1',items:[]};
|
||
const first={sourceReview:{humanReview:{documentId:'doc',revision:1,textHash:'same'}}};
|
||
const second={sourceReview:{humanReview:{documentId:'doc',revision:2,textHash:'same'}}};
|
||
assert.notEqual(bidSourceSnapshot(tender,first),bidSourceSnapshot(tender,second));
|
||
});
|
||
|
||
test('persisted preparation retains critical conditions and changed findings invalidate review', async()=>{
|
||
const {preparationAnalysisSource,preparationConditionSections}=await import('../src/services/preparationAnalysis.js');
|
||
const analysis={itemsAndSpecs:[],qualificationCriteria:['Servis yetkisi'],criticalRequirements:['Numune zorunlu'],risksAndPenalties:[{text:'Gecikme cezası',clause:'Madde 12'}],sourceEvidence:[{quote:'numune'}],documentVersion:'same-document'};
|
||
const saved=JSON.parse(JSON.stringify(preparationAnalysisSource(analysis)));
|
||
assert.deepEqual(saved.qualificationCriteria,analysis.qualificationCriteria);
|
||
assert.deepEqual(saved.risksAndPenalties,analysis.risksAndPenalties);
|
||
assert.deepEqual(saved.sourceEvidence,analysis.sourceEvidence);
|
||
assert.equal(bidSourceSnapshot(tender,analysis),bidSourceSnapshot(tender,saved));
|
||
for(const [field] of preparationConditionSections) {
|
||
assert.notEqual(bidSourceSnapshot(tender,saved),bidSourceSnapshot(tender,{...saved,[field]:['Yeni koşul']}),field);
|
||
}
|
||
});
|