Files
xarticleaudio/test/wallet.test.js

88 lines
1.9 KiB
JavaScript

"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const { WalletStore } = require("../src/lib/wallet");
test("applies credit and debit transactions", () => {
const wallet = new WalletStore();
wallet.applyTransaction({
userId: "u1",
type: "credit",
amount: 5,
reason: "topup",
idempotencyKey: "evt-1",
});
wallet.applyTransaction({
userId: "u1",
type: "debit",
amount: 2,
reason: "article_generation",
idempotencyKey: "evt-2",
});
assert.equal(wallet.getBalance("u1"), 3);
});
test("prevents overdraft debits", () => {
const wallet = new WalletStore();
assert.throws(() => {
wallet.applyTransaction({
userId: "u1",
type: "debit",
amount: 1,
reason: "article_generation",
idempotencyKey: "evt-3",
});
}, /insufficient_credits/);
});
test("is idempotent by idempotency key", () => {
const wallet = new WalletStore();
const first = wallet.applyTransaction({
userId: "u1",
type: "credit",
amount: 4,
reason: "topup",
idempotencyKey: "evt-4",
});
const second = wallet.applyTransaction({
userId: "u1",
type: "credit",
amount: 999,
reason: "topup",
idempotencyKey: "evt-4",
});
assert.equal(first.id, second.id);
assert.equal(wallet.getBalance("u1"), 4);
});
test("can restore state from previous snapshot", () => {
const original = new WalletStore();
original.applyTransaction({
userId: "u1",
type: "credit",
amount: 3,
reason: "topup",
idempotencyKey: "evt-r1",
});
const restored = new WalletStore(original.exportState());
assert.equal(restored.getBalance("u1"), 3);
const duplicate = restored.applyTransaction({
userId: "u1",
type: "credit",
amount: 3,
reason: "topup",
idempotencyKey: "evt-r1",
});
assert.equal(duplicate.amount, 3);
assert.equal(restored.getBalance("u1"), 3);
});