laplace-api 4.7.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@ import { Logger } from "winston";
2
2
  import { LaplaceConfiguration } from "../utilities/configuration";
3
3
  import "./client_test_suite";
4
4
  import { BISTBidAskStreamData, BISTStockStreamData, LivePriceClient, OrderbookLiveData } from "../client/live-price";
5
+ import { LivePriceFeed } from "../client/live-price-web-socket";
5
6
 
6
7
  describe("LivePrice", () => {
7
8
  let client: LivePriceClient;
@@ -159,6 +160,8 @@ describe("LivePrice", () => {
159
160
  expect(typeof receivedData.s).toBe("string");
160
161
  expect(typeof receivedData.p).toBe("number");
161
162
  expect(typeof receivedData.d).toBe("number");
163
+ expect(typeof receivedData.pc).toBe("number");
164
+ expect(typeof receivedData.ac).toBe("number");
162
165
  } else {
163
166
  console.log("Timeout waiting for US data");
164
167
  }
@@ -475,6 +478,137 @@ describe("LivePrice", () => {
475
478
  );
476
479
  });
477
480
 
481
+ describe("GetClientWebsocketUrl", () => {
482
+ it(
483
+ "should return a websocket url string",
484
+ async () => {
485
+ const resp = await client.getClientWebsocketUrl("test-integration-user", [LivePriceFeed.LiveBist]);
486
+ expect(typeof resp).toBe("string");
487
+ expect(resp.length).toBeGreaterThan(0);
488
+ },
489
+ TEST_CONSTANTS.JEST_TIMEOUT
490
+ );
491
+ });
492
+
493
+ describe("GetWebsocketUsageForMonth", () => {
494
+ it(
495
+ "should return an array of usage data",
496
+ async () => {
497
+ const resp = await client.getWebsocketUsageForMonth(1, 2025, LivePriceFeed.LiveBist);
498
+ expect(Array.isArray(resp)).toBe(true);
499
+ if (resp.length > 0) {
500
+ expect(typeof resp[0].externalUserID).toBe("string");
501
+ expect(typeof resp[0].uniqueDeviceCount).toBe("number");
502
+ }
503
+ },
504
+ TEST_CONSTANTS.JEST_TIMEOUT
505
+ );
506
+ });
507
+
508
+ describe("Mock Tests (Data Injection)", () => {
509
+ let mockClient: LivePriceClient;
510
+ let cli: { request: jest.Mock };
511
+
512
+ beforeEach(() => {
513
+ cli = { request: jest.fn() };
514
+ const config = (global as any).testSuite.config as LaplaceConfiguration;
515
+ const mockLogger: Logger = {
516
+ info: jest.fn(),
517
+ error: jest.fn(),
518
+ warn: jest.fn(),
519
+ debug: jest.fn(),
520
+ } as unknown as Logger;
521
+ mockClient = new LivePriceClient(config, mockLogger, cli as any);
522
+ });
523
+
524
+ describe("getClientWebsocketUrl", () => {
525
+ test("calls correct endpoint, sends correct body, and returns url string", async () => {
526
+ cli.request.mockResolvedValueOnce({ data: { url: "wss://example.com/ws" } });
527
+
528
+ const resp = await mockClient.getClientWebsocketUrl("user123", [LivePriceFeed.LiveBist, LivePriceFeed.LiveUs]);
529
+
530
+ expect(cli.request).toHaveBeenCalledTimes(1);
531
+ const call = cli.request.mock.calls[0][0];
532
+ expect(call.method).toBe("POST");
533
+ expect(call.url).toBe("/api/v2/ws/url");
534
+ expect(call.data).toEqual({ externalUserId: "user123", feeds: [LivePriceFeed.LiveBist, LivePriceFeed.LiveUs] });
535
+ expect(resp).toBe("wss://example.com/ws");
536
+ });
537
+
538
+ test("bubbles up request error", async () => {
539
+ cli.request.mockRejectedValueOnce(new Error("Unauthorized"));
540
+
541
+ await expect(mockClient.getClientWebsocketUrl("user123", [LivePriceFeed.LiveBist])).rejects.toThrow("Unauthorized");
542
+ expect(cli.request).toHaveBeenCalledTimes(1);
543
+ });
544
+ });
545
+
546
+ describe("getWebsocketUsageForMonth", () => {
547
+ test("calls correct endpoint with correct query params and returns usage data", async () => {
548
+ const mockUsage = [
549
+ { externalUserID: "user123", firstConnectionTime: new Date("2024-01-15"), uniqueDeviceCount: 3 },
550
+ ];
551
+ cli.request.mockResolvedValueOnce({ data: mockUsage });
552
+
553
+ const resp = await mockClient.getWebsocketUsageForMonth(1, 2024, LivePriceFeed.LiveBist);
554
+
555
+ expect(cli.request).toHaveBeenCalledTimes(1);
556
+ const call = cli.request.mock.calls[0][0];
557
+ expect(call.method).toBe("GET");
558
+ expect(call.url).toBe("/api/v1/ws/report");
559
+ expect(call.params).toEqual({ month: 1, year: 2024, feedType: LivePriceFeed.LiveBist });
560
+ expect(resp).toEqual(mockUsage);
561
+ });
562
+
563
+ test("bubbles up request error", async () => {
564
+ cli.request.mockRejectedValueOnce(new Error("Forbidden"));
565
+
566
+ await expect(mockClient.getWebsocketUsageForMonth(1, 2024, LivePriceFeed.LiveBist)).rejects.toThrow("Forbidden");
567
+ expect(cli.request).toHaveBeenCalledTimes(1);
568
+ });
569
+ });
570
+
571
+ describe("sendWebsocketEvent", () => {
572
+ test("calls correct endpoint with request body", async () => {
573
+ cli.request.mockResolvedValueOnce({ data: undefined });
574
+
575
+ const request = { externalUserID: "user123", event: { type: "test" }, transient: true };
576
+ await mockClient.sendWebsocketEvent(request);
577
+
578
+ expect(cli.request).toHaveBeenCalledTimes(1);
579
+ const call = cli.request.mock.calls[0][0];
580
+ expect(call.method).toBe("POST");
581
+ expect(call.url).toBe("/api/v1/ws/event");
582
+ expect(call.data).toEqual(request);
583
+ });
584
+
585
+ test("bubbles up request error", async () => {
586
+ cli.request.mockRejectedValueOnce(new Error("Bad request"));
587
+
588
+ await expect(mockClient.sendWebsocketEvent({ event: { type: "test" } })).rejects.toThrow("Bad request");
589
+ });
590
+ });
591
+
592
+ describe("revokeWebsocketConnection", () => {
593
+ test("calls correct endpoint with id path param", async () => {
594
+ cli.request.mockResolvedValueOnce({ data: {} });
595
+
596
+ await mockClient.revokeWebsocketConnection("abc-123");
597
+
598
+ expect(cli.request).toHaveBeenCalledTimes(1);
599
+ const call = cli.request.mock.calls[0][0];
600
+ expect(call.method).toBe("POST");
601
+ expect(call.url).toBe("/api/v1/ws/user/revoke/abc-123");
602
+ });
603
+
604
+ test("bubbles up request error", async () => {
605
+ cli.request.mockRejectedValueOnce(new Error("Not found"));
606
+
607
+ await expect(mockClient.revokeWebsocketConnection("bad-id")).rejects.toThrow("Not found");
608
+ });
609
+ });
610
+ });
611
+
478
612
  describe("GetBidAskForBIST", () => {
479
613
  it(
480
614
  "should receive BIST bid/ask data",
@@ -515,7 +649,7 @@ describe("LivePrice", () => {
515
649
  console.log("Received BIST bid/ask data:", tempReceivedData);
516
650
  expect(tempReceivedData.s).toBeDefined();
517
651
  expect(typeof tempReceivedData.s).toBe("string");
518
- expect(typeof tempReceivedData.d).toBe("string");
652
+ expect(typeof tempReceivedData.d).toBe("number");
519
653
  expect(typeof tempReceivedData.ask).toBe("number");
520
654
  expect(typeof tempReceivedData.bid).toBe("number");
521
655
  } else {