Files
xarticleaudio/test/access.test.js

78 lines
2.2 KiB
JavaScript

"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const { WalletStore } = require("../src/lib/wallet");
const { AudioAccessStore } = require("../src/lib/access");
const audio = {
id: "a1",
ownerUserId: "owner-1",
creditsCharged: 3,
};
test("owner can access without payment", () => {
const access = new AudioAccessStore();
const result = access.canAccess({ audio, userId: "owner-1" });
assert.equal(result.allowed, true);
assert.equal(result.reason, "owner");
});
test("non-owner requires payment", () => {
const access = new AudioAccessStore();
const result = access.canAccess({ audio, userId: "u2" });
assert.equal(result.allowed, false);
assert.equal(result.reason, "payment_required");
assert.equal(result.creditsRequired, 3);
});
test("unlock debits same credits and creates permanent grant", () => {
const access = new AudioAccessStore();
const wallet = new WalletStore();
wallet.applyTransaction({
userId: "u2",
type: "credit",
amount: 10,
reason: "topup",
idempotencyKey: "credit-u2",
});
const unlocked = access.unlockWithCredits({ audio, userId: "u2", wallet });
assert.equal(unlocked.unlocked, true);
assert.equal(unlocked.charged, 3);
assert.equal(wallet.getBalance("u2"), 7);
const canAccess = access.canAccess({ audio, userId: "u2" });
assert.equal(canAccess.allowed, true);
assert.equal(canAccess.reason, "grant");
});
test("second unlock call is idempotent and does not double charge", () => {
const access = new AudioAccessStore();
const wallet = new WalletStore();
wallet.applyTransaction({
userId: "u2",
type: "credit",
amount: 10,
reason: "topup",
idempotencyKey: "credit-u2-2",
});
access.unlockWithCredits({ audio, userId: "u2", wallet });
access.unlockWithCredits({ audio, userId: "u2", wallet });
assert.equal(wallet.getBalance("u2"), 7);
});
test("restores grant state from snapshot", () => {
const access = new AudioAccessStore();
access.grantAccess("a1", "u2");
const restored = new AudioAccessStore(access.exportState());
const canAccess = restored.canAccess({ audio, userId: "u2" });
assert.equal(canAccess.allowed, true);
assert.equal(canAccess.reason, "grant");
});