const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const dbPath = path.join(os.tmpdir(), `bill-tracker-bank-sync-test-${process.pid}.sqlite`); process.env.DB_PATH = dbPath; const { getDb, closeDb } = require('../db/database'); const { encryptSecret } = require('../services/encryptionService'); const { syncDataSource } = require('../services/bankSyncService'); function createUser(db, suffix) { return db.prepare(` INSERT INTO users (username, password_hash, role, active, email, created_at, updated_at) VALUES (?, 'x', 'user', 1, ?, datetime('now'), datetime('now')) `).run(`bank-sync-${suffix}`, `bank-sync-${suffix}@local`).lastInsertRowid; } function createSource(db, userId) { return db.prepare(` INSERT INTO data_sources (user_id, type, provider, name, status, encrypted_secret) VALUES (?, 'provider_sync', 'simplefin', 'SimpleFIN', 'active', ?) `).run(userId, encryptSecret('https://user:pass@example.com/simplefin')).lastInsertRowid; } function createAccount(db, userId, dataSourceId, providerAccountId, monitored) { return db.prepare(` INSERT INTO financial_accounts (user_id, data_source_id, provider_account_id, name, currency, monitored) VALUES (?, ?, ?, ?, 'USD', ?) `).run(userId, dataSourceId, providerAccountId, providerAccountId, monitored ? 1 : 0).lastInsertRowid; } test.after(() => { closeDb(); for (const suffix of ['', '-wal', '-shm']) { fs.rmSync(`${dbPath}${suffix}`, { force: true }); } }); test('SimpleFIN sync skips storing transactions for unmonitored accounts', async () => { const db = getDb(); const userId = createUser(db, 'skip-unmonitored'); const dataSourceId = createSource(db, userId); const mutedAccountId = createAccount(db, userId, dataSourceId, 'muted-account', false); const originalFetch = global.fetch; global.fetch = async () => ({ ok: true, status: 200, json: async () => ({ accounts: [ { id: 'muted-account', name: 'Muted Account', currency: 'USD', balance: '100.00', transactions: [ { id: 'muted-tx-1', amount: '-12.34', posted: 1772323200, description: 'Muted charge' }, ], }, { id: 'tracked-account', name: 'Tracked Account', currency: 'USD', balance: '200.00', transactions: [ { id: 'tracked-tx-1', amount: '-56.78', posted: 1772323200, description: 'Tracked charge' }, ], }, ], }), }); try { const result = await syncDataSource(db, userId, dataSourceId); assert.equal(result.transactionsNew, 1); } finally { global.fetch = originalFetch; } const mutedTransactions = db.prepare('SELECT COUNT(*) AS count FROM transactions WHERE account_id = ?').get(mutedAccountId).count; assert.equal(mutedTransactions, 0); const trackedAccount = db.prepare(` SELECT id, monitored FROM financial_accounts WHERE user_id = ? AND data_source_id = ? AND provider_account_id = 'tracked-account' `).get(userId, dataSourceId); assert.equal(trackedAccount.monitored, 1); const trackedTransactions = db.prepare('SELECT COUNT(*) AS count FROM transactions WHERE account_id = ?').get(trackedAccount.id).count; assert.equal(trackedTransactions, 1); });