laplace-api 4.8.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.
@@ -1,87 +1,69 @@
1
1
  import { Logger } from "winston";
2
2
  import { LaplaceConfiguration } from "../utilities/configuration";
3
3
  import "./client_test_suite";
4
- import { Holding, Politician, PoliticianClient, PoliticianDetail, TopHolding } from "../client/politician";
5
-
6
- describe("Politician", () => {
7
- let politicianClient: PoliticianClient;
8
-
9
- const mockPoliticians: Politician[] = [
10
- {
11
- id: 1,
12
- politicianName: "John Doe",
13
- totalHoldings: 10000,
14
- lastUpdated: new Date("2024-01-01")
15
- },
16
- {
17
- id: 2,
18
- politicianName: "Jane Smith",
19
- totalHoldings: 10000,
20
- lastUpdated: new Date("2024-01-02")
21
- }
22
- ];
23
-
24
- const mockHoldings: Holding[] = [
25
- {
26
- politicianName: "John Doe",
27
- symbol: "AAPL",
28
- company: "Apple Inc.",
29
- holding: "$500,000",
30
- allocation: "50%",
31
- lastUpdated: new Date("2024-01-01")
32
- },
33
- {
34
- politicianName: "John Doe",
35
- symbol: "GOOGL",
36
- company: "Alphabet Inc.",
37
- holding: "$500,000",
38
- allocation: "50%",
39
- lastUpdated: new Date("2024-01-01")
40
- }
41
- ];
42
-
43
- const mockTopHoldings: TopHolding[] = [
44
- {
45
- symbol: "AAPL",
46
- company: "Apple Inc.",
47
- politicians: [
48
- {
49
- name: "John Doe",
50
- holding: "$500,000",
51
- allocation: "50%"
52
- },
53
- {
54
- name: "Jane Smith",
55
- holding: "$1,000,000",
56
- allocation: "40%"
57
- }
58
- ],
59
- count: 2
60
- }
61
- ];
4
+ import { PoliticianClient } from "../client/politician";
62
5
 
63
- const mockPoliticianPortfolio: PoliticianDetail = {
6
+ const mockPoliticians = [
7
+ {
64
8
  id: 1,
65
- name: "John Doe",
66
- holdings: [
67
- {
68
- symbol: "AAPL",
69
- company: "Apple Inc.",
70
- holding: "$500,000",
71
- allocation: "50%"
72
- },
73
- {
74
- symbol: "GOOGL",
75
- company: "Alphabet Inc.",
76
- holding: "$500,000",
77
- allocation: "50%"
78
- }
79
- ],
80
- totalHoldings: 1000000,
9
+ politicianName: "John Doe",
10
+ totalHoldings: 10000,
81
11
  lastUpdated: new Date("2024-01-01")
82
- };
83
-
84
- beforeAll(async () => {
12
+ },
13
+ {
14
+ id: 2,
15
+ politicianName: "Jane Smith",
16
+ totalHoldings: 20000,
17
+ lastUpdated: new Date("2024-01-02")
18
+ }
19
+ ];
20
+
21
+ const mockHoldings = [
22
+ {
23
+ politicianName: "John Doe",
24
+ symbol: "AAPL",
25
+ company: "Apple Inc.",
26
+ holding: "$500,000",
27
+ allocation: "50%",
28
+ lastUpdated: new Date("2024-01-01")
29
+ },
30
+ {
31
+ politicianName: "John Doe",
32
+ symbol: "GOOGL",
33
+ company: "Alphabet Inc.",
34
+ holding: "$500,000",
35
+ allocation: "50%",
36
+ lastUpdated: new Date("2024-01-01")
37
+ }
38
+ ];
39
+
40
+ const mockTopHoldings = [
41
+ {
42
+ symbol: "AAPL",
43
+ company: "Apple Inc.",
44
+ politicians: [
45
+ { name: "John Doe", holding: "$500,000", allocation: "50%" },
46
+ { name: "Jane Smith", holding: "$1,000,000", allocation: "40%" }
47
+ ],
48
+ count: 2
49
+ }
50
+ ];
51
+
52
+ const mockPoliticianDetail = {
53
+ id: 1,
54
+ name: "John Doe",
55
+ holdings: [
56
+ { symbol: "AAPL", company: "Apple Inc.", holding: "$500,000", allocation: "50%" },
57
+ { symbol: "GOOGL", company: "Alphabet Inc.", holding: "$500,000", allocation: "50%" }
58
+ ],
59
+ totalHoldings: 1000000,
60
+ lastUpdated: new Date("2024-01-01")
61
+ };
62
+
63
+ describe("Politician Client", () => {
64
+ let client: PoliticianClient;
65
+
66
+ beforeAll(() => {
85
67
  const config = (global as any).testSuite.config as LaplaceConfiguration;
86
68
  const logger: Logger = {
87
69
  info: jest.fn(),
@@ -90,164 +72,171 @@ describe("Politician", () => {
90
72
  debug: jest.fn(),
91
73
  } as unknown as Logger;
92
74
 
93
- politicianClient = new PoliticianClient(config, logger);
75
+ client = new PoliticianClient(config, logger);
94
76
  });
95
77
 
96
78
  describe("Integration Tests", () => {
97
79
  describe("getAllPolitician", () => {
98
- it("should fetch all politicians", async () => {
99
- const politicians = await politicianClient.getAllPolitician();
100
- expect(Array.isArray(politicians)).toBe(true);
101
- if (politicians.length > 0) {
102
- expect(politicians[0]).toHaveProperty("id");
103
- expect(politicians[0]).toHaveProperty("politicianName");
104
- expect(politicians[0]).toHaveProperty("totalHoldings");
105
- expect(politicians[0]).toHaveProperty("lastUpdated");
80
+ test("should return all politicians", async () => {
81
+ const resp = await client.getAllPolitician();
82
+
83
+ expect(Array.isArray(resp)).toBe(true);
84
+
85
+ if (resp.length > 0) {
86
+ const first = resp[0];
87
+ expect(typeof first.id).toBe("number");
88
+ expect(typeof first.politicianName).toBe("string");
89
+ expect(typeof first.totalHoldings).toBe("number");
90
+ expect(first.lastUpdated).toBeDefined();
106
91
  }
107
92
  });
108
93
  });
109
94
 
110
95
  describe("getPoliticianHoldingBySymbol", () => {
111
- it("should fetch holdings for a specific symbol", async () => {
112
- const symbol = "AAPL";
113
- const holdings = await politicianClient.getPoliticianHoldingBySymbol(symbol);
114
- expect(Array.isArray(holdings)).toBe(true);
115
- if (holdings.length > 0) {
116
- expect(holdings[0]).toHaveProperty("politicianName");
117
- expect(holdings[0]).toHaveProperty("symbol", symbol);
118
- expect(holdings[0]).toHaveProperty("company");
119
- expect(holdings[0]).toHaveProperty("holding");
120
- expect(holdings[0]).toHaveProperty("allocation");
96
+ test("should return holdings for a specific symbol", async () => {
97
+ const resp = await client.getPoliticianHoldingBySymbol("AAPL");
98
+
99
+ expect(Array.isArray(resp)).toBe(true);
100
+
101
+ if (resp.length > 0) {
102
+ const first = resp[0];
103
+ expect(typeof first.politicianName).toBe("string");
104
+ expect(typeof first.symbol).toBe("string");
105
+ expect(typeof first.company).toBe("string");
106
+ expect(typeof first.holding).toBe("string");
107
+ expect(typeof first.allocation).toBe("string");
121
108
  }
122
109
  });
123
110
  });
124
111
 
125
112
  describe("getAllTopHoldings", () => {
126
- it("should fetch all top holdings", async () => {
127
- const topHoldings = await politicianClient.getAllTopHoldings();
128
- expect(Array.isArray(topHoldings)).toBe(true);
129
- if (topHoldings.length > 0) {
130
- expect(topHoldings[0]).toHaveProperty("symbol");
131
- expect(topHoldings[0]).toHaveProperty("company");
132
- expect(topHoldings[0]).toHaveProperty("politicians");
133
- expect(topHoldings[0]).toHaveProperty("count");
134
- if (topHoldings[0].politicians.length > 0) {
135
- expect(topHoldings[0].politicians[0]).toHaveProperty("name");
136
- expect(topHoldings[0].politicians[0]).toHaveProperty("holding");
137
- expect(topHoldings[0].politicians[0]).toHaveProperty("allocation");
113
+ test("should return all top holdings", async () => {
114
+ const resp = await client.getAllTopHoldings();
115
+
116
+ expect(Array.isArray(resp)).toBe(true);
117
+
118
+ if (resp.length > 0) {
119
+ const first = resp[0];
120
+ expect(typeof first.symbol).toBe("string");
121
+ expect(typeof first.company).toBe("string");
122
+ expect(typeof first.count).toBe("number");
123
+ expect(Array.isArray(first.politicians)).toBe(true);
124
+
125
+ if (first.politicians.length > 0) {
126
+ const politician = first.politicians[0];
127
+ expect(typeof politician.name).toBe("string");
128
+ expect(typeof politician.holding).toBe("string");
129
+ expect(typeof politician.allocation).toBe("string");
138
130
  }
139
131
  }
140
132
  });
141
133
  });
142
134
 
143
- describe("getPoliticianById", () => {
144
- it("should fetch politician detail by ID", async () => {
145
- const portfolio = await politicianClient.getPoliticianDetail(1);
146
- expect(portfolio).toHaveProperty("id");
147
- expect(portfolio).toHaveProperty("name");
148
- expect(portfolio).toHaveProperty("holdings");
149
- expect(portfolio).toHaveProperty("totalHoldings");
150
- expect(portfolio).toHaveProperty("lastUpdated");
151
- if (portfolio.holdings.length > 0) {
152
- expect(portfolio.holdings[0]).toHaveProperty("symbol");
153
- expect(portfolio.holdings[0]).toHaveProperty("company");
154
- expect(portfolio.holdings[0]).toHaveProperty("holding");
155
- expect(portfolio.holdings[0]).toHaveProperty("allocation");
135
+ describe("getPoliticianDetail", () => {
136
+ test("should return politician detail by ID", async () => {
137
+ const resp = await client.getPoliticianDetail(1);
138
+
139
+ expect(resp).toBeDefined();
140
+ expect(typeof resp.id).toBe("number");
141
+ expect(typeof resp.name).toBe("string");
142
+ expect(typeof resp.totalHoldings).toBe("number");
143
+ expect(resp.lastUpdated).toBeDefined();
144
+ expect(Array.isArray(resp.holdings)).toBe(true);
145
+
146
+ if (resp.holdings.length > 0) {
147
+ const first = resp.holdings[0];
148
+ expect(typeof first.symbol).toBe("string");
149
+ expect(typeof first.company).toBe("string");
150
+ expect(typeof first.holding).toBe("string");
151
+ expect(typeof first.allocation).toBe("string");
156
152
  }
157
153
  });
158
154
  });
159
155
  });
160
156
 
161
- describe("Mock Tests", () => {
157
+ describe("Mock Tests (Data Injection)", () => {
158
+ let client: PoliticianClient;
159
+ let cli: { request: jest.Mock };
160
+
162
161
  beforeEach(() => {
163
- jest.clearAllMocks();
164
- });
162
+ cli = { request: jest.fn() };
165
163
 
166
- describe("getAllPolitician", () => {
167
- it("should return all politicians successfully", async () => {
168
- jest.spyOn(politicianClient, "getAllPolitician").mockResolvedValue(mockPoliticians);
164
+ const config = (global as any).testSuite.config as LaplaceConfiguration;
165
+ const logger: Logger = {
166
+ info: jest.fn(),
167
+ error: jest.fn(),
168
+ warn: jest.fn(),
169
+ debug: jest.fn(),
170
+ } as unknown as Logger;
169
171
 
170
- const result = await politicianClient.getAllPolitician();
172
+ client = new PoliticianClient(config, logger, cli as any);
173
+ });
171
174
 
172
- expect(result).toEqual(mockPoliticians);
173
- expect(result).toHaveLength(2);
174
- expect(result[0].politicianName).toBe("John Doe");
175
- expect(result[1].politicianName).toBe("Jane Smith");
176
- });
175
+ test("getAllPolitician: calls correct endpoint and matches raw response", async () => {
176
+ cli.request.mockResolvedValueOnce({ data: mockPoliticians });
177
177
 
178
- it("should handle errors when fetching politicians", async () => {
179
- jest.spyOn(politicianClient, "getAllPolitician").mockRejectedValue(new Error("Failed to fetch politicians"));
178
+ const resp = await client.getAllPolitician();
180
179
 
181
- await expect(politicianClient.getAllPolitician()).rejects.toThrow("Failed to fetch politicians");
182
- });
183
- });
180
+ expect(cli.request).toHaveBeenCalledTimes(1);
181
+ const call = cli.request.mock.calls[0][0];
184
182
 
185
- describe("getPoliticianHoldingBySymbol", () => {
186
- it("should return holdings for a symbol successfully", async () => {
187
- jest.spyOn(politicianClient, "getPoliticianHoldingBySymbol").mockResolvedValue(mockHoldings);
188
-
189
- const result = await politicianClient.getPoliticianHoldingBySymbol("AAPL");
183
+ expect(call.method).toBe("GET");
184
+ expect(call.url).toBe("/api/v1/politician");
185
+ expect(call.params).toBeUndefined();
190
186
 
191
- expect(result).toEqual(mockHoldings);
192
- expect(result).toHaveLength(2);
193
- expect(result[0].symbol).toBe("AAPL");
194
- expect(result[1].symbol).toBe("GOOGL");
195
- });
187
+ expect(resp).toEqual(mockPoliticians);
188
+ });
196
189
 
197
- it("should handle errors when fetching holdings", async () => {
198
- jest.spyOn(politicianClient, "getPoliticianHoldingBySymbol").mockRejectedValue(new Error("Failed to fetch holdings"));
190
+ test("getPoliticianHoldingBySymbol: calls correct endpoint and matches raw response", async () => {
191
+ cli.request.mockResolvedValueOnce({ data: mockHoldings });
199
192
 
200
- await expect(politicianClient.getPoliticianHoldingBySymbol("INVALID")).rejects.toThrow("Failed to fetch holdings");
201
- });
193
+ const resp = await client.getPoliticianHoldingBySymbol("AAPL");
202
194
 
203
- it("should handle empty holdings", async () => {
204
- jest.spyOn(politicianClient, "getPoliticianHoldingBySymbol").mockResolvedValue([]);
195
+ expect(cli.request).toHaveBeenCalledTimes(1);
196
+ const call = cli.request.mock.calls[0][0];
205
197
 
206
- const result = await politicianClient.getPoliticianHoldingBySymbol("NONEXISTENT");
198
+ expect(call.method).toBe("GET");
199
+ expect(call.url).toBe("/api/v1/holding/AAPL");
200
+ expect(call.params).toBeUndefined();
207
201
 
208
- expect(result).toEqual([]);
209
- expect(result).toHaveLength(0);
210
- });
202
+ expect(resp).toEqual(mockHoldings);
211
203
  });
212
204
 
213
- describe("getAllTopHoldings", () => {
214
- it("should return top holdings successfully", async () => {
215
- jest.spyOn(politicianClient, "getAllTopHoldings").mockResolvedValue(mockTopHoldings);
205
+ test("getAllTopHoldings: calls correct endpoint and matches raw response", async () => {
206
+ cli.request.mockResolvedValueOnce({ data: mockTopHoldings });
216
207
 
217
- const result = await politicianClient.getAllTopHoldings();
208
+ const resp = await client.getAllTopHoldings();
218
209
 
219
- expect(result).toEqual(mockTopHoldings);
220
- expect(result).toHaveLength(1);
221
- expect(result[0].symbol).toBe("AAPL");
222
- expect(result[0].politicians).toHaveLength(2);
223
- expect(result[0].count).toBe(2);
224
- });
210
+ expect(cli.request).toHaveBeenCalledTimes(1);
211
+ const call = cli.request.mock.calls[0][0];
225
212
 
226
- it("should handle errors when fetching top holdings", async () => {
227
- jest.spyOn(politicianClient, "getAllTopHoldings").mockRejectedValue(new Error("Failed to fetch top holdings"));
213
+ expect(call.method).toBe("GET");
214
+ expect(call.url).toBe("/api/v1/top-holding");
215
+ expect(call.params).toBeUndefined();
228
216
 
229
- await expect(politicianClient.getAllTopHoldings()).rejects.toThrow("Failed to fetch top holdings");
230
- });
217
+ expect(resp).toEqual(mockTopHoldings);
231
218
  });
232
219
 
233
- describe("getPoliticianDetail", () => {
234
- it("should return politician by ID successfully", async () => {
235
- jest.spyOn(politicianClient, "getPoliticianDetail").mockResolvedValue(mockPoliticianPortfolio);
220
+ test("getPoliticianDetail: calls correct endpoint and matches raw response", async () => {
221
+ cli.request.mockResolvedValueOnce({ data: mockPoliticianDetail });
236
222
 
237
- const result = await politicianClient.getPoliticianDetail(1);
223
+ const resp = await client.getPoliticianDetail(1);
238
224
 
239
- expect(result).toEqual(mockPoliticianPortfolio);
240
- expect(result.id).toBe(1);
241
- expect(result.name).toBe("John Doe");
242
- expect(result.holdings).toHaveLength(2);
243
- expect(result.totalHoldings).toBe(1000000);
244
- });
225
+ expect(cli.request).toHaveBeenCalledTimes(1);
226
+ const call = cli.request.mock.calls[0][0];
245
227
 
246
- it("should handle errors when fetching politician by ID", async () => {
247
- jest.spyOn(politicianClient, "getPoliticianDetail").mockRejectedValue(new Error("Failed to fetch politician"));
228
+ expect(call.method).toBe("GET");
229
+ expect(call.url).toBe("/api/v1/politician/1");
230
+ expect(call.params).toBeUndefined();
248
231
 
249
- await expect(politicianClient.getPoliticianDetail(999)).rejects.toThrow("Failed to fetch politician");
250
- });
232
+ expect(resp).toEqual(mockPoliticianDetail);
233
+ });
234
+
235
+ test("bubbles up request error", async () => {
236
+ cli.request.mockRejectedValueOnce(new Error("API Error"));
237
+
238
+ await expect(client.getAllPolitician()).rejects.toThrow("API Error");
239
+ expect(cli.request).toHaveBeenCalledTimes(1);
251
240
  });
252
241
  });
253
242
  });
@@ -282,9 +282,9 @@ describe("README Examples - Comprehensive Tests", () => {
282
282
  test("getTopMovers", async () => {
283
283
  const movers = await financialFundamentalsClient.getTopMovers(
284
284
  Region.Tr,
285
- 1,
286
285
  10,
287
286
  TopMoverDirection.Gainers,
287
+ 0,
288
288
  AssetType.Stock,
289
289
  AssetClass.Equity
290
290
  );
@@ -313,7 +313,7 @@ describe("README Examples - Comprehensive Tests", () => {
313
313
 
314
314
  describe("Brokers Client", () => {
315
315
  test("getBrokers", async () => {
316
- const brokers = await brokerClient.getBrokers(Region.Tr, 1, 10);
316
+ const brokers = await brokerClient.getBrokers(Region.Tr, 10, 1);
317
317
  expect(Array.isArray(brokers.items)).toBe(true);
318
318
  });
319
319
 
@@ -324,8 +324,8 @@ describe("README Examples - Comprehensive Tests", () => {
324
324
  SortDirection.Desc,
325
325
  "2024-01-01",
326
326
  "2024-01-31",
327
- 1,
328
- 10
327
+ 10,
328
+ 1
329
329
  );
330
330
  expect(Array.isArray(marketStocks.items)).toBe(true);
331
331
  });
@@ -338,8 +338,8 @@ describe("README Examples - Comprehensive Tests", () => {
338
338
  SortDirection.Desc,
339
339
  "2024-01-01",
340
340
  "2024-01-31",
341
- 1,
342
- 10
341
+ 10,
342
+ 1
343
343
  );
344
344
  expect(Array.isArray(brokersByStock.items)).toBe(true);
345
345
  });
@@ -350,8 +350,8 @@ describe("README Examples - Comprehensive Tests", () => {
350
350
  const results = await searchClient.search(
351
351
  "technology",
352
352
  [SearchType.Stock, SearchType.Collection],
353
- Region.Us,
354
- Locale.En
353
+ Locale.En,
354
+ Region.Us
355
355
  );
356
356
  expect(results).toBeDefined();
357
357
  });
@@ -368,9 +368,9 @@ describe("README Examples - Comprehensive Tests", () => {
368
368
  describe("Capital Increase Client", () => {
369
369
  test("getAllCapitalIncreases", async () => {
370
370
  const increases = await capitalIncreaseClient.getAllCapitalIncreases(
371
- 1,
372
371
  10,
373
- Region.Tr
372
+ Region.Tr,
373
+ 1
374
374
  );
375
375
  expect(Array.isArray(increases.items)).toBe(true);
376
376
  });
@@ -379,9 +379,9 @@ describe("README Examples - Comprehensive Tests", () => {
379
379
  const instrumentIncreases =
380
380
  await capitalIncreaseClient.getCapitalIncreasesForInstrument(
381
381
  "THYAO",
382
- 1,
383
382
  10,
384
- Region.Tr
383
+ Region.Tr,
384
+ 1
385
385
  );
386
386
  expect(Array.isArray(instrumentIncreases.items)).toBe(true);
387
387
  });
@@ -390,7 +390,6 @@ describe("README Examples - Comprehensive Tests", () => {
390
390
  const rights = await capitalIncreaseClient.getActiveRightsForInstrument(
391
391
  "THYAO",
392
392
  "2024-01-15",
393
- Region.Tr
394
393
  );
395
394
  expect(Array.isArray(rights)).toBe(true);
396
395
  });