Skip to content
markpaper

src/rest/activeOrders.test.ts

v0.2.1 · 3.2 KB

Download file
import { describe, expect, it } from 'vitest';
import { activeOrdersText, ORDER_ID_A, ORDER_ID_B, ORDER_ID_ROUNDED } from '../testing/fixtures.js';
import { ordersOnUnknownMarkets, parseActiveOrders } from './activeOrders.js';
import { LighterReadError } from './errors.js';

const symbols = new Map<number, string>([
  [32, 'ETH'],
  [41, 'CRWV'],
]);

describe('parseActiveOrders', () => {
  it('keeps ids exact from the raw text and skips zero remainders', () => {
    const orders = parseActiveOrders(activeOrdersText(), { symbolByMarketId: symbols });
    expect(orders).toHaveLength(2); // the filled one has remaining 0
    expect(orders.map((o) => o.orderId)).toEqual([ORDER_ID_A, ORDER_ID_B]);
    expect(orders.every((o) => o.orderIdPrecision === 'exact')).toBe(true);
    expect(orders[0]).toMatchObject({
      clientOrderIndex: 1712345678,
      marketIndex: 32,
      symbol: 'ETH',
      isAsk: true,
      isBuy: false,
      priceStr: '1650.00',
      price: 1650,
      remaining: 0.01,
      initial: 0.01,
      reduceOnly: false,
      status: 'open',
    });
    expect(orders[1]).toMatchObject({ isBuy: true, reduceOnly: true, remaining: 0.02, initial: 0.03 });
  });

  it('two orders whose numbers collapse stay two distinct orders', () => {
    const orders = parseActiveOrders(activeOrdersText());
    expect(Number(orders[0]?.orderId)).toBe(Number(orders[1]?.orderId));
    expect(orders[0]?.orderId).not.toBe(orders[1]?.orderId);
  });

  it('accepts a parsed object when order_id is a string, rejects a rounded-only id', () => {
    const okObj = {
      orders: [
        {
          order_id: ORDER_ID_A,
          order_index: ORDER_ID_ROUNDED,
          market_index: 32,
          price: '1',
          remaining_base_amount: '1',
        },
      ],
    };
    expect(parseActiveOrders(okObj)[0]?.orderId).toBe(ORDER_ID_A);
    const rounded = {
      orders: [{ order_index: ORDER_ID_ROUNDED, market_index: 32, price: '1', remaining_base_amount: '1' }],
    };
    expect(() => parseActiveOrders(rounded)).toThrow(/rounded id/);
  });

  it('fails closed on a missing array and on broken records', () => {
    expect(() => parseActiveOrders('{"code":200}')).toThrow(LighterReadError);
    expect(() => parseActiveOrders({ orders: 'none' })).toThrow(LighterReadError);
    expect(() =>
      parseActiveOrders({ orders: [{ order_id: '1', market_index: 1, price: 'x', remaining_base_amount: '1' }] }),
    ).toThrow(/broken order/);
    expect(() => parseActiveOrders({ orders: [{ order_id: '1', market_index: 1, price: '1' }] })).toThrow(
      /broken order/,
    );
    expect(() => parseActiveOrders({ orders: [{ order_id: '1', price: '1', remaining_base_amount: '1' }] })).toThrow(
      /broken order/,
    );
    expect(() => parseActiveOrders({ orders: [42] })).toThrow(/non-object/);
  });

  it('keeps orders on unknown markets with symbol undefined and lists them', () => {
    const orders = parseActiveOrders(activeOrdersText(), { symbolByMarketId: new Map([[41, 'CRWV']]) });
    expect(orders.map((o) => o.symbol)).toEqual([undefined, undefined]);
    expect(ordersOnUnknownMarkets(orders)).toHaveLength(2);
    expect(parseActiveOrders('{"orders":[]}')).toEqual([]);
  });
});
All files