fix: persist tender preparation and correct calendar export

This commit is contained in:
2026-09-06 08:30:32 +03:00
parent 909ebae7c2
commit c91631d99f
19 changed files with 569 additions and 182 deletions
+57
View File
@@ -0,0 +1,57 @@
import { test, after } from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { DatabaseSync } from 'node:sqlite';
const dir = mkdtempSync(join(tmpdir(), 'ihaleist-store-'));
process.env.IHALEIST_USER_DATA_DIR = dir;
const legacy = new DatabaseSync(join(dir, 'users.sqlite'));
legacy.exec(`CREATE TABLE belgeler (id TEXT PRIMARY KEY,email TEXT NOT NULL,ad TEXT NOT NULL,kategori TEXT,boyut INTEGER NOT NULL,mime TEXT,dosya TEXT NOT NULL,olusturma TEXT);
INSERT INTO belgeler VALUES ('old','a@example.test','Eski belge','Yasal',5,'text/plain','old.txt','2026-09-01');`);
legacy.close();
const store = await import('../server/user-store.mjs');
after(() => rmSync(dir, { recursive: true, force: true }));
test('old volume migrates before indexing, preserves files and migration is repeatable', () => {
for (let i = 0; i < 2; i++) {
const db = store.openDb();
assert.equal(db.prepare('SELECT COUNT(*) n FROM schema_migrations').get().n, 1);
assert.ok(db.prepare('PRAGMA table_info(belgeler)').all().some(c => c.name === 'ikn'));
db.close();
}
assert.equal(store.listDocuments('a@example.test')[0].ad, 'Eski belge');
assert.deepEqual(store.listDocuments('b@example.test'), []);
});
test('five preparation records persist across DB close/reopen and stay account scoped', () => {
const records = Object.fromEntries(['1573235','1582991','1523851','1499061','1534665'].map(id => ['2026/'+id, { takipte: true, gorev: { kontrolListesi: [{ad:'ÜTS',tamam:false}] }, kanbanStatus:'teklif_hazirlaniyor' }]));
assert.equal(store.setData('a@example.test', 'gorevler', records), true);
assert.deepEqual(store.getAllData('a@example.test').gorevler, records);
assert.equal(store.getData('b@example.test', 'gorevler'), null);
});
test('document and API key ownership enforced', () => {
const id = store.addDocument('a@example.test', {ad:'Şartname',boyut:10,dosya:'spec.pdf',ikn:'2026/1582991'});
assert.equal(store.listDocuments('a@example.test', {ikn:'2026/1582991'}).length, 1);
assert.equal(store.getDocument('b@example.test', id), null);
const key = store.createApiKey('a@example.test', 'Test');
assert.equal(store.verifyApiKey(key.anahtar).email, 'a@example.test');
assert.equal(store.revokeApiKey('b@example.test', key.id), false);
store.revokeApiKey('a@example.test', key.id);
assert.equal(store.verifyApiKey(key.anahtar), null);
});
test('database write failure propagates instead of pretending success', () => {
const db = store.openDb();
db.exec(`CREATE TRIGGER reject_write BEFORE INSERT ON kullanici_verisi BEGIN SELECT RAISE(FAIL,'test write failure'); END;`);
db.close();
assert.throws(() => store.setData('a@example.test','takip',[]), /test write failure/);
});
test('per-tender versions prevent stale updates; five tasks persist', () => {
for (const id of ['1573235','1582991','1523851','1499061','1534665']) {
const key = '2026/'+id;
const saved = store.saveTenderState('c@example.test', key, {takipte:true,gorev:{kontrolListesi:[]}}, {id:key,ikn:key}, 0);
assert.equal(saved.version,1);
assert.throws(() => store.saveTenderState('c@example.test', key, {takipte:false}, {}, 0), e => e.kod === 'VERSION_CONFLICT');
assert.equal(store.saveTenderState('c@example.test', key, {notes:[{text:'test'}]}, {}, 1).version,2);
}
assert.equal(Object.keys(store.getTenderStates('c@example.test')).length,5);
assert.deepEqual(store.getTenderStates('d@example.test'),{});
});