fix(history): preserve multiple balance updates on the same day
This commit is contained in:
1 parent
99174a3da5
commit
2eb2f4b56e
8 files changed
+130
-38
No files matched your search
@@ -46,6 +46,23 @@ test('correction recalculates later delta', () => {
|
||||
assert.equal(history(a)[1].delta, '20');
|
||||
assert.equal(totals([a], [], 'CNY', '2026-09-02').net, '110.10');
|
||||
});
|
||||
test('multiple same-day balances preserve ordering and use last value in totals', () => {
|
||||
const a = p();
|
||||
a.revisions = [
|
||||
{ ...rev('120.10', '2026-09-01'), sequence: 3 },
|
||||
{ ...rev('100.10', '2026-09-01'), sequence: 1 },
|
||||
{ ...rev('110.10', '2026-09-01'), sequence: 2 },
|
||||
];
|
||||
assert.deepEqual(
|
||||
history(a).map((r) => r.after),
|
||||
['100.1', '110.1', '120.1'],
|
||||
);
|
||||
assert.equal(history(a)[2].delta, '10');
|
||||
assert.equal(totals([a], [], 'CNY', '2026-09-01').net, '120.10');
|
||||
a.revisions[1].amount = '90.10';
|
||||
assert.equal(history(a)[1].delta, '20');
|
||||
assert.equal(totals([a], [], 'CNY', '2026-09-01').net, '120.10');
|
||||
});
|
||||
test('FX and actual changes separated', () => {
|
||||
const a = p('asset', 'USD');
|
||||
a.revisions = [rev('100', '2026-09-01'), rev('110', '2026-09-02')];
|
||||
|
||||
@@ -232,6 +232,35 @@ test('real MySQL: authentication, isolation, history, backup and atomic failures
|
||||
);
|
||||
o = (await call('/overview', 'GET', undefined, a.cookie)).data;
|
||||
assert.equal(o.net, '570.10');
|
||||
assert.equal(
|
||||
(
|
||||
await call(
|
||||
'/positions/' + bank + '/revisions',
|
||||
'POST',
|
||||
{ amount: '120.10', date: '2026-09-02' },
|
||||
a.cookie,
|
||||
)
|
||||
).status,
|
||||
201,
|
||||
);
|
||||
const sameDay = (await call('/positions/' + bank, 'GET', undefined, a.cookie)).data.history;
|
||||
assert.equal(sameDay.length, 3);
|
||||
assert.equal(sameDay[2].after, '120.1');
|
||||
assert.equal(sameDay[2].delta, '10');
|
||||
assert.ok(sameDay[2].sequence > sameDay[1].sequence);
|
||||
assert.equal(
|
||||
(
|
||||
await call(
|
||||
'/positions/' + bank + '/revisions',
|
||||
'POST',
|
||||
{ amount: '0', date: '2026-09-03', reason: 'repayment' },
|
||||
a.cookie,
|
||||
)
|
||||
).status,
|
||||
400,
|
||||
);
|
||||
o = (await call('/overview', 'GET', undefined, a.cookie)).data;
|
||||
assert.equal(o.net, '580.10');
|
||||
const backup = (await call('/backup', 'GET', undefined, a.cookie)).data;
|
||||
assert.equal(backup.positions.length, 4);
|
||||
assert.equal(backup.links.length, 2);
|
||||
@@ -270,6 +299,13 @@ test('real MySQL: authentication, isolation, history, backup and atomic failures
|
||||
),
|
||||
);
|
||||
assert.equal(restored.find((p: { kind: string }) => p.kind === 'debt').outgoing.length, 2);
|
||||
const restoredHistory = restored.find(
|
||||
(p: { kind: string; side: string }) => p.kind === 'account' && p.side === 'asset',
|
||||
).history;
|
||||
assert.deepEqual(
|
||||
restoredHistory.map((h: { after: string }) => h.after),
|
||||
sameDay.map((h: { after: string }) => h.after),
|
||||
);
|
||||
assert.equal(
|
||||
(await call('/backup/import', 'POST', { confirmed: true, backup }, b.cookie)).status,
|
||||
409,
|
||||
|
||||
Reference in new issue
Block a user