63 lines
3.6 KiB
JavaScript
63 lines
3.6 KiB
JavaScript
import { test } from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import { createTenderICS, tenderDeadline, deadlineInfo, calendarMonthDays, istanbulDateKey } from '../src/services/tenderCalendar.js';
|
||
const t = {ikn:'2026/1582991',baslik:'Mikroskop',kurum:'Giresun',tarih:'10.09.2026',saat:'',aciklama:'Tarih ve Saati : 10.09.2026 - 10:00'};
|
||
test('Giresun date is September 10 at 10:00 Turkey, not hard-coded August', () => {
|
||
assert.equal(tenderDeadline(t).toISOString(),'2026-09-10T07:00:00.000Z');
|
||
assert.match(createTenderICS(t), /DTSTART:20260910T070000Z/);
|
||
});
|
||
test('all five tender deadlines and year rollover', () => {
|
||
for (const [date,time,expected] of [
|
||
['09.09.2026','10:00','2026-09-09T07:00'],['11.09.2026','10:00','2026-09-11T07:00'],
|
||
['22.09.2026','10:30','2026-09-22T07:30'],['22.09.2026','11:00','2026-09-22T08:00'],
|
||
['01.01.2027','01:00','2026-12-31T22:00'],['29.02.2028','10:00','2028-02-29T07:00']])
|
||
assert.ok(tenderDeadline({...t,tarih:date,saat:time}).toISOString().startsWith(expected));
|
||
});
|
||
test('missing time, impossible date, invalid time are rejected', () => {
|
||
for (const patch of [{saat:'',aciklama:''},{tarih:'31.02.2026',saat:'10:00'},{saat:'25:00'}])
|
||
assert.throws(() => tenderDeadline({...t,...patch}));
|
||
});
|
||
test('ICS escapes text, folds UTF-8 lines, keeps stable UID', () => {
|
||
const ics = createTenderICS({...t,baslik:'Ş'.repeat(100)+'\nEND:VEVENT;,'});
|
||
assert.ok(ics.split('\r\n').every(l => Buffer.byteLength(l) <= 75));
|
||
assert.equal(ics.split('UID:')[1].split('\r\n')[0],'2026%2F1582991@ihaleist.com');
|
||
assert.ok(ics.includes('\\nEND:VEVENT\\;\\,'));
|
||
});
|
||
|
||
test('all countdowns use Istanbul calendar days and exact expiry', () => {
|
||
const now = new Date('2026-09-06T08:00:00Z');
|
||
assert.equal(deadlineInfo(t,now).days,4);
|
||
assert.equal(deadlineInfo(t,now).label,'4 gün');
|
||
assert.equal(deadlineInfo(t,new Date('2026-09-10T06:59:00Z')).expired,false);
|
||
assert.equal(deadlineInfo(t,new Date('2026-09-10T07:00:00Z')).expired,true);
|
||
assert.equal(istanbulDateKey(new Date('2026-12-31T22:00:00Z')),'2027-01-01');
|
||
});
|
||
test('missing time stays unknown today, impossible date is not counted', () => {
|
||
const now=new Date('2026-09-10T10:00:00Z');
|
||
const info=deadlineInfo({tarih:'10.09.2026'},now);
|
||
assert.equal(info.expired,null);assert.equal(info.deadline,null);
|
||
assert.match(info.label,/saat doğrulanmalı/);
|
||
assert.equal(deadlineInfo({tarih:'31.02.2026'},now).days,null);
|
||
assert.equal(deadlineInfo({tarih:'09.09.2026'},now).expired,true);
|
||
});
|
||
test('month view includes late-month tenders and leap days', () => {
|
||
assert.equal(calendarMonthDays('2026-09').length,30);
|
||
assert.ok(calendarMonthDays('2026-09').some(d=>d.date==='22.09.2026'));
|
||
assert.equal(calendarMonthDays('2028-02').length,29);
|
||
assert.equal(calendarMonthDays('2027-02').length,28);
|
||
assert.deepEqual(calendarMonthDays('2026-13'),[]);
|
||
});
|
||
|
||
test('deadline ICS is a transparent instant, preserves UID across date changes and states update limits',()=>{
|
||
const first=createTenderICS(t,new Date('2026-09-01T00:00:00Z'));
|
||
const changed=createTenderICS({...t,tarih:'12.09.2026',saat:'14:30'},new Date('2026-09-02T00:00:00Z'));
|
||
assert.equal(first.match(/^UID:.+$/m)[0],changed.match(/^UID:.+$/m)[0]);
|
||
assert.match(changed,/DTSTART:20260912T113000Z/);
|
||
assert.doesNotMatch(changed,/DTEND:|DURATION:/);
|
||
assert.match(changed,/TRANSP:TRANSPARENT/);
|
||
assert.match(changed.replace(/\r\n /g,''),/otomatik güncellenmez/);
|
||
const hostile=createTenderICS({...t,baslik:'A\rEND:VEVENT\rBEGIN:VEVENT\nB'});
|
||
assert.equal(hostile.split('\r\n').filter(line=>line==='BEGIN:VEVENT').length,1);
|
||
assert.equal(hostile.split('\r\n').filter(line=>line==='END:VEVENT').length,1);
|
||
});
|