BillTracker/tests/subscriptionService.test.js

74 lines
2.7 KiB
JavaScript

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-subscription-service-test-${process.pid}.sqlite`);
process.env.DB_PATH = dbPath;
const { getDb, closeDb } = require('../db/database');
const {
getSubscriptionRecommendations,
searchSubscriptionTransactions,
} = require('../services/subscriptionService');
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(`subscription-user-${suffix}`, `subscription-user-${suffix}@local`).lastInsertRowid;
}
function createTransaction(db, userId, overrides = {}) {
return db.prepare(`
INSERT INTO transactions
(user_id, source_type, posted_date, amount, currency, description, payee, match_status, ignored)
VALUES (?, 'manual', ?, ?, 'USD', ?, ?, 'unmatched', 0)
`).run(
userId,
overrides.posted_date || new Date().toISOString().slice(0, 10),
overrides.amount ?? -1599,
overrides.description || 'NETFLIX.COM',
overrides.payee || 'NETFLIX.COM',
).lastInsertRowid;
}
test.after(() => {
closeDb();
for (const suffix of ['', '-wal', '-shm']) {
fs.rmSync(`${dbPath}${suffix}`, { force: true });
}
});
test('known catalog services appear as high-confidence subscription recommendations', () => {
const db = getDb();
const userId = createUser(db, 'recommendation');
createTransaction(db, userId);
const recommendations = getSubscriptionRecommendations(db, userId);
const netflix = recommendations.find(item => item.catalog_match?.name === 'Netflix');
assert.ok(netflix, 'Netflix catalog match should be recommended from one known charge');
assert.equal(netflix.subscription_type, 'streaming');
assert.equal(netflix.confidence >= 90, true);
assert.match(netflix.reasons.join(' '), /Matches known service: Netflix/);
});
test('subscription transaction search annotates known catalog matches', () => {
const db = getDb();
const userId = createUser(db, 'search');
const transactionId = createTransaction(db, userId, {
description: 'NETFLIX.COM 866-579-7172',
payee: 'NETFLIX.COM',
});
const matches = searchSubscriptionTransactions(db, userId, { q: 'netflix', limit: 10 });
const match = matches.find(item => item.id === transactionId);
assert.ok(match, 'transaction should be returned by subscription search');
assert.equal(match.is_known_subscription, true);
assert.equal(match.catalog_match.name, 'Netflix');
assert.equal(match.catalog_match.subscription_type, 'streaming');
});