import { describe, expect, it } from "vitest"; 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"], ["OPERATION_TYPE_SELL_CARD", "sell"], ["OPERATION_TYPE_SELL_MARGIN", "sell"], ["OPERATION_TYPE_DIV_EXT", "dividend"], ["OPERATION_TYPE_DIVIDEND", "dividend"], ["OPERATION_TYPE_DIVIDEND_TRANSFER", "dividend"], ["OPERATION_TYPE_INPUT_SECURITIES", "input"], ["OPERATION_TYPE_OUTPUT_SECURITIES", "output"], ["OPERATION_TYPE_FUTURE_TAX", "tax"], ["OPERATION_TYPE_FUTURE_FEE", "fee"], ["OPERATION_TYPE_TRANS_FUTURE", "transfer"], ["FUTURE_UNKNOWN_OPERATION", "other"], ])("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(); }); });