Files
ihaleist/tests/offer-draft.test.mjs

58 lines
3.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {qualifyOfferDraft} from '../server/offer-draft.mjs';
const requested=['Kapak','Teknik','Ekler'];
test('missing sections are explicit editable placeholders, not a complete dossier',()=>{
const out=qualifyOfferDraft({bolumler:[{baslik:'Kapak',icerik:'Kapak metni'}]},requested);
assert.equal(out.draftReview.status,'partial');
assert.deepEqual(out.draftReview.missingSections,['Teknik','Ekler']);
assert.match(out.bolumler[1].icerik,/DOLDURUN/);assert.equal(out.bolumler[0].icerik,'Kapak metni');
});
test('long sections retain their last conditions and requested section order',()=>{
const text='Teknik şart '.repeat(1500)+'SON KOŞUL: Numune zorunludur.';
const out=qualifyOfferDraft({bolumler:[{baslik:'Ekler',icerik:'Ekler metni'},{baslik:'Teknik',icerik:text},{baslik:'Kapak',icerik:'Kapak'}]},requested);
assert.deepEqual(out.bolumler.map(row=>row.baslik),requested);
assert.equal(out.bolumler[1].icerik,text);assert.equal(out.draftReview.status,'draft');
});
test('unexpected content is preserved but never substitutes for a requested section',()=>{
const out=qualifyOfferDraft({bolumler:[{baslik:'Başka bölüm',icerik:'Ek içerik'}]},requested);
assert.equal(out.draftReview.status,'partial');assert.equal(out.draftReview.missingSections.length,3);
assert.equal(out.bolumler.at(-1).icerik,'Ek içerik');
});
test('malformed or repeated sections cannot silently overwrite user-visible content',()=>{
for(const bolumler of [[],[null],[{baslik:'Kapak',icerik:{text:'invalid'}}],[{baslik:'Kapak',icerik:'a'},{baslik:'Kapak',icerik:'b'}]])
assert.throws(()=>qualifyOfferDraft({bolumler},requested));
});
const {draftOfferInParts}=await import('../server/offer-draft-parts.mjs');
test('long draft input processes every character and retains late section text in deterministic order',async()=>{
const source='Kalem ve firma şartları. '.repeat(2100)+'SON KALEM 101: cihaz kurulum yükümlülüğü';
const seen=[];
const out=await draftOfferInParts(source,requested,async(part)=>{
seen.push(part);
return {bolumler:requested.map(baslik=>({baslik,icerik:part.text}))};
});
assert.equal(seen.sort((a,b)=>a.index-b.index).map(p=>p.text).join(''),source);
assert.ok(seen.every(p=>p.text.length<=16000));
assert.match(out.bolumler[1].icerik,/SON KALEM 101/);
assert.equal(out.draftReview.status,'partial');
assert.equal(out.draftReview.parts.at(-1).end,source.length);
});
test('failed draft parts remain explicit, not silently omitted or marked complete',async()=>{
const out=await draftOfferInParts('X'.repeat(40000),requested,async part=>{
if(part.index===1)throw new Error('provider unavailable');
return {bolumler:requested.map(baslik=>({baslik,icerik:'Useful draft'}))};
});
assert.deepEqual(out.draftReview.failedParts,[2]);
assert.equal(out.draftReview.parts[1].status,'failed');
assert.match(out.bolumler[0].icerik,/üretilemedi/);
assert.equal(out.draftReview.status,'partial');
});
test('draft cancellation stops subsequent batches',async()=>{
const controller=new AbortController();let calls=0;
await assert.rejects(draftOfferInParts('X'.repeat(80000),requested,async()=>{
calls++;controller.abort();return {bolumler:[{baslik:'Kapak',icerik:'draft'}]};
},{signal:controller.signal}),{name:'AbortError'});
assert.ok(calls<=2);
});