import test from 'node:test'; import assert from 'node:assert/strict'; import {DatabaseSync} from 'node:sqlite'; import {execFileSync} from 'node:child_process'; import {mkdtempSync,rmSync} from 'node:fs'; import {tmpdir} from 'node:os'; import {join} from 'node:path'; const moduleUrl=new URL('../server/notify-store.mjs',import.meta.url).href; const schema=`CREATE TABLE abonelikler(id INTEGER PRIMARY KEY AUTOINCREMENT,email TEXT NOT NULL,ad TEXT,sehir TEXT,sektor TEXT,alim_turu TEXT,anahtar TEXT,kurumlar TEXT,konular TEXT,aktif INTEGER NOT NULL DEFAULT 1,sonGonderim TEXT,sonGorulenler TEXT,olusturma TEXT,UNIQUE(email,sehir,sektor,alim_turu,anahtar));CREATE INDEX idx_abone_email ON abonelikler(email);`; for(const malformed of [false,true])test(`subscription migration ${malformed?'rolls back invalid legacy data':'preserves ids delivery history duplicates and sequence'}`,()=>{ const dir=mkdtempSync(join(tmpdir(),'ihaleist-subscription-migrate-')),file=join(dir,'notify.sqlite'); try { let db=new DatabaseSync(file);db.exec(schema); const insert=db.prepare('INSERT INTO abonelikler(id,email,ad,sehir,sektor,alim_turu,anahtar,kurumlar,konular,sonGonderim,sonGorulenler,olusturma) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); insert.run(7,'owner','Name','Ankara','','','','[]',malformed?'invalid':'["Laboratuvar"]','2026-09-01','["seen-1"]','2026-08-01'); insert.run(8,'owner','Second','ANKARA','','','','[]','["laboratuvar"]','2026-09-02','["seen-2"]','2026-08-02'); db.exec("UPDATE sqlite_sequence SET seq=99 WHERE name='abonelikler'");db.close(); const output=JSON.parse(execFileSync(process.execPath,['--input-type=module','-e',` const store=await import(${JSON.stringify(moduleUrl)}); try {const old=store.list('owner');const rows=store.subscribe('owner',{sehir:'Ankara',konular:['Cihaz']});console.log(JSON.stringify({old,rows}));} catch(error){console.log(JSON.stringify({error:error.message}));} `],{env:{...process.env,IHALEIST_USER_DATA_DIR:dir},encoding:'utf8',timeout:10000,stdio:['ignore','pipe','pipe']})); db=new DatabaseSync(file); try { assert.equal(db.prepare('PRAGMA integrity_check').get().integrity_check,'ok'); const columns=db.prepare('PRAGMA table_info(abonelikler)').all().map(row=>row.name); if(malformed){assert.ok(output.error);assert.equal(columns.includes('criteria_key'),false);assert.equal(db.prepare('SELECT count(*) n FROM abonelikler').get().n,2);} else { assert.equal(output.error,undefined);assert.equal(output.old.length,2); assert.deepEqual(output.old.find(row=>row.id===7).sonGorulenler,['seen-1']);assert.equal(output.old.find(row=>row.id===8).sonGonderim,'2026-09-02'); assert.equal(output.rows.length,3);assert.equal(output.rows[0].id,100); assert.equal(db.prepare("SELECT count(*) n FROM sqlite_master WHERE name='idx_abone_email' AND tbl_name='abonelikler'").get().n,1); } }finally {db.close();} }finally {rmSync(dir,{recursive:true,force:true});} });