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'),[]); });