feat: add engine and store snapshot/restore for restart resilience
This commit is contained in:
@@ -65,3 +65,13 @@ test("second unlock call is idempotent and does not double charge", () => {
|
||||
|
||||
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");
|
||||
});
|
||||
|
||||
@@ -154,3 +154,29 @@ test("lists jobs for user newest first and provides summary", () => {
|
||||
assert.equal(summary.totalCreditsSpent, 2);
|
||||
assert.equal(summary.balance, 8);
|
||||
});
|
||||
|
||||
test("round-trips state snapshot across engine restart", () => {
|
||||
const engine1 = createEngine();
|
||||
engine1.topUpCredits("u1", 5, "topup-snapshot");
|
||||
|
||||
const created = engine1.processMention({
|
||||
mentionPostId: "m-snapshot",
|
||||
callerUserId: "u1",
|
||||
parentPost: {
|
||||
id: "p-snapshot",
|
||||
authorId: "author-snapshot",
|
||||
article: { id: "a-snapshot", title: "Snap", body: "hello world" },
|
||||
},
|
||||
});
|
||||
|
||||
const snapshot = engine1.exportState();
|
||||
const engine2 = new XArtAudioEngine({
|
||||
creditConfig: engine1.creditConfig,
|
||||
initialState: snapshot,
|
||||
});
|
||||
|
||||
assert.equal(engine2.getWalletBalance("u1"), 4);
|
||||
assert.equal(engine2.getJob(created.job.id).article.title, "Snap");
|
||||
assert.equal(engine2.getAsset(created.job.assetId).articleTitle, "Snap");
|
||||
assert.equal(engine2.checkAudioAccess(created.job.assetId, "u1").allowed, true);
|
||||
});
|
||||
|
||||
@@ -61,3 +61,27 @@ test("is idempotent by idempotency key", () => {
|
||||
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);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user