laplace-api 3.1.0 → 4.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,6 +1,5 @@
1
1
  import { Logger } from "winston";
2
2
  import { LaplaceConfiguration } from "../utilities/configuration";
3
- import { Client, createClient } from "../client/client";
4
3
  import {
5
4
  FinancialClient,
6
5
  HistoricalRatiosKey,
@@ -8,12 +7,99 @@ import {
8
7
  FinancialSheetPeriod,
9
8
  Currency,
10
9
  HistoricalFinancialSheetRow,
10
+ RatioComparisonPeerType,
11
+ StockPeerFinancialRatioComparison,
12
+ StockHistoricalRatios,
13
+ HistoricalRatiosFormat,
14
+ StockHistoricalRatiosDescription,
15
+ HistoricalFinancialSheets
11
16
  } from "../client/financial_ratios";
12
- import { Region, Locale } from "../client/collections";
13
17
  import "./client_test_suite";
14
18
  import { equal } from "assert";
19
+ import { Locale, Region } from "../client/collections";
15
20
 
16
- describe('FinancialRatios', () => {
21
+ const mockRatioComparisonResponse: StockPeerFinancialRatioComparison[] = [
22
+ {
23
+ metricName: "Net Kar Marjı",
24
+ normalizedValue: 0.85,
25
+ data: [
26
+ {
27
+ slug: "TUPRS",
28
+ value: 12.5,
29
+ average: 8.2
30
+ },
31
+ {
32
+ slug: "SECTOR_AVERAGE",
33
+ value: 7.8,
34
+ average: 8.2
35
+ }
36
+ ]
37
+ }
38
+ ];
39
+
40
+ const mockHistoricalRatiosResponse: StockHistoricalRatios[] = [
41
+ {
42
+ slug: HistoricalRatiosKey.NetMargin,
43
+ finalValue: 12.5,
44
+ threeYearGrowth: 15.2,
45
+ yearGrowth: 5.8,
46
+ finalSectorValue: 7.8,
47
+ currency: Currency.TRY,
48
+ format: HistoricalRatiosFormat.PERCENTAGE,
49
+ name: "Net Kar Marjı",
50
+ items: [
51
+ {
52
+ period: "2024-Q1",
53
+ value: 12.5,
54
+ sectorMean: 7.8
55
+ },
56
+ {
57
+ period: "2023-Q4",
58
+ value: 11.8,
59
+ sectorMean: 7.5
60
+ }
61
+ ]
62
+ }
63
+ ];
64
+
65
+ const mockRatiosDescriptionsResponse: StockHistoricalRatiosDescription[] = [
66
+ {
67
+ id: 1,
68
+ format: HistoricalRatiosFormat.PERCENTAGE,
69
+ currency: Currency.TRY,
70
+ slug: HistoricalRatiosKey.NetMargin,
71
+ createdAt: "2024-03-14T10:00:00Z",
72
+ updatedAt: "2024-03-14T10:00:00Z",
73
+ name: "Net Kar Marjı",
74
+ description: "Net karın satışlara oranı",
75
+ locale: Locale.Tr,
76
+ isRealtime: false
77
+ }
78
+ ];
79
+
80
+ const mockFinancialSheetsResponse: HistoricalFinancialSheets = {
81
+ sheets: [
82
+ {
83
+ period: "2024-Q1",
84
+ items: [
85
+ {
86
+ description: "Satış Gelirleri",
87
+ value: 50000000000,
88
+ lineCodeId: 1,
89
+ indentLevel: 0
90
+ },
91
+ {
92
+ description: "Satışların Maliyeti",
93
+ value: -40000000000,
94
+ lineCodeId: 2,
95
+ indentLevel: 0
96
+ }
97
+ ]
98
+ }
99
+ ]
100
+ };
101
+
102
+ describe("FinancialRatios", () => {
17
103
  let financialClient: FinancialClient;
18
104
 
19
105
  beforeAll(() => {
@@ -28,82 +114,297 @@ describe('FinancialRatios', () => {
28
114
  financialClient = new FinancialClient(config, logger);
29
115
  });
30
116
 
31
- test('GetFinancialRatioComparison', async () => {
32
- const resp = await financialClient.getFinancialRatioComparison('TUPRS', Region.Tr);
33
- expect(resp).not.toBeEmpty();
34
- });
117
+ describe("Integration Tests", () => {
118
+ test("GetFinancialRatioComparison", async () => {
119
+ const resp = await financialClient.getFinancialRatioComparison(
120
+ "TUPRS",
121
+ Region.Tr,
122
+ RatioComparisonPeerType.Sector
123
+ );
124
+ expect(resp).not.toBeEmpty();
35
125
 
36
- test("GetHistoricalRatios", async () => {
37
- const resp = await financialClient.getHistoricalRatios(
38
- "TUPRS",
39
- Object.values(HistoricalRatiosKey).flat(),
40
- Region.Tr,
41
- Locale.Tr
42
- );
43
- expect(resp).not.toBeEmpty();
44
- for (const ratio of resp) {
45
- expect(typeof ratio.finalValue).toBe("number");
46
- expect(typeof ratio.threeYearGrowth).toBe("number");
47
- expect(typeof ratio.yearGrowth).toBe("number");
48
- expect(typeof ratio.finalSectorValue).toBe("number");
49
- expect(equal(ratio.currency, Currency.TRY));
50
- expect(typeof ratio.format).toBe("string");
51
- expect(typeof ratio.name).toBe("string");
52
- expect(ratio.items).not.toBeEmpty();
53
- expect(ratio.items.at(0)).toBeTruthy();
54
- expect(typeof ratio.items.at(0)?.period).toBe("string");
55
- expect(typeof ratio.items.at(0)?.sectorMean).toBe("number");
56
- expect(typeof ratio.items.at(0)?.value).toBe("number");
57
- }
58
- });
126
+ const comparison = resp[0];
127
+ expect(typeof comparison.metricName).toBe("string");
128
+ expect(typeof comparison.normalizedValue).toBe("number");
129
+
130
+ const comparisonData = comparison.data;
131
+ expect(Array.isArray(comparisonData)).toBe(true);
132
+ expect(comparisonData).not.toBeEmpty();
133
+ expect(typeof comparisonData[0].slug).toBe("string");
134
+ expect(typeof comparisonData[0].value).toBe("number");
135
+ expect(typeof comparisonData[0].average).toBe("number");
136
+ });
137
+
138
+ describe("GetHistoricalRatios", () => {
139
+ test("GetHistoricalRatios", async () => {
140
+ const resp = await financialClient.getHistoricalRatios(
141
+ "TUPRS",
142
+ Object.values(HistoricalRatiosKey).flat(),
143
+ Region.Tr,
144
+ Locale.Tr
145
+ );
146
+ expect(resp).not.toBeEmpty();
147
+
148
+ const firstRatio = resp[0];
149
+ expect(typeof firstRatio.finalValue).toBe("number");
150
+ expect(typeof firstRatio.threeYearGrowth).toBe("number");
151
+ expect(typeof firstRatio.yearGrowth).toBe("number");
152
+ expect(typeof firstRatio.finalSectorValue).toBe("number");
153
+ expect(equal(firstRatio.currency, Currency.TRY));
154
+ expect(typeof firstRatio.format).toBe("string");
155
+ expect(typeof firstRatio.name).toBe("string");
156
+
157
+ expect(firstRatio.items).not.toBeEmpty();
158
+ const firstItem = firstRatio.items[0];
159
+ expect(typeof firstItem.period).toBe("string");
160
+ expect(typeof firstItem.sectorMean).toBe("number");
161
+ expect(typeof firstItem.value).toBe("number");
162
+ });
163
+ });
59
164
 
60
- test("GetHistoricalRatiosDescriptions", async () => {
61
- const resp = await financialClient.getHistoricalRatiosDescriptions(
62
- Locale.Tr,
63
- Region.Tr
64
- );
65
- expect(resp).not.toBeEmpty();
165
+ describe("GetHistoricalRatiosDescriptions", () => {
166
+ test("GetHistoricalRatiosDescriptions", async () => {
167
+ const resp = await financialClient.getHistoricalRatiosDescriptions(
168
+ Locale.Tr,
169
+ Region.Tr
170
+ );
171
+ expect(resp).not.toBeEmpty();
172
+
173
+ const firstDescription = resp[0];
174
+ expect(typeof firstDescription.id).toBe("number");
175
+ expect(typeof firstDescription.format).toBe("string");
176
+ expect(typeof firstDescription.currency).toBe("string");
177
+ expect(typeof firstDescription.slug).toBe("string");
178
+ expect(typeof firstDescription.createdAt).toBe("string");
179
+ expect(typeof firstDescription.updatedAt).toBe("string");
180
+ expect(typeof firstDescription.name).toBe("string");
181
+ expect(typeof firstDescription.description).toBe("string");
182
+ expect(typeof firstDescription.locale).toBe("string");
183
+ expect(typeof firstDescription.isRealtime).toBe("boolean");
184
+ });
185
+ });
186
+
187
+ test("GetHistoricalFinancialSheets", async () => {
188
+ try {
189
+ await financialClient.getHistoricalFinancialSheets(
190
+ "TUPRS",
191
+ { year: 2022, month: 1, day: 1 },
192
+ { year: 2025, month: 1, day: 1 },
193
+ FinancialSheetType.BalanceSheet,
194
+ FinancialSheetPeriod.Annual,
195
+ Currency.TRY,
196
+ Region.Tr
197
+ );
198
+ } catch (error) {
199
+ expect((error as Error).message).toContain(
200
+ "balance sheet is only available for cumulative period"
201
+ );
202
+ }
203
+
204
+ const resp = await financialClient.getHistoricalFinancialSheets(
205
+ "TUPRS",
206
+ { year: 2022, month: 1, day: 1 },
207
+ { year: 2025, month: 1, day: 1 },
208
+ FinancialSheetType.CashFlow,
209
+ FinancialSheetPeriod.Quarterly,
210
+ Currency.TRY,
211
+ Region.Tr
212
+ );
213
+
214
+ expect(resp).toBeDefined();
215
+ expect(resp).not.toBeNull();
216
+ expect(resp).not.toBeEmpty();
217
+
218
+ expect(resp.sheets).toBeDefined();
219
+ expect(Array.isArray(resp.sheets)).toBe(true);
220
+ expect(resp.sheets.length).toBeGreaterThan(0);
221
+
222
+ const firstSheet = resp.sheets[0];
223
+ expect(firstSheet).toBeDefined();
224
+
225
+ expect(firstSheet.period).toBeDefined();
226
+ expect(typeof firstSheet.period).toBe("string");
227
+
228
+ expect(firstSheet.items).toBeDefined();
229
+ expect(Array.isArray(firstSheet.items)).toBe(true);
230
+ expect(firstSheet.items.length).toBeGreaterThan(0);
231
+
232
+ const firstRow = firstSheet.items[0];
233
+ expect(firstRow).toBeDefined();
234
+
235
+ expect(firstRow).toMatchObject<HistoricalFinancialSheetRow>({
236
+ description: expect.any(String),
237
+ value: expect.any(Number),
238
+ lineCodeId: expect.any(Number),
239
+ indentLevel: expect.any(Number),
240
+ });
241
+ });
66
242
  });
67
243
 
68
- test('GetHistoricalFinancialSheets', async () => {
69
- const resp = await financialClient.getHistoricalFinancialSheets(
70
- 'TUPRS',
71
- { year: 2022, month: 1, day: 1 },
72
- { year: 2025, month: 1, day: 1 },
73
- FinancialSheetType.CashFlow,
74
- FinancialSheetPeriod.Quarterly,
75
- Currency.TRY,
76
- Region.Tr
77
- );
78
-
79
- expect(resp).toBeDefined();
80
- expect(resp).not.toBeNull();
81
- expect(resp).not.toBeEmpty();
82
-
83
- expect(resp.sheets).toBeDefined();
84
- expect(Array.isArray(resp.sheets)).toBe(true);
85
- expect(resp.sheets.length).toBeGreaterThan(0);
86
-
87
- const firstSheet = resp.sheets[0];
88
- expect(firstSheet).toBeDefined();
89
-
90
- expect(firstSheet.period).toBeDefined();
91
- expect(typeof firstSheet.period).toBe("string")
92
-
93
- expect(firstSheet.items).toBeDefined();
94
- expect(Array.isArray(firstSheet.items)).toBe(true);
95
- expect(firstSheet.items.length).toBeGreaterThan(0);
96
-
97
- const firstRow = firstSheet.items[0];
98
- expect(firstRow).toBeDefined();
99
-
100
- expect(firstRow).toMatchObject<HistoricalFinancialSheetRow>({
101
- description: expect.any(String),
102
- value: expect.any(Number),
103
- lineCodeId: expect.any(Number),
104
- indentLevel: expect.any(Number),
105
- firstAncestorLineCodeId: expect.any(Number),
106
- sectionLineCodeId: expect.any(Number),
244
+ describe("Mock Tests", () => {
245
+ beforeEach(() => {
246
+ jest.clearAllMocks();
247
+ });
248
+
249
+ describe("getFinancialRatioComparison", () => {
250
+ test("should return ratio comparison with mock data", async () => {
251
+ jest.spyOn(financialClient, 'getFinancialRatioComparison').mockResolvedValue(mockRatioComparisonResponse);
252
+
253
+ const resp = await financialClient.getFinancialRatioComparison(
254
+ "TUPRS",
255
+ Region.Tr,
256
+ RatioComparisonPeerType.Sector
257
+ );
258
+
259
+ expect(resp).toHaveLength(1);
260
+
261
+ const comparison = resp[0];
262
+ expect(comparison.metricName).toBe("Net Kar Marjı");
263
+ expect(comparison.normalizedValue).toBe(0.85);
264
+ expect(comparison.data).toHaveLength(2);
265
+
266
+ const companyData = comparison.data[0];
267
+ expect(companyData.slug).toBe("TUPRS");
268
+ expect(companyData.value).toBe(12.5);
269
+ expect(companyData.average).toBe(8.2);
270
+
271
+ const sectorData = comparison.data[1];
272
+ expect(sectorData.slug).toBe("SECTOR_AVERAGE");
273
+ expect(sectorData.value).toBe(7.8);
274
+ expect(sectorData.average).toBe(8.2);
275
+
276
+ expect(financialClient.getFinancialRatioComparison).toHaveBeenCalledWith(
277
+ "TUPRS",
278
+ Region.Tr,
279
+ RatioComparisonPeerType.Sector
280
+ );
281
+ });
282
+ });
283
+
284
+ describe("getHistoricalRatios", () => {
285
+ test("should return historical ratios with mock data", async () => {
286
+ jest.spyOn(financialClient, 'getHistoricalRatios').mockResolvedValue(mockHistoricalRatiosResponse);
287
+
288
+ const resp = await financialClient.getHistoricalRatios(
289
+ "TUPRS",
290
+ [HistoricalRatiosKey.NetMargin],
291
+ Region.Tr,
292
+ Locale.Tr
293
+ );
294
+
295
+ expect(resp).toHaveLength(1);
296
+
297
+ const ratio = resp[0];
298
+ expect(ratio.slug).toBe(HistoricalRatiosKey.NetMargin);
299
+ expect(ratio.finalValue).toBe(12.5);
300
+ expect(ratio.threeYearGrowth).toBe(15.2);
301
+ expect(ratio.yearGrowth).toBe(5.8);
302
+ expect(ratio.finalSectorValue).toBe(7.8);
303
+ expect(ratio.currency).toBe(Currency.TRY);
304
+ expect(ratio.format).toBe(HistoricalRatiosFormat.PERCENTAGE);
305
+ expect(ratio.name).toBe("Net Kar Marjı");
306
+
307
+ expect(ratio.items).toHaveLength(2);
308
+ const firstItem = ratio.items[0];
309
+ expect(firstItem.period).toBe("2024-Q1");
310
+ expect(firstItem.value).toBe(12.5);
311
+ expect(firstItem.sectorMean).toBe(7.8);
312
+
313
+ expect(financialClient.getHistoricalRatios).toHaveBeenCalledWith(
314
+ "TUPRS",
315
+ [HistoricalRatiosKey.NetMargin],
316
+ Region.Tr,
317
+ Locale.Tr
318
+ );
319
+ });
320
+ });
321
+
322
+ describe("getHistoricalRatiosDescriptions", () => {
323
+ test("should return ratio descriptions with mock data", async () => {
324
+ jest.spyOn(financialClient, 'getHistoricalRatiosDescriptions').mockResolvedValue(mockRatiosDescriptionsResponse);
325
+
326
+ const resp = await financialClient.getHistoricalRatiosDescriptions(
327
+ Locale.Tr,
328
+ Region.Tr
329
+ );
330
+
331
+ expect(resp).toHaveLength(1);
332
+
333
+ const description = resp[0];
334
+ expect(description.id).toBe(1);
335
+ expect(description.format).toBe(HistoricalRatiosFormat.PERCENTAGE);
336
+ expect(description.currency).toBe(Currency.TRY);
337
+ expect(description.slug).toBe(HistoricalRatiosKey.NetMargin);
338
+ expect(description.name).toBe("Net Kar Marjı");
339
+ expect(description.description).toBe("Net karın satışlara oranı");
340
+ expect(description.locale).toBe(Locale.Tr);
341
+ expect(description.isRealtime).toBe(false);
342
+
343
+ expect(financialClient.getHistoricalRatiosDescriptions).toHaveBeenCalledWith(
344
+ Locale.Tr,
345
+ Region.Tr
346
+ );
347
+ });
348
+ });
349
+
350
+ describe("getHistoricalFinancialSheets", () => {
351
+ test("should return financial sheets with mock data", async () => {
352
+ jest.spyOn(financialClient, 'getHistoricalFinancialSheets').mockResolvedValue(mockFinancialSheetsResponse);
353
+
354
+ const resp = await financialClient.getHistoricalFinancialSheets(
355
+ "TUPRS",
356
+ { year: 2024, month: 1, day: 1 },
357
+ { year: 2024, month: 3, day: 31 },
358
+ FinancialSheetType.CashFlow,
359
+ FinancialSheetPeriod.Quarterly,
360
+ Currency.TRY,
361
+ Region.Tr
362
+ );
363
+
364
+ expect(resp.sheets).toHaveLength(1);
365
+
366
+ const sheet = resp.sheets[0];
367
+ expect(sheet.period).toBe("2024-Q1");
368
+ expect(sheet.items).toHaveLength(2);
369
+
370
+ const revenue = sheet.items[0];
371
+ expect(revenue.description).toBe("Satış Gelirleri");
372
+ expect(revenue.value).toBe(50000000000);
373
+ expect(revenue.lineCodeId).toBe(1);
374
+ expect(revenue.indentLevel).toBe(0);
375
+
376
+ const cogs = sheet.items[1];
377
+ expect(cogs.description).toBe("Satışların Maliyeti");
378
+ expect(cogs.value).toBe(-40000000000);
379
+ expect(cogs.lineCodeId).toBe(2);
380
+ expect(cogs.indentLevel).toBe(0);
381
+
382
+ expect(financialClient.getHistoricalFinancialSheets).toHaveBeenCalledWith(
383
+ "TUPRS",
384
+ { year: 2024, month: 1, day: 1 },
385
+ { year: 2024, month: 3, day: 31 },
386
+ FinancialSheetType.CashFlow,
387
+ FinancialSheetPeriod.Quarterly,
388
+ Currency.TRY,
389
+ Region.Tr
390
+ );
391
+ });
392
+
393
+ test("should handle balance sheet period error", async () => {
394
+ jest.spyOn(financialClient, 'getHistoricalFinancialSheets').mockRejectedValue(
395
+ new Error("Balance sheet is only available for cumulative period")
396
+ );
397
+
398
+ await expect(financialClient.getHistoricalFinancialSheets(
399
+ "TUPRS",
400
+ { year: 2024, month: 1, day: 1 },
401
+ { year: 2024, month: 3, day: 31 },
402
+ FinancialSheetType.BalanceSheet,
403
+ FinancialSheetPeriod.Quarterly,
404
+ Currency.TRY,
405
+ Region.Tr
406
+ )).rejects.toThrow("Balance sheet is only available for cumulative period");
407
+ });
107
408
  });
108
409
  });
109
410
  });