laplace-api 4.8.0 → 5.2.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 +106 -107
- 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 +399 -169
- 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
package/src/test/search.test.ts
CHANGED
|
@@ -71,7 +71,6 @@ const mockAllTypesSearchResponse = {
|
|
|
71
71
|
{
|
|
72
72
|
id: "col123",
|
|
73
73
|
title: "Artificial Intelligence",
|
|
74
|
-
description: "AI focused companies",
|
|
75
74
|
region: [Region.Us],
|
|
76
75
|
assetClass: "equity",
|
|
77
76
|
imageUrl: "https://example.com/collection.jpg",
|
|
@@ -97,12 +96,7 @@ describe("Search", () => {
|
|
|
97
96
|
|
|
98
97
|
describe("Integration Tests", () => {
|
|
99
98
|
test("SearchStock", async () => {
|
|
100
|
-
const resp = await client.search(
|
|
101
|
-
"TUPRS",
|
|
102
|
-
[SearchType.Stock],
|
|
103
|
-
Region.Tr,
|
|
104
|
-
Locale.Tr
|
|
105
|
-
);
|
|
99
|
+
const resp = await client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr);
|
|
106
100
|
expect(resp.stocks).not.toBeEmpty();
|
|
107
101
|
|
|
108
102
|
const firstResult = resp.stocks[0];
|
|
@@ -115,12 +109,7 @@ describe("Search", () => {
|
|
|
115
109
|
});
|
|
116
110
|
|
|
117
111
|
test("SearchIndustry", async () => {
|
|
118
|
-
const resp = await client.search(
|
|
119
|
-
"Hava",
|
|
120
|
-
[SearchType.Industry],
|
|
121
|
-
Region.Tr,
|
|
122
|
-
Locale.Tr
|
|
123
|
-
);
|
|
112
|
+
const resp = await client.search("Hava", [SearchType.Industry], Locale.Tr, Region.Tr);
|
|
124
113
|
expect(resp.industries).not.toBeEmpty();
|
|
125
114
|
|
|
126
115
|
const firstResult = resp.industries[0];
|
|
@@ -128,9 +117,7 @@ describe("Search", () => {
|
|
|
128
117
|
expect(typeof firstResult.title).toBe("string");
|
|
129
118
|
expect(Array.isArray(firstResult.region)).toBe(true);
|
|
130
119
|
expect(firstResult.region.length).toBeGreaterThan(0);
|
|
131
|
-
firstResult.region.forEach((
|
|
132
|
-
expect(typeof region).toBe("string");
|
|
133
|
-
});
|
|
120
|
+
firstResult.region.forEach((r: string) => expect(typeof r).toBe("string"));
|
|
134
121
|
|
|
135
122
|
expect(typeof firstResult.assetClass).toBe("string");
|
|
136
123
|
expect(typeof firstResult.imageUrl).toBe("string");
|
|
@@ -140,19 +127,11 @@ describe("Search", () => {
|
|
|
140
127
|
test("SearchAllTypes", async () => {
|
|
141
128
|
const resp = await client.search(
|
|
142
129
|
"Ab",
|
|
143
|
-
[
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
SearchType.Sector,
|
|
147
|
-
SearchType.Collection,
|
|
148
|
-
],
|
|
149
|
-
Region.Us,
|
|
150
|
-
Locale.Tr
|
|
130
|
+
[SearchType.Stock, SearchType.Industry, SearchType.Sector, SearchType.Collection],
|
|
131
|
+
Locale.Tr,
|
|
132
|
+
Region.Us
|
|
151
133
|
);
|
|
152
134
|
|
|
153
|
-
expect(typeof resp).toBe("object");
|
|
154
|
-
expect(resp).not.toBeNull();
|
|
155
|
-
|
|
156
135
|
const hasResults =
|
|
157
136
|
(resp.stocks && resp.stocks.length > 0) ||
|
|
158
137
|
(resp.industries && resp.industries.length > 0) ||
|
|
@@ -160,168 +139,163 @@ describe("Search", () => {
|
|
|
160
139
|
(resp.collections && resp.collections.length > 0);
|
|
161
140
|
|
|
162
141
|
expect(hasResults).toBe(true);
|
|
163
|
-
|
|
164
|
-
if (resp.stocks) expect(Array.isArray(resp.stocks)).toBe(true);
|
|
165
|
-
if (resp.industries) expect(Array.isArray(resp.industries)).toBe(true);
|
|
166
|
-
if (resp.sectors) expect(Array.isArray(resp.sectors)).toBe(true);
|
|
167
|
-
if (resp.collections) expect(Array.isArray(resp.collections)).toBe(true);
|
|
168
142
|
});
|
|
169
143
|
});
|
|
170
144
|
|
|
171
|
-
describe("Mock Tests", () => {
|
|
145
|
+
describe("Mock Tests (Data Injection)", () => {
|
|
146
|
+
let client: SearchClient;
|
|
147
|
+
let cli: { request: jest.Mock };
|
|
148
|
+
|
|
172
149
|
beforeEach(() => {
|
|
173
|
-
jest.
|
|
150
|
+
cli = { request: jest.fn() };
|
|
151
|
+
|
|
152
|
+
const config = (global as any).testSuite.config as LaplaceConfiguration;
|
|
153
|
+
const logger: Logger = {
|
|
154
|
+
info: jest.fn(),
|
|
155
|
+
error: jest.fn(),
|
|
156
|
+
warn: jest.fn(),
|
|
157
|
+
debug: jest.fn(),
|
|
158
|
+
} as unknown as Logger;
|
|
159
|
+
|
|
160
|
+
client = new SearchClient(config, logger, cli as any);
|
|
174
161
|
});
|
|
175
162
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
Locale.Tr
|
|
206
|
-
);
|
|
207
|
-
});
|
|
163
|
+
function expectSearchCall(expected: {
|
|
164
|
+
filter: string;
|
|
165
|
+
types: SearchType[];
|
|
166
|
+
locale: Locale;
|
|
167
|
+
region?: Region;
|
|
168
|
+
page?: number;
|
|
169
|
+
size?: number;
|
|
170
|
+
}) {
|
|
171
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
172
|
+
const call = cli.request.mock.calls[0][0];
|
|
173
|
+
|
|
174
|
+
expect(call.method).toBe("GET");
|
|
175
|
+
expect(call.url).toBe("/api/v1/search");
|
|
176
|
+
|
|
177
|
+
const expectedParams: any = {
|
|
178
|
+
filter: expected.filter,
|
|
179
|
+
types: expected.types.join(","),
|
|
180
|
+
locale: expected.locale,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
if (expected.region != null) expectedParams.region = expected.region;
|
|
184
|
+
if (expected.page != null) expectedParams.page = expected.page;
|
|
185
|
+
if (expected.size != null) expectedParams.size = expected.size;
|
|
186
|
+
|
|
187
|
+
expect(call.params).toEqual(expectedParams);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
test("SearchStock: calls correct endpoint/params and matches raw response", async () => {
|
|
191
|
+
cli.request.mockResolvedValueOnce({ data: mockStockSearchResponse });
|
|
208
192
|
|
|
209
|
-
|
|
210
|
-
jest.spyOn(client, 'search').mockRejectedValue(new Error("Failed to search stocks"));
|
|
193
|
+
const resp = await client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr);
|
|
211
194
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
)).rejects.toThrow("Failed to search stocks");
|
|
195
|
+
expectSearchCall({
|
|
196
|
+
filter: "TUPRS",
|
|
197
|
+
types: [SearchType.Stock],
|
|
198
|
+
locale: Locale.Tr,
|
|
199
|
+
region: Region.Tr,
|
|
218
200
|
});
|
|
201
|
+
|
|
202
|
+
expect(resp.stocks).toHaveLength(1);
|
|
203
|
+
const first = resp.stocks[0];
|
|
204
|
+
expect(first.id).toBe(mockStockSearchResponse.stocks[0].id);
|
|
205
|
+
expect(first.name).toBe(mockStockSearchResponse.stocks[0].name);
|
|
206
|
+
expect(first.title).toBe(mockStockSearchResponse.stocks[0].title);
|
|
207
|
+
expect(first.region).toBe(mockStockSearchResponse.stocks[0].region);
|
|
208
|
+
expect(first.assetType).toBe(mockStockSearchResponse.stocks[0].assetType);
|
|
209
|
+
expect(first.type).toBe(mockStockSearchResponse.stocks[0].type);
|
|
210
|
+
|
|
211
|
+
expect(resp.industries).toHaveLength(0);
|
|
212
|
+
expect(resp.sectors).toHaveLength(0);
|
|
213
|
+
expect(resp.collections).toHaveLength(0);
|
|
219
214
|
});
|
|
220
215
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
expect(resp.industries).toHaveLength(1);
|
|
233
|
-
|
|
234
|
-
const firstResult = resp.industries[0];
|
|
235
|
-
expect(firstResult.id).toBe("ind123");
|
|
236
|
-
expect(firstResult.title).toBe("Hava Yolları Taşımacılığı");
|
|
237
|
-
expect(firstResult.region).toEqual([Region.Tr]);
|
|
238
|
-
expect(firstResult.assetClass).toBe("equity");
|
|
239
|
-
expect(firstResult.imageUrl).toBe("https://example.com/image.jpg");
|
|
240
|
-
expect(firstResult.avatarUrl).toBe("https://example.com/avatar.jpg");
|
|
241
|
-
|
|
242
|
-
expect(resp.stocks).toHaveLength(0);
|
|
243
|
-
expect(resp.sectors).toHaveLength(0);
|
|
244
|
-
expect(resp.collections).toHaveLength(0);
|
|
245
|
-
|
|
246
|
-
expect(client.search).toHaveBeenCalledWith(
|
|
247
|
-
"Hava",
|
|
248
|
-
[SearchType.Industry],
|
|
249
|
-
Region.Tr,
|
|
250
|
-
Locale.Tr
|
|
251
|
-
);
|
|
216
|
+
test("SearchIndustry: calls correct endpoint/params and matches raw response", async () => {
|
|
217
|
+
cli.request.mockResolvedValueOnce({ data: mockIndustrySearchResponse });
|
|
218
|
+
|
|
219
|
+
const resp = await client.search("Hava", [SearchType.Industry], Locale.Tr, Region.Tr);
|
|
220
|
+
|
|
221
|
+
expectSearchCall({
|
|
222
|
+
filter: "Hava",
|
|
223
|
+
types: [SearchType.Industry],
|
|
224
|
+
locale: Locale.Tr,
|
|
225
|
+
region: Region.Tr,
|
|
252
226
|
});
|
|
253
227
|
|
|
254
|
-
|
|
255
|
-
|
|
228
|
+
expect(resp.industries).toHaveLength(1);
|
|
229
|
+
const first = resp.industries[0];
|
|
230
|
+
expect(first.id).toBe(mockIndustrySearchResponse.industries[0].id);
|
|
231
|
+
expect(first.title).toBe(mockIndustrySearchResponse.industries[0].title);
|
|
232
|
+
expect(first.region).toEqual(mockIndustrySearchResponse.industries[0].region);
|
|
233
|
+
expect(first.assetClass).toBe(mockIndustrySearchResponse.industries[0].assetClass);
|
|
234
|
+
expect(first.imageUrl).toBe(mockIndustrySearchResponse.industries[0].imageUrl);
|
|
235
|
+
expect(first.avatarUrl).toBe(mockIndustrySearchResponse.industries[0].avatarUrl);
|
|
236
|
+
|
|
237
|
+
expect(resp.stocks).toHaveLength(0);
|
|
238
|
+
expect(resp.sectors).toHaveLength(0);
|
|
239
|
+
expect(resp.collections).toHaveLength(0);
|
|
240
|
+
});
|
|
256
241
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
242
|
+
test("SearchAllTypes: calls correct endpoint/params and matches raw response", async () => {
|
|
243
|
+
cli.request.mockResolvedValueOnce({ data: mockAllTypesSearchResponse });
|
|
244
|
+
|
|
245
|
+
const resp = await client.search(
|
|
246
|
+
"Ab",
|
|
247
|
+
[SearchType.Stock, SearchType.Industry, SearchType.Sector, SearchType.Collection],
|
|
248
|
+
Locale.Tr,
|
|
249
|
+
Region.Us
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
expectSearchCall({
|
|
253
|
+
filter: "Ab",
|
|
254
|
+
types: [SearchType.Stock, SearchType.Industry, SearchType.Sector, SearchType.Collection],
|
|
255
|
+
locale: Locale.Tr,
|
|
256
|
+
region: Region.Us,
|
|
263
257
|
});
|
|
258
|
+
|
|
259
|
+
expect(resp.stocks).toHaveLength(1);
|
|
260
|
+
expect(resp.industries).toHaveLength(1);
|
|
261
|
+
expect(resp.sectors).toHaveLength(1);
|
|
262
|
+
expect(resp.collections).toHaveLength(1);
|
|
264
263
|
});
|
|
265
264
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
SearchType.Sector,
|
|
276
|
-
SearchType.Collection,
|
|
277
|
-
],
|
|
278
|
-
Region.Us,
|
|
279
|
-
Locale.Tr
|
|
280
|
-
);
|
|
281
|
-
|
|
282
|
-
expect(resp.stocks).toHaveLength(1);
|
|
283
|
-
expect(resp.stocks[0].name).toBe("Abbott");
|
|
284
|
-
expect(resp.stocks[0].region).toBe(Region.Us);
|
|
285
|
-
|
|
286
|
-
expect(resp.industries).toHaveLength(1);
|
|
287
|
-
expect(resp.industries[0].title).toBe("Abrasive Manufacturing");
|
|
288
|
-
expect(resp.industries[0].region).toEqual([Region.Us]);
|
|
289
|
-
|
|
290
|
-
expect(resp.sectors).toHaveLength(1);
|
|
291
|
-
expect(resp.sectors[0].title).toBe("Aerospace & Defense");
|
|
292
|
-
expect(resp.sectors[0].region).toEqual([Region.Us]);
|
|
293
|
-
|
|
294
|
-
expect(resp.collections).toHaveLength(1);
|
|
295
|
-
expect(resp.collections[0].title).toBe("Artificial Intelligence");
|
|
296
|
-
expect(resp.collections[0].region).toEqual([Region.Us]);
|
|
297
|
-
|
|
298
|
-
expect(client.search).toHaveBeenCalledWith(
|
|
299
|
-
"Ab",
|
|
300
|
-
[
|
|
301
|
-
SearchType.Stock,
|
|
302
|
-
SearchType.Industry,
|
|
303
|
-
SearchType.Sector,
|
|
304
|
-
SearchType.Collection,
|
|
305
|
-
],
|
|
306
|
-
Region.Us,
|
|
307
|
-
Locale.Tr
|
|
308
|
-
);
|
|
265
|
+
test("does not send optional params when undefined", async () => {
|
|
266
|
+
cli.request.mockResolvedValueOnce({ data: mockStockSearchResponse });
|
|
267
|
+
|
|
268
|
+
await client.search("TUPRS", [SearchType.Stock], Locale.Tr);
|
|
269
|
+
|
|
270
|
+
expectSearchCall({
|
|
271
|
+
filter: "TUPRS",
|
|
272
|
+
types: [SearchType.Stock],
|
|
273
|
+
locale: Locale.Tr,
|
|
309
274
|
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test("bubbles up request error", async () => {
|
|
278
|
+
cli.request.mockRejectedValueOnce(new Error("Failed to search"));
|
|
279
|
+
|
|
280
|
+
await expect(client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr)).rejects.toThrow(
|
|
281
|
+
"Failed to search"
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test("page=0 / size=0 should still be sent (guards against falsy spread bug)", async () => {
|
|
288
|
+
cli.request.mockResolvedValueOnce({ data: mockStockSearchResponse });
|
|
289
|
+
|
|
290
|
+
await client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr, 0, 10);
|
|
310
291
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
SearchType.Industry,
|
|
319
|
-
SearchType.Sector,
|
|
320
|
-
SearchType.Collection,
|
|
321
|
-
],
|
|
322
|
-
Region.Us,
|
|
323
|
-
Locale.Tr
|
|
324
|
-
)).rejects.toThrow("Failed to search all types");
|
|
292
|
+
expectSearchCall({
|
|
293
|
+
filter: "TUPRS",
|
|
294
|
+
types: [SearchType.Stock],
|
|
295
|
+
locale: Locale.Tr,
|
|
296
|
+
region: Region.Tr,
|
|
297
|
+
page: 0,
|
|
298
|
+
size: 10,
|
|
325
299
|
});
|
|
326
300
|
});
|
|
327
301
|
});
|