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.
- package/package.json +1 -1
- package/src/client/broker.ts +17 -17
- package/src/client/capital_increase.ts +9 -10
- package/src/client/client.ts +40 -40
- package/src/client/collections.ts +26 -14
- package/src/client/custom_theme.ts +15 -14
- package/src/client/financial_fundamentals.ts +29 -27
- package/src/client/financial_ratios.ts +29 -47
- package/src/client/funds.ts +10 -5
- package/src/client/key-insights.ts +1 -1
- package/src/client/live-price-web-socket.ts +3 -1
- package/src/client/live-price.ts +18 -44
- package/src/client/news.ts +40 -56
- package/src/client/search.ts +13 -9
- package/src/client/stocks.ts +42 -12
- package/src/test/broker.test.ts +580 -453
- package/src/test/capital_increase.test.ts +131 -82
- package/src/test/collections.test.ts +489 -268
- package/src/test/custom_theme.test.ts +250 -144
- package/src/test/financial_fundamentals.test.ts +171 -202
- package/src/test/financial_ratios.test.ts +222 -170
- package/src/test/funds.test.ts +231 -162
- package/src/test/helpers.ts +23 -27
- package/src/test/key-insight.test.ts +71 -36
- package/src/test/live-price.test.ts +135 -1
- package/src/test/news.test.ts +320 -177
- package/src/test/politician.test.ts +176 -187
- package/src/test/readme.test.ts +12 -13
- package/src/test/search.test.ts +144 -170
- package/src/test/stocks.test.ts +306 -370
- package/src/utilities/test.env +0 -2
|
@@ -9,65 +9,63 @@ import {
|
|
|
9
9
|
import { Stock, StockClient } from "../client/stocks";
|
|
10
10
|
import "./client_test_suite";
|
|
11
11
|
import { validateCollection } from "./helpers";
|
|
12
|
-
import { Locale, Region, SortBy,
|
|
13
|
-
import { AssetType } from "../client/stocks";
|
|
12
|
+
import { Locale, Region, SortBy, CollectionType } from "../client/collections";
|
|
14
13
|
|
|
15
|
-
const
|
|
14
|
+
const mockCustomThemes = [
|
|
16
15
|
{
|
|
17
|
-
id: "
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
assetType: AssetType.Stock,
|
|
31
|
-
sectorId: "sector2",
|
|
32
|
-
industryId: "industry2",
|
|
33
|
-
updatedDate: "2024-03-14T10:00:00Z",
|
|
34
|
-
active: true
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: "stock3",
|
|
38
|
-
name: "Türk Hava Yolları",
|
|
39
|
-
symbol: "THYAO",
|
|
40
|
-
assetType: AssetType.Stock,
|
|
41
|
-
sectorId: "sector3",
|
|
42
|
-
industryId: "industry3",
|
|
43
|
-
updatedDate: "2024-03-14T10:00:00Z",
|
|
44
|
-
active: true
|
|
16
|
+
"id": "6888e18a6c84bcba9dc69ef7",
|
|
17
|
+
"title": "Test Custom Theme",
|
|
18
|
+
"region": [
|
|
19
|
+
"tr"
|
|
20
|
+
],
|
|
21
|
+
"imageUrl": "Test Custom Theme Image URL",
|
|
22
|
+
"avatarUrl": "Test Custom Theme Avatar Image",
|
|
23
|
+
"numStocks": 2,
|
|
24
|
+
"assetClass": "equity",
|
|
25
|
+
"description": "Test Custom Theme Description",
|
|
26
|
+
"image": "Test Custom Theme Image",
|
|
27
|
+
"order": 0,
|
|
28
|
+
"status": "active"
|
|
45
29
|
}
|
|
46
30
|
];
|
|
47
31
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
32
|
+
const mockCustomThemeDetail = {
|
|
33
|
+
"id": "6888e18a6c84bcba9dc69ef7",
|
|
34
|
+
"title": "Test Custom Theme",
|
|
35
|
+
"region": [
|
|
36
|
+
"tr"
|
|
37
|
+
],
|
|
38
|
+
"imageUrl": "Test Custom Theme Image URL",
|
|
39
|
+
"avatarUrl": "Test Custom Theme Avatar Image",
|
|
40
|
+
"numStocks": 2,
|
|
41
|
+
"assetClass": "equity",
|
|
42
|
+
"description": "Test Custom Theme Description",
|
|
43
|
+
"image": "Test Custom Theme Image",
|
|
44
|
+
"order": 0,
|
|
45
|
+
"status": "active",
|
|
46
|
+
"stocks": [
|
|
47
|
+
{
|
|
48
|
+
"id": "648ab66e38daf3102a5a7401",
|
|
49
|
+
"assetType": "stock",
|
|
50
|
+
"name": "A1 Capital Yatırım Menkul Değerler",
|
|
51
|
+
"symbol": "A1CAP",
|
|
52
|
+
"sectorId": "65533e047844ee7afe9941bc",
|
|
53
|
+
"industryId": "65533e441fa5c7b58afa0955",
|
|
54
|
+
"updatedDate": "2025-04-01T00:00:00.533Z",
|
|
55
|
+
"active": true
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "61dd0da80ec21141463430cf",
|
|
59
|
+
"assetType": "stock",
|
|
60
|
+
"name": "A1 Yenilenebilir Enerji",
|
|
61
|
+
"symbol": "A1YEN",
|
|
62
|
+
"sectorId": "65533e047844ee7afe9941c2",
|
|
63
|
+
"industryId": "65533e441fa5c7b58afa0985",
|
|
64
|
+
"updatedDate": "2025-07-28T09:06:04.286Z",
|
|
65
|
+
"active": true
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"locale": "tr"
|
|
71
69
|
};
|
|
72
70
|
|
|
73
71
|
describe("CustomTheme", () => {
|
|
@@ -153,124 +151,232 @@ describe("CustomTheme", () => {
|
|
|
153
151
|
});
|
|
154
152
|
|
|
155
153
|
describe("Mock Tests", () => {
|
|
154
|
+
const locale = Locale.Tr;
|
|
155
|
+
|
|
156
|
+
let client: CustomThemeClient;
|
|
157
|
+
let cli: { request: jest.Mock };
|
|
158
|
+
|
|
156
159
|
beforeEach(() => {
|
|
157
|
-
jest.
|
|
160
|
+
cli = { request: jest.fn() };
|
|
161
|
+
|
|
162
|
+
const config = (global as any).testSuite.config as LaplaceConfiguration;
|
|
163
|
+
const logger: Logger = {
|
|
164
|
+
info: jest.fn(),
|
|
165
|
+
error: jest.fn(),
|
|
166
|
+
warn: jest.fn(),
|
|
167
|
+
debug: jest.fn(),
|
|
168
|
+
} as unknown as Logger;
|
|
169
|
+
|
|
170
|
+
client = new CustomThemeClient(config, logger, cli as any);
|
|
158
171
|
});
|
|
159
|
-
|
|
172
|
+
|
|
160
173
|
describe("getAllCustomThemes", () => {
|
|
161
|
-
test("should
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const resp = await client.getAllCustomThemes(
|
|
165
|
-
|
|
174
|
+
test("should call correct endpoint/params and return list (check all fields)", async () => {
|
|
175
|
+
cli.request.mockResolvedValueOnce({ data: mockCustomThemes });
|
|
176
|
+
|
|
177
|
+
const resp = await client.getAllCustomThemes(locale);
|
|
178
|
+
|
|
179
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
180
|
+
const call = cli.request.mock.calls[0][0];
|
|
181
|
+
expect(call.method).toBe("GET");
|
|
182
|
+
expect(call.url).toBe(`/api/v1/${CollectionType.CustomTheme}`);
|
|
183
|
+
expect(call.params).toEqual({ locale });
|
|
184
|
+
|
|
185
|
+
expect(Array.isArray(resp)).toBe(true);
|
|
166
186
|
expect(resp).toHaveLength(1);
|
|
167
|
-
|
|
187
|
+
|
|
168
188
|
const theme = resp[0];
|
|
169
|
-
|
|
170
|
-
expect(theme.
|
|
171
|
-
expect(theme.
|
|
172
|
-
expect(theme.region).toEqual([
|
|
173
|
-
expect(theme.imageUrl).toBe("
|
|
174
|
-
expect(theme.avatarUrl).toBe("
|
|
175
|
-
expect(theme.numStocks).toBe(
|
|
176
|
-
expect(theme.
|
|
177
|
-
|
|
178
|
-
expect(
|
|
189
|
+
|
|
190
|
+
expect(theme.id).toBe("6888e18a6c84bcba9dc69ef7");
|
|
191
|
+
expect(theme.title).toBe("Test Custom Theme");
|
|
192
|
+
expect(theme.region).toEqual(["tr"]);
|
|
193
|
+
expect(theme.imageUrl).toBe("Test Custom Theme Image URL");
|
|
194
|
+
expect(theme.avatarUrl).toBe("Test Custom Theme Avatar Image");
|
|
195
|
+
expect(theme.numStocks).toBe(2);
|
|
196
|
+
expect(theme.assetClass).toBe("equity");
|
|
197
|
+
expect(theme.description).toBe("Test Custom Theme Description");
|
|
198
|
+
expect(theme.image).toBe("Test Custom Theme Image");
|
|
199
|
+
expect(theme.order).toBe(0);
|
|
200
|
+
expect(theme.status).toBe("active");
|
|
179
201
|
});
|
|
180
202
|
});
|
|
181
|
-
|
|
203
|
+
|
|
182
204
|
describe("getCustomThemeDetail", () => {
|
|
183
|
-
test("should
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const resp = await client.getCustomThemeDetail(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
expect(
|
|
193
|
-
|
|
205
|
+
test("should call correct endpoint/params and return detail (check all fields)", async () => {
|
|
206
|
+
cli.request.mockResolvedValueOnce({ data: mockCustomThemeDetail });
|
|
207
|
+
|
|
208
|
+
const resp = await client.getCustomThemeDetail(
|
|
209
|
+
"6888e18a6c84bcba9dc69ef7",
|
|
210
|
+
locale,
|
|
211
|
+
null
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
215
|
+
const call = cli.request.mock.calls[0][0];
|
|
216
|
+
expect(call.method).toBe("GET");
|
|
217
|
+
expect(call.url).toBe(
|
|
218
|
+
`/api/v1/${CollectionType.CustomTheme}/6888e18a6c84bcba9dc69ef7`
|
|
219
|
+
);
|
|
220
|
+
expect(call.params).toEqual({ locale });
|
|
221
|
+
|
|
222
|
+
expect(resp.id).toBe("6888e18a6c84bcba9dc69ef7");
|
|
223
|
+
expect(resp.title).toBe("Test Custom Theme");
|
|
224
|
+
expect(resp.region).toEqual(["tr"]);
|
|
225
|
+
expect(resp.imageUrl).toBe("Test Custom Theme Image URL");
|
|
226
|
+
expect(resp.avatarUrl).toBe("Test Custom Theme Avatar Image");
|
|
194
227
|
expect(resp.numStocks).toBe(2);
|
|
195
|
-
expect(resp.
|
|
228
|
+
expect(resp.assetClass).toBe("equity");
|
|
229
|
+
expect(resp.description).toBe("Test Custom Theme Description");
|
|
230
|
+
expect(resp.image).toBe("Test Custom Theme Image");
|
|
231
|
+
expect(resp.order).toBe(0);
|
|
232
|
+
expect(resp.status).toBe("active");
|
|
233
|
+
expect(resp.locale).toBe("tr");
|
|
234
|
+
|
|
235
|
+
expect(Array.isArray(resp.stocks)).toBe(true);
|
|
196
236
|
expect(resp.stocks).toHaveLength(2);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
expect(
|
|
237
|
+
|
|
238
|
+
const s0 = resp.stocks[0];
|
|
239
|
+
expect(s0.id).toBe("648ab66e38daf3102a5a7401");
|
|
240
|
+
expect(s0.assetType).toBe("stock");
|
|
241
|
+
expect(s0.name).toBe("A1 Capital Yatırım Menkul Değerler");
|
|
242
|
+
expect(s0.symbol).toBe("A1CAP");
|
|
243
|
+
expect(s0.sectorId).toBe("65533e047844ee7afe9941bc");
|
|
244
|
+
expect(s0.industryId).toBe("65533e441fa5c7b58afa0955");
|
|
245
|
+
expect(s0.updatedDate).toBe("2025-04-01T00:00:00.533Z");
|
|
246
|
+
expect(s0.active).toBe(true);
|
|
247
|
+
|
|
248
|
+
const s1 = resp.stocks[1];
|
|
249
|
+
expect(s1.id).toBe("61dd0da80ec21141463430cf");
|
|
250
|
+
expect(s1.assetType).toBe("stock");
|
|
251
|
+
expect(s1.name).toBe("A1 Yenilenebilir Enerji");
|
|
252
|
+
expect(s1.symbol).toBe("A1YEN");
|
|
253
|
+
expect(s1.sectorId).toBe("65533e047844ee7afe9941c2");
|
|
254
|
+
expect(s1.industryId).toBe("65533e441fa5c7b58afa0985");
|
|
255
|
+
expect(s1.updatedDate).toBe("2025-07-28T09:06:04.286Z");
|
|
256
|
+
expect(s1.active).toBe(true);
|
|
201
257
|
});
|
|
202
|
-
|
|
203
|
-
test("should
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
await client.getCustomThemeDetail(
|
|
207
|
-
|
|
208
|
-
|
|
258
|
+
|
|
259
|
+
test("should include sortBy when provided", async () => {
|
|
260
|
+
cli.request.mockResolvedValueOnce({ data: mockCustomThemeDetail });
|
|
261
|
+
|
|
262
|
+
await client.getCustomThemeDetail(
|
|
263
|
+
"6888e18a6c84bcba9dc69ef7",
|
|
264
|
+
locale,
|
|
265
|
+
SortBy.PriceChange
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
269
|
+
const call = cli.request.mock.calls[0][0];
|
|
270
|
+
|
|
271
|
+
expect(call.method).toBe("GET");
|
|
272
|
+
expect(call.url).toBe(
|
|
273
|
+
`/api/v1/${CollectionType.CustomTheme}/6888e18a6c84bcba9dc69ef7`
|
|
274
|
+
);
|
|
275
|
+
expect(call.params).toEqual({ locale, sortBy: SortBy.PriceChange });
|
|
209
276
|
});
|
|
210
277
|
});
|
|
211
|
-
|
|
212
278
|
describe("createCustomTheme", () => {
|
|
213
|
-
test("should
|
|
279
|
+
test("should call correct endpoint/body and return id", async () => {
|
|
214
280
|
const createParams: CreateCustomThemeParams = {
|
|
215
|
-
title: {
|
|
216
|
-
|
|
217
|
-
[Locale.En]: "New Theme"
|
|
218
|
-
},
|
|
219
|
-
description: {
|
|
220
|
-
[Locale.Tr]: "Tema açıklaması",
|
|
221
|
-
[Locale.En]: "Theme description"
|
|
222
|
-
},
|
|
281
|
+
title: { [Locale.Tr]: "Test Custom Theme" },
|
|
282
|
+
description: { [Locale.Tr]: "Test Custom Theme Description" },
|
|
223
283
|
region: [Region.Tr],
|
|
224
|
-
image_url: "
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
284
|
+
image_url: "Test Custom Theme Image URL",
|
|
285
|
+
image: "Test Custom Theme Image",
|
|
286
|
+
avatar_url: "Test Custom Theme Avatar Image",
|
|
287
|
+
stocks: [
|
|
288
|
+
"648ab66e38daf3102a5a7401",
|
|
289
|
+
"61dd0da80ec21141463430cf",
|
|
290
|
+
],
|
|
291
|
+
order: 0,
|
|
292
|
+
status: CollectionStatus.Active,
|
|
293
|
+
meta_data: { foo: "bar" },
|
|
228
294
|
};
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
expect(
|
|
235
|
-
|
|
236
|
-
|
|
295
|
+
|
|
296
|
+
cli.request.mockResolvedValueOnce({ data: { id: "6888e18a6c84bcba9dc69ef7" } });
|
|
297
|
+
|
|
298
|
+
const id = await client.createCustomTheme(createParams);
|
|
299
|
+
|
|
300
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
301
|
+
const call = cli.request.mock.calls[0][0];
|
|
302
|
+
|
|
303
|
+
expect(call.method).toBe("POST");
|
|
304
|
+
expect(call.url).toBe("/api/v1/custom-theme");
|
|
305
|
+
expect(call.data).toEqual(createParams);
|
|
306
|
+
|
|
307
|
+
expect(id).toBe("6888e18a6c84bcba9dc69ef7");
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test("should bubble up request error", async () => {
|
|
311
|
+
const createParams: CreateCustomThemeParams = {
|
|
312
|
+
title: { [Locale.Tr]: "Test Custom Theme" },
|
|
313
|
+
stocks: ["648ab66e38daf3102a5a7401"],
|
|
314
|
+
status: CollectionStatus.Active,
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
cli.request.mockRejectedValueOnce(new Error("Validation error"));
|
|
318
|
+
|
|
319
|
+
await expect(client.createCustomTheme(createParams)).rejects.toThrow("Validation error");
|
|
237
320
|
});
|
|
238
321
|
});
|
|
239
|
-
|
|
322
|
+
|
|
240
323
|
describe("updateCustomTheme", () => {
|
|
241
|
-
test("should
|
|
324
|
+
test("should call correct endpoint/body (stockIds) and resolve", async () => {
|
|
242
325
|
const updateParams: UpdateCustomThemeParams = {
|
|
243
|
-
title: {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
326
|
+
title: { [Locale.Tr]: "Test Custom Theme Title Updated" },
|
|
327
|
+
description: { [Locale.Tr]: "Test Custom Theme Description Updated" },
|
|
328
|
+
image_url: "Test Custom Theme Image URL Updated",
|
|
329
|
+
image: "Test Custom Theme Image Updated",
|
|
330
|
+
avatar_url: "Test Custom Theme Avatar Image Updated",
|
|
331
|
+
stockIds: [
|
|
332
|
+
"648ab66e38daf3102a5a7401",
|
|
333
|
+
"61dd0da80ec21141463430cf",
|
|
334
|
+
],
|
|
335
|
+
status: CollectionStatus.Inactive,
|
|
336
|
+
meta_data: { hello: "world" },
|
|
248
337
|
};
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
await client.updateCustomTheme("
|
|
253
|
-
|
|
254
|
-
expect(
|
|
338
|
+
|
|
339
|
+
cli.request.mockResolvedValueOnce({ data: undefined });
|
|
340
|
+
|
|
341
|
+
await client.updateCustomTheme("6888e18a6c84bcba9dc69ef7", updateParams);
|
|
342
|
+
|
|
343
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
344
|
+
const call = cli.request.mock.calls[0][0];
|
|
345
|
+
|
|
346
|
+
expect(call.method).toBe("PATCH");
|
|
347
|
+
expect(call.url).toBe("/api/v1/custom-theme/6888e18a6c84bcba9dc69ef7");
|
|
348
|
+
expect(call.data).toEqual(updateParams);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test("should bubble up request error", async () => {
|
|
352
|
+
cli.request.mockRejectedValueOnce(new Error("Theme not found"));
|
|
353
|
+
|
|
354
|
+
await expect(
|
|
355
|
+
client.updateCustomTheme("invalid-theme", { status: CollectionStatus.Active })
|
|
356
|
+
).rejects.toThrow("Theme not found");
|
|
255
357
|
});
|
|
256
358
|
});
|
|
257
|
-
|
|
359
|
+
|
|
258
360
|
describe("deleteCustomTheme", () => {
|
|
259
|
-
test("should
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
await client.deleteCustomTheme("
|
|
263
|
-
|
|
264
|
-
expect(
|
|
361
|
+
test("should call correct endpoint and resolve", async () => {
|
|
362
|
+
cli.request.mockResolvedValueOnce({ data: undefined });
|
|
363
|
+
|
|
364
|
+
await client.deleteCustomTheme("6888e18a6c84bcba9dc69ef7");
|
|
365
|
+
|
|
366
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
367
|
+
const call = cli.request.mock.calls[0][0];
|
|
368
|
+
|
|
369
|
+
expect(call.method).toBe("DELETE");
|
|
370
|
+
expect(call.url).toBe("/api/v1/custom-theme/6888e18a6c84bcba9dc69ef7");
|
|
265
371
|
});
|
|
266
|
-
|
|
267
|
-
test("should
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
await expect(client.deleteCustomTheme("invalid-theme"))
|
|
271
|
-
.rejects.toThrow("Theme not found");
|
|
372
|
+
|
|
373
|
+
test("should bubble up request error", async () => {
|
|
374
|
+
cli.request.mockRejectedValueOnce(new Error("Theme not found"));
|
|
375
|
+
|
|
376
|
+
await expect(client.deleteCustomTheme("invalid-theme")).rejects.toThrow("Theme not found");
|
|
272
377
|
});
|
|
273
378
|
});
|
|
379
|
+
|
|
274
380
|
});
|
|
275
381
|
});
|
|
276
382
|
|