feat: group all-account rows by instrument and day (WealthLedger/main#47) (#126)
This commit was merged in pull request #126.
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
import { expect, it } from "vitest";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { operationLabelKey } from "./display";
|
||||
import type { BrokerageOperation } from "../api/useBrokerageOperations";
|
||||
|
||||
import { brokerageOperationGroupKey, operationLabelKey } from "./display";
|
||||
|
||||
it.each([
|
||||
["OPERATION_TYPE_BUY", "buy"],
|
||||
["OPERATION_TYPE_COUPON", "other"],
|
||||
["OPERATION_TYPE_BUY_CARD", "buy"],
|
||||
["OPERATION_TYPE_BUY_MARGIN", "buy"],
|
||||
["OPERATION_TYPE_SELL", "sell"],
|
||||
@@ -21,3 +24,71 @@ it.each([
|
||||
])("preserves the wire operation label for %s", (type, label) => {
|
||||
expect(operationLabelKey(type)).toBe(`ledger.operationType.${label}`);
|
||||
});
|
||||
|
||||
describe("brokerageOperationGroupKey", () => {
|
||||
const base: BrokerageOperation = {
|
||||
account: { id: "account-1", name: "Брокерский" },
|
||||
accruedInterest: null,
|
||||
category: "income",
|
||||
commission: null,
|
||||
description: "Купон",
|
||||
figi: "FIGI",
|
||||
id: "operation",
|
||||
instrumentType: "bond",
|
||||
instrumentUid: "UID",
|
||||
logoName: null,
|
||||
occurredAt: "2026-08-14T10:00:00Z",
|
||||
payment: null,
|
||||
price: null,
|
||||
quantity: null,
|
||||
ticker: "BOND",
|
||||
type: "OPERATION_TYPE_COUPON",
|
||||
};
|
||||
|
||||
it("uses screen day, preferred identity and exact type, not account", () => {
|
||||
const first = brokerageOperationGroupKey(base);
|
||||
|
||||
const same = brokerageOperationGroupKey({
|
||||
...base,
|
||||
account: { id: "account-2", name: "ИИС" },
|
||||
figi: "OTHER-FIGI",
|
||||
occurredAt: "2026-08-14T11:00:00Z",
|
||||
});
|
||||
|
||||
expect(same).toBe(first);
|
||||
expect(brokerageOperationGroupKey({
|
||||
...base,
|
||||
type: "OPERATION_TYPE_DIVIDEND",
|
||||
})).not.toBe(first);
|
||||
});
|
||||
|
||||
it("keeps buy and sell of one instrument in different groups", () => {
|
||||
expect(brokerageOperationGroupKey({ ...base, type: "OPERATION_TYPE_BUY" }))
|
||||
.not.toBe(brokerageOperationGroupKey({
|
||||
...base,
|
||||
type: "OPERATION_TYPE_SELL",
|
||||
}));
|
||||
});
|
||||
|
||||
it("separates local midnight and joins one local day across UTC dates", () => {
|
||||
const before = new Date(2026, 7, 14, 23, 59).toISOString();
|
||||
const after = new Date(2026, 7, 15, 0, 1).toISOString();
|
||||
const morning = new Date(2026, 7, 14, 1).toISOString();
|
||||
const evening = new Date(2026, 7, 14, 23).toISOString();
|
||||
|
||||
expect(brokerageOperationGroupKey({ ...base, occurredAt: before }))
|
||||
.not.toBe(brokerageOperationGroupKey({ ...base, occurredAt: after }));
|
||||
expect(brokerageOperationGroupKey({ ...base, occurredAt: morning }))
|
||||
.toBe(brokerageOperationGroupKey({ ...base, occurredAt: evening }));
|
||||
});
|
||||
|
||||
it("falls back to FIGI and leaves missing identity ungrouped", () => {
|
||||
expect(brokerageOperationGroupKey({ ...base, instrumentUid: null }))
|
||||
.toBe(brokerageOperationGroupKey({ ...base, instrumentUid: "" }));
|
||||
expect(brokerageOperationGroupKey({
|
||||
...base,
|
||||
figi: null,
|
||||
instrumentUid: null,
|
||||
})).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user