import test from 'node:test'; import assert from 'node:assert/strict'; import { clearOfflineMutations, enqueueTenderMutation, listOfflineMutations, offlineMutationCount, replayOfflineMutations, } from '../src/services/offlineMutationQueue.js'; const storage = new Map(); globalThis.localStorage = { getItem: key => storage.has(key) ? storage.get(key) : null, setItem: (key, value) => storage.set(key, String(value)), removeItem: key => storage.delete(key), }; test('offline tender mutations are account scoped and merged by tender', async () => { clearOfflineMutations('qa@example.test'); enqueueTenderMutation('qa@example.test', { key: '2026/1', patch: { takipte: true }, snapshot: { ikn: '2026/1' }, version: 2 }); enqueueTenderMutation('qa@example.test', { key: '2026/1', patch: { kanbanStatus: 'teklif_hazirlaniyor' }, snapshot: { ikn: '2026/1' }, version: 2 }); enqueueTenderMutation('other@example.test', { key: '2026/1', patch: { takipte: true }, snapshot: { ikn: '2026/1' }, version: 0 }); assert.equal(offlineMutationCount('qa@example.test'), 1); assert.deepEqual(listOfflineMutations('qa@example.test')[0].patch, { takipte: true, kanbanStatus: 'teklif_hazirlaniyor' }); assert.equal(offlineMutationCount('other@example.test'), 1); clearOfflineMutations('qa@example.test'); clearOfflineMutations('other@example.test'); }); test('replay removes acknowledged rows and retains the first failed row', async () => { clearOfflineMutations('replay@example.test'); enqueueTenderMutation('replay@example.test', { key: 'a', patch: { takipte: true }, snapshot: {}, version: 0 }); enqueueTenderMutation('replay@example.test', { key: 'b', patch: { takipte: true }, snapshot: {}, version: 0 }); const sent = []; const first = await replayOfflineMutations('replay@example.test', async item => { sent.push(item.key); }); assert.deepEqual(sent, ['a', 'b']); assert.equal(first.pending, 0); enqueueTenderMutation('replay@example.test', { key: 'c', patch: { takipte: true }, snapshot: {}, version: 0 }); enqueueTenderMutation('replay@example.test', { key: 'd', patch: { takipte: true }, snapshot: {}, version: 0 }); const second = await replayOfflineMutations('replay@example.test', async item => { if (item.key === 'c') throw new Error('network'); }); assert.equal(second.sent, 0); assert.equal(listOfflineMutations('replay@example.test')[0].key, 'c'); assert.equal(listOfflineMutations('replay@example.test')[0].attempts, 1); clearOfflineMutations('replay@example.test'); });