laplace-api 4.0.0 → 4.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.
@@ -5,9 +5,180 @@ import {
5
5
  HistoricalPricePeriod,
6
6
  HistoricalPriceInterval,
7
7
  AssetClass,
8
+ Stock,
9
+ AssetType,
10
+ Market,
11
+ StockPriceGraph,
12
+ MarketState,
13
+ EarningsTranscriptWithSummary,
14
+ EarningsTranscriptListItem
8
15
  } from "../client/stocks";
9
16
  import "./client_test_suite";
10
17
  import { Region, Locale } from "../client/collections";
18
+ import { PaginatedResponse } from "../client/capital_increase";
19
+
20
+ const mockStocksResponse: Stock[] = [
21
+ {
22
+ id: "61dd0d6f0ec2114146342fd0",
23
+ assetType: AssetType.Stock,
24
+ name: "Tüpraş",
25
+ symbol: "TUPRS",
26
+ sectorId: "sector123",
27
+ industryId: "industry456",
28
+ updatedDate: "2024-03-14T10:00:00Z",
29
+ dailyChange: 2.5,
30
+ active: true
31
+ },
32
+ {
33
+ id: "61dd0d6f0ec2114146342fd1",
34
+ assetType: AssetType.Stock,
35
+ name: "Garanti Bankası",
36
+ symbol: "GARAN",
37
+ sectorId: "sector789",
38
+ industryId: "industry101",
39
+ updatedDate: "2024-03-14T10:00:00Z",
40
+ dailyChange: -1.2,
41
+ active: true
42
+ }
43
+ ];
44
+
45
+ const mockStockDetailResponse = {
46
+ id: "61dd0d6f0ec2114146342fd0",
47
+ assetType: AssetType.Stock,
48
+ assetClass: AssetClass.Equity,
49
+ name: "Tüpraş",
50
+ symbol: "TUPRS",
51
+ sectorId: "sector123",
52
+ industryId: "industry456",
53
+ updatedDate: "2024-03-14T10:00:00Z",
54
+ dailyChange: 2.5,
55
+ active: true,
56
+ description: "Türkiye'nin en büyük rafineri şirketi",
57
+ shortDescription: "Rafineri şirketi",
58
+ region: Region.Tr,
59
+ localized_description: {
60
+ tr: "Türkiye'nin en büyük rafineri şirketi",
61
+ en: "Turkey's largest refinery company"
62
+ },
63
+ localizedShortDescription: {
64
+ tr: "Rafineri şirketi",
65
+ en: "Refinery company"
66
+ },
67
+ markets: [Market.Yildiz]
68
+ };
69
+
70
+ const mockHistoricalPricesResponse: StockPriceGraph[] = [
71
+ {
72
+ symbol: "TUPRS",
73
+ "1D": [
74
+ { d: 1710374400000, c: 425.5, h: 428.0, l: 422.0, o: 423.0 },
75
+ { d: 1710378000000, c: 426.8, h: 427.5, l: 425.0, o: 425.5 }
76
+ ],
77
+ "1W": [
78
+ { d: 1709856000000, c: 420.5, h: 422.0, l: 419.0, o: 419.5 },
79
+ { d: 1709942400000, c: 423.0, h: 424.5, l: 420.0, o: 420.5 }
80
+ ],
81
+ "1M": [
82
+ { d: 1707436800000, c: 415.0, h: 416.5, l: 414.0, o: 414.5 },
83
+ { d: 1707523200000, c: 417.2, h: 418.0, l: 415.0, o: 415.0 }
84
+ ],
85
+ "3M": [],
86
+ "1Y": [],
87
+ "2Y": [],
88
+ "3Y": [],
89
+ "5Y": []
90
+ }
91
+ ];
92
+
93
+ const mockStockRestrictionsResponse = [
94
+ {
95
+ id: 1,
96
+ title: "Bedelli Sermaye Artırımı",
97
+ description: "Şirket bedelli sermaye artırımı yapacaktır",
98
+ symbol: "TUPRS",
99
+ startDate: "2024-03-15T00:00:00Z",
100
+ endDate: "2024-03-20T00:00:00Z",
101
+ market: Market.Yildiz
102
+ },
103
+ {
104
+ id: 2,
105
+ title: "Temettü Ödemesi",
106
+ description: "Şirket temettü ödemesi yapacaktır",
107
+ symbol: "TUPRS",
108
+ startDate: "2024-04-01T00:00:00Z",
109
+ endDate: "2024-04-01T00:00:00Z",
110
+ market: Market.Yildiz
111
+ }
112
+ ];
113
+
114
+ const mockTickRulesResponse = {
115
+ basePrice: 425.5,
116
+ additionalPrice: 0.1,
117
+ lowerPriceLimit: 382.95,
118
+ upperPriceLimit: 468.05,
119
+ rules: [
120
+ { priceFrom: 0, priceTo: 20, tickSize: 0.01 },
121
+ { priceFrom: 20, priceTo: 50, tickSize: 0.02 },
122
+ { priceFrom: 50, priceTo: 100, tickSize: 0.05 }
123
+ ]
124
+ };
125
+
126
+ const mockEarningsTranscriptList: EarningsTranscriptListItem[] = [
127
+ {
128
+ symbol: "TUPRS",
129
+ year: 2024,
130
+ quarter: 1,
131
+ date: "2024-05-15",
132
+ fiscal_year: 2024
133
+ },
134
+ {
135
+ symbol: "TUPRS",
136
+ year: 2023,
137
+ quarter: 4,
138
+ date: "2024-02-20",
139
+ fiscal_year: 2023
140
+ }
141
+ ];
142
+
143
+ const mockEarningsTranscriptDetail: EarningsTranscriptWithSummary = {
144
+ symbol: "TUPRS",
145
+ year: 2024,
146
+ quarter: 1,
147
+ date: "2024-05-15",
148
+ content: "Q1 2024 earnings call transcript content...",
149
+ summary: "Strong Q1 performance with 15% revenue growth",
150
+ has_summary: true
151
+ };
152
+
153
+ const mockMarketStates: MarketState[] = [
154
+ {
155
+ id: 1,
156
+ marketSymbol: "XIST",
157
+ state: "OPEN",
158
+ lastTimestamp: "2024-03-14T10:00:00Z",
159
+ stockSymbol: "TUPRS"
160
+ },
161
+ {
162
+ id: 2,
163
+ marketSymbol: "XIST",
164
+ state: "CLOSED",
165
+ lastTimestamp: "2024-03-14T18:00:00Z",
166
+ stockSymbol: "GARAN"
167
+ }
168
+ ];
169
+
170
+ const mockPaginatedMarketStates: PaginatedResponse<MarketState> = {
171
+ recordCount: 2,
172
+ items: mockMarketStates
173
+ };
174
+
175
+ const mockSingleMarketState: MarketState = {
176
+ id: 1,
177
+ marketSymbol: "XIST",
178
+ state: "OPEN",
179
+ lastTimestamp: "2024-03-14T10:00:00Z",
180
+ stockSymbol: "TUPRS"
181
+ };
11
182
 
12
183
  describe("Stocks Client", () => {
13
184
  let client: StockClient;
@@ -24,192 +195,633 @@ describe("Stocks Client", () => {
24
195
  client = new StockClient(config, logger);
25
196
  });
26
197
 
27
- describe("getAllStocks", () => {
28
- test("should return stocks list for TR region", async () => {
29
- const resp = await client.getAllStocks(Region.Tr);
30
-
31
- expect(resp).not.toBeEmpty();
198
+ describe("Integration Tests", () => {
199
+ describe("getAllStocks", () => {
200
+ test("should return stocks list for TR region", async () => {
201
+ const resp = await client.getAllStocks(Region.Tr);
202
+
203
+ expect(resp).not.toBeEmpty();
204
+
205
+ const firstStock = resp[0];
206
+ expect(typeof firstStock.id).toBe("string");
207
+ expect(typeof firstStock.assetType).toBe("string");
208
+ expect(typeof firstStock.name).toBe("string");
209
+ expect(typeof firstStock.symbol).toBe("string");
210
+ expect(typeof firstStock.sectorId).toBe("string");
211
+ expect(typeof firstStock.industryId).toBe("string");
212
+ expect(typeof firstStock.updatedDate).toBe("string");
213
+ expect(typeof firstStock.active).toBe("boolean");
214
+
215
+ if (firstStock.dailyChange !== undefined) {
216
+ expect(typeof firstStock.dailyChange).toBe("number");
217
+ }
218
+ });
32
219
 
33
- const firstStock = resp[0];
34
- expect(typeof firstStock.id).toBe("string");
35
- expect(typeof firstStock.assetType).toBe("string");
36
- expect(typeof firstStock.name).toBe("string");
37
- expect(typeof firstStock.symbol).toBe("string");
38
- expect(typeof firstStock.sectorId).toBe("string");
39
- expect(typeof firstStock.industryId).toBe("string");
40
- expect(typeof firstStock.updatedDate).toBe("string");
41
- expect(typeof firstStock.active).toBe("boolean");
220
+ test("should handle pagination correctly", async () => {
221
+ const resp = await client.getAllStocks(Region.Tr, 10, 10);
42
222
 
43
- if (firstStock.dailyChange !== undefined) {
44
- expect(typeof firstStock.dailyChange).toBe("number");
45
- }
223
+ expect(resp).not.toBeEmpty();
224
+ expect(resp.length).toBeLessThanOrEqual(10);
225
+ });
46
226
  });
47
227
 
48
- test("should handle pagination correctly", async () => {
49
- const resp = await client.getAllStocks(Region.Tr, 10, 10);
50
-
51
- expect(resp).not.toBeEmpty();
52
- expect(resp.length).toBeLessThanOrEqual(10);
228
+ describe("getStockDetailById", () => {
229
+ test("should return stock detail by ID", async () => {
230
+ const resp = await client.getStockDetailById(
231
+ "61dd0d6f0ec2114146342fd0",
232
+ Locale.Tr
233
+ );
234
+
235
+ expect(resp).toBeDefined();
236
+ expect(typeof resp.id).toBe("string");
237
+ expect(typeof resp.assetClass).toBe("string");
238
+ expect(typeof resp.description).toBe("string");
239
+ expect(typeof resp.shortDescription).toBe("string");
240
+ expect(typeof resp.region).toBe("string");
241
+ expect(typeof resp.localized_description).toBe("object");
242
+ expect(typeof resp.localizedShortDescription).toBe("object");
243
+
244
+ if (resp.markets) {
245
+ expect(Array.isArray(resp.markets)).toBe(true);
246
+ }
247
+ });
53
248
  });
54
- });
55
249
 
56
- describe("getStockDetailById", () => {
57
- test("should return stock detail by ID", async () => {
58
- const resp = await client.getStockDetailById(
59
- "61dd0d6f0ec2114146342fd0",
60
- Locale.Tr
61
- );
62
-
63
- expect(resp).toBeDefined();
64
- expect(typeof resp.id).toBe("string");
65
- expect(typeof resp.assetClass).toBe("string");
66
- expect(typeof resp.description).toBe("string");
67
- expect(typeof resp.shortDescription).toBe("string");
68
- expect(typeof resp.region).toBe("string");
69
- expect(typeof resp.localized_description).toBe("object");
70
- expect(typeof resp.localizedShortDescription).toBe("object");
71
-
72
- if (resp.markets) {
73
- expect(Array.isArray(resp.markets)).toBe(true);
74
- }
250
+ describe("getStockDetailBySymbol", () => {
251
+ test("should return stock detail by symbol", async () => {
252
+ const resp = await client.getStockDetailBySymbol(
253
+ "TUPRS",
254
+ AssetClass.Equity,
255
+ Region.Tr,
256
+ Locale.Tr
257
+ );
258
+
259
+ expect(resp).toBeDefined();
260
+ expect(resp.symbol).toBe("TUPRS");
261
+ expect(typeof resp.assetClass).toBe("string");
262
+ expect(typeof resp.description).toBe("string");
263
+ expect(typeof resp.region).toBe("string");
264
+ });
75
265
  });
76
- });
77
266
 
78
- describe("getStockDetailBySymbol", () => {
79
- test("should return stock detail by symbol", async () => {
80
- const resp = await client.getStockDetailBySymbol(
81
- "TUPRS",
82
- AssetClass.Equity,
83
- Region.Tr,
84
- Locale.Tr
85
- );
86
-
87
- expect(resp).toBeDefined();
88
- expect(resp.symbol).toBe("TUPRS");
89
- expect(typeof resp.assetClass).toBe("string");
90
- expect(typeof resp.description).toBe("string");
91
- expect(typeof resp.region).toBe("string");
267
+ describe("getHistoricalPrices", () => {
268
+ test("should return historical prices for multiple symbols", async () => {
269
+ const resp = await client.getHistoricalPrices(
270
+ ["TUPRS", "SASA"],
271
+ Region.Tr,
272
+ [
273
+ HistoricalPricePeriod.OneDay,
274
+ HistoricalPricePeriod.OneWeek,
275
+ HistoricalPricePeriod.OneMonth,
276
+ ]
277
+ );
278
+
279
+ expect(resp).not.toBeEmpty();
280
+
281
+ const firstPriceGraph = resp[0];
282
+ expect(typeof firstPriceGraph.symbol).toBe("string");
283
+ expect(Array.isArray(firstPriceGraph["1D"])).toBe(true);
284
+ expect(Array.isArray(firstPriceGraph["1W"])).toBe(true);
285
+ expect(Array.isArray(firstPriceGraph["1M"])).toBe(true);
286
+
287
+ if (firstPriceGraph["1D"].length > 0) {
288
+ const firstDataPoint = firstPriceGraph["1D"][0];
289
+ expect(typeof firstDataPoint.d).toBe("number");
290
+ expect(typeof firstDataPoint.c).toBe("number");
291
+ expect(typeof firstDataPoint.h).toBe("number");
292
+ expect(typeof firstDataPoint.l).toBe("number");
293
+ expect(typeof firstDataPoint.o).toBe("number");
294
+ }
295
+ });
92
296
  });
93
- });
94
-
95
- describe("getHistoricalPrices", () => {
96
- test("should return historical prices for multiple symbols", async () => {
97
- const resp = await client.getHistoricalPrices(
98
- ["TUPRS", "SASA"],
99
- Region.Tr,
100
- [
101
- HistoricalPricePeriod.OneDay,
102
- HistoricalPricePeriod.OneWeek,
103
- HistoricalPricePeriod.OneMonth,
104
- ]
105
- );
106
297
 
107
- expect(resp).not.toBeEmpty();
298
+ describe("getCustomHistoricalPrices", () => {
299
+ test("should return custom historical prices", async () => {
300
+ const resp = await client.getCustomHistoricalPrices(
301
+ "TUPRS",
302
+ Region.Tr,
303
+ "2024-01-01",
304
+ "2024-03-01",
305
+ HistoricalPriceInterval.OneDay,
306
+ false
307
+ );
108
308
 
109
- const firstPriceGraph = resp[0];
110
- expect(typeof firstPriceGraph.symbol).toBe("string");
111
- expect(Array.isArray(firstPriceGraph["1D"])).toBe(true);
112
- expect(Array.isArray(firstPriceGraph["1W"])).toBe(true);
113
- expect(Array.isArray(firstPriceGraph["1M"])).toBe(true);
309
+ expect(resp).not.toBeEmpty();
114
310
 
115
- if (firstPriceGraph["1D"].length > 0) {
116
- const firstDataPoint = firstPriceGraph["1D"][0];
311
+ const firstDataPoint = resp[0];
117
312
  expect(typeof firstDataPoint.d).toBe("number");
118
313
  expect(typeof firstDataPoint.c).toBe("number");
119
314
  expect(typeof firstDataPoint.h).toBe("number");
120
315
  expect(typeof firstDataPoint.l).toBe("number");
121
316
  expect(typeof firstDataPoint.o).toBe("number");
122
- }
317
+ });
318
+
319
+ test("should handle detailed historical prices", async () => {
320
+ const resp = await client.getCustomHistoricalPrices(
321
+ "SASA",
322
+ Region.Tr,
323
+ "2024-01-01 10:00:00",
324
+ "2024-01-05 10:00:00",
325
+ HistoricalPriceInterval.OneHour,
326
+ true
327
+ );
328
+
329
+ expect(resp).not.toBeEmpty();
330
+ });
123
331
  });
124
- });
125
332
 
126
- describe("getCustomHistoricalPrices", () => {
127
- test("should return custom historical prices", async () => {
128
- const resp = await client.getCustomHistoricalPrices(
129
- "TUPRS",
130
- Region.Tr,
131
- "2024-01-01",
132
- "2024-03-01",
133
- HistoricalPriceInterval.OneDay,
134
- false
135
- );
136
-
137
- expect(resp).not.toBeEmpty();
138
-
139
- const firstDataPoint = resp[0];
140
- expect(typeof firstDataPoint.d).toBe("number");
141
- expect(typeof firstDataPoint.c).toBe("number");
142
- expect(typeof firstDataPoint.h).toBe("number");
143
- expect(typeof firstDataPoint.l).toBe("number");
144
- expect(typeof firstDataPoint.o).toBe("number");
145
- });
146
-
147
- test("should handle detailed historical prices", async () => {
148
- const resp = await client.getCustomHistoricalPrices(
149
- "SASA",
150
- Region.Tr,
151
- "2024-01-01 10:00:00",
152
- "2024-01-05 10:00:00",
153
- HistoricalPriceInterval.OneHour,
154
- true
155
- );
156
-
157
- expect(resp).not.toBeEmpty();
333
+ describe("getStockRestrictions", () => {
334
+ test("should return stock restrictions for specific symbol", async () => {
335
+ const resp = await client.getStockRestrictions("TUPRS", Region.Tr);
336
+
337
+ if (resp && resp.length > 0) {
338
+ const firstRestriction = resp[0];
339
+ expect(typeof firstRestriction.id).toBe("number");
340
+ expect(typeof firstRestriction.title).toBe("string");
341
+ expect(typeof firstRestriction.description).toBe("string");
342
+ expect(typeof firstRestriction.startDate).toBe("string");
343
+ expect(typeof firstRestriction.endDate).toBe("string");
344
+
345
+ if (firstRestriction.symbol) {
346
+ expect(typeof firstRestriction.symbol).toBe("string");
347
+ }
348
+ if (firstRestriction.market) {
349
+ expect(typeof firstRestriction.market).toBe("string");
350
+ }
351
+ }
352
+ });
158
353
  });
159
- });
160
354
 
161
- describe("getStockRestrictions", () => {
162
- test("should return stock restrictions for specific symbol", async () => {
163
- const resp = await client.getStockRestrictions("TUPRS", Region.Tr);
355
+ describe("getAllStockRestrictions", () => {
356
+ test("should return all stock restrictions for region", async () => {
357
+ const resp = await client.getAllStockRestrictions(Region.Tr);
164
358
 
165
- if (resp && resp.length > 0) {
166
- const firstRestriction = resp[0];
167
- expect(typeof firstRestriction.id).toBe("number");
168
- expect(typeof firstRestriction.title).toBe("string");
169
- expect(typeof firstRestriction.description).toBe("string");
170
- expect(typeof firstRestriction.startDate).toBe("string");
171
- expect(typeof firstRestriction.endDate).toBe("string");
172
-
173
- if (firstRestriction.symbol) {
174
- expect(typeof firstRestriction.symbol).toBe("string");
359
+ expect(Array.isArray(resp)).toBe(true);
360
+
361
+ if (resp.length > 0) {
362
+ const firstRestriction = resp[0];
363
+ expect(typeof firstRestriction.id).toBe("number");
364
+ expect(typeof firstRestriction.title).toBe("string");
365
+ expect(typeof firstRestriction.description).toBe("string");
366
+ expect(typeof firstRestriction.startDate).toBe("string");
367
+ expect(typeof firstRestriction.endDate).toBe("string");
368
+ }
369
+ });
370
+ });
371
+
372
+ describe("getTickRules", () => {
373
+ test("should return tick rules for symbol", async () => {
374
+ const resp = await client.getTickRules("TUPRS", Region.Tr);
375
+
376
+ expect(resp).toBeDefined();
377
+ expect(typeof resp.basePrice).toBe("number");
378
+ expect(typeof resp.additionalPrice).toBe("number");
379
+ expect(typeof resp.lowerPriceLimit).toBe("number");
380
+ expect(typeof resp.upperPriceLimit).toBe("number");
381
+
382
+ if (resp.rules !== null) {
383
+ expect(Array.isArray(resp.rules)).toBe(true);
384
+ }
385
+ });
386
+ });
387
+
388
+ describe("getEarningsTranscripts", () => {
389
+ test("should return earnings transcript list", async () => {
390
+ const resp = await client.getEarningsTranscripts("TUPRS", Region.Tr);
391
+
392
+ expect(Array.isArray(resp)).toBe(true);
393
+
394
+ if (resp.length > 0) {
395
+ const firstTranscript = resp[0];
396
+ expect(typeof firstTranscript.symbol).toBe("string");
397
+ expect(typeof firstTranscript.year).toBe("number");
398
+ expect(typeof firstTranscript.quarter).toBe("number");
399
+ expect(typeof firstTranscript.date).toBe("string");
400
+ expect(typeof firstTranscript.fiscal_year).toBe("number");
401
+ }
402
+ });
403
+ });
404
+
405
+ describe("getEarningsTranscript", () => {
406
+ test("should return earnings transcript detail", async () => {
407
+ const resp = await client.getEarningsTranscript("TUPRS", 2023, 4);
408
+
409
+ expect(resp).toBeDefined();
410
+ expect(typeof resp.symbol).toBe("string");
411
+ expect(typeof resp.year).toBe("number");
412
+ expect(typeof resp.quarter).toBe("number");
413
+ expect(typeof resp.date).toBe("string");
414
+ expect(typeof resp.content).toBe("string");
415
+ expect(typeof resp.has_summary).toBe("boolean");
416
+
417
+ if (resp.summary) {
418
+ expect(typeof resp.summary).toBe("string");
419
+ }
420
+ });
421
+ });
422
+
423
+ describe("getStockStateAll", () => {
424
+ test("should return paginated stock states", async () => {
425
+ const resp = await client.getStockStateAll(0, 10, Region.Tr);
426
+
427
+ expect(resp).toBeDefined();
428
+ expect(Array.isArray(resp.items)).toBe(true);
429
+ expect(typeof resp.recordCount).toBe("number");
430
+
431
+ if (resp.items.length > 0) {
432
+ const firstState = resp.items[0];
433
+ expect(typeof firstState.id).toBe("number");
434
+ expect(typeof firstState.state).toBe("string");
435
+ expect(typeof firstState.lastTimestamp).toBe("string");
436
+ }
437
+ });
438
+ });
439
+
440
+ describe("getStockState", () => {
441
+ test("should return single stock state", async () => {
442
+ const resp = await client.getStockState("TUPRS");
443
+
444
+ expect(resp).toBeDefined();
445
+ expect(typeof resp.id).toBe("number");
446
+ expect(typeof resp.state).toBe("string");
447
+ expect(typeof resp.lastTimestamp).toBe("string");
448
+
449
+ if (resp.stockSymbol) {
450
+ expect(typeof resp.stockSymbol).toBe("string");
451
+ }
452
+ if (resp.marketSymbol) {
453
+ expect(typeof resp.marketSymbol).toBe("string");
175
454
  }
176
- if (firstRestriction.market) {
177
- expect(typeof firstRestriction.market).toBe("string");
455
+ });
456
+ });
457
+
458
+ describe("getStateAll", () => {
459
+ test("should return paginated market states", async () => {
460
+ const resp = await client.getStateAll(0, 10, Region.Tr);
461
+
462
+ expect(resp).toBeDefined();
463
+ expect(Array.isArray(resp.items)).toBe(true);
464
+ expect(typeof resp.recordCount).toBe("number");
465
+
466
+ if (resp.items.length > 0) {
467
+ const firstState = resp.items[0];
468
+ expect(typeof firstState.id).toBe("number");
469
+ expect(typeof firstState.state).toBe("string");
470
+ expect(typeof firstState.lastTimestamp).toBe("string");
471
+ }
472
+ });
473
+ });
474
+
475
+ describe("getState", () => {
476
+ test("should return single market state", async () => {
477
+ const resp = await client.getState("XIST");
478
+
479
+ expect(resp).toBeDefined();
480
+ expect(typeof resp.id).toBe("number");
481
+ expect(typeof resp.state).toBe("string");
482
+ expect(typeof resp.lastTimestamp).toBe("string");
483
+
484
+ if (resp.marketSymbol) {
485
+ expect(typeof resp.marketSymbol).toBe("string");
178
486
  }
179
- }
487
+ });
180
488
  });
181
489
  });
182
490
 
183
- describe("getAllStockRestrictions", () => {
184
- test("should return all stock restrictions for region", async () => {
185
- const resp = await client.getAllStockRestrictions(Region.Tr);
491
+ describe("Mock Tests", () => {
492
+ beforeEach(() => {
493
+ jest.clearAllMocks();
494
+ });
495
+
496
+ describe("getAllStocks", () => {
497
+ test("should handle getAllStocks response correctly with mock data", async () => {
498
+ jest.spyOn(client, 'getAllStocks').mockResolvedValue(mockStocksResponse);
499
+
500
+ const resp = await client.getAllStocks(Region.Tr);
501
+
502
+ expect(resp).toHaveLength(2);
503
+
504
+ const firstStock = resp[0];
505
+ expect(firstStock.id).toBe("61dd0d6f0ec2114146342fd0");
506
+ expect(firstStock.assetType).toBe(AssetType.Stock);
507
+ expect(firstStock.name).toBe("Tüpraş");
508
+ expect(firstStock.symbol).toBe("TUPRS");
509
+ expect(firstStock.sectorId).toBe("sector123");
510
+ expect(firstStock.industryId).toBe("industry456");
511
+ expect(firstStock.updatedDate).toBe("2024-03-14T10:00:00Z");
512
+ expect(firstStock.dailyChange).toBe(2.5);
513
+ expect(firstStock.active).toBe(true);
514
+
515
+ const secondStock = resp[1];
516
+ expect(secondStock.id).toBe("61dd0d6f0ec2114146342fd1");
517
+ expect(secondStock.symbol).toBe("GARAN");
518
+ expect(secondStock.dailyChange).toBe(-1.2);
519
+
520
+ expect(client.getAllStocks).toHaveBeenCalledWith(Region.Tr);
521
+ });
522
+
523
+ test("should handle pagination correctly with mock data", async () => {
524
+ jest.spyOn(client, 'getAllStocks').mockResolvedValue([mockStocksResponse[0]]);
525
+
526
+ const resp = await client.getAllStocks(Region.Tr, 1, 0);
527
+
528
+ expect(resp).toHaveLength(1);
529
+ expect(resp[0].symbol).toBe("TUPRS");
530
+
531
+ expect(client.getAllStocks).toHaveBeenCalledWith(Region.Tr, 1, 0);
532
+ });
533
+
534
+ test("should handle API errors correctly", async () => {
535
+ jest.spyOn(client, 'getAllStocks').mockRejectedValue(new Error("API Error"));
536
+
537
+ await expect(client.getAllStocks(Region.Tr)).rejects.toThrow("API Error");
538
+ });
539
+ });
540
+
541
+ describe("getStockDetailById", () => {
542
+ test("should return stock detail by ID with mock data", async () => {
543
+ jest.spyOn(client, 'getStockDetailById').mockResolvedValue(mockStockDetailResponse);
544
+
545
+ const resp = await client.getStockDetailById("61dd0d6f0ec2114146342fd0", Locale.Tr);
546
+
547
+ expect(resp).toBeDefined();
548
+ expect(resp.id).toBe("61dd0d6f0ec2114146342fd0");
549
+ expect(resp.assetType).toBe(AssetType.Stock);
550
+ expect(resp.assetClass).toBe(AssetClass.Equity);
551
+ expect(resp.description).toBe("Türkiye'nin en büyük rafineri şirketi");
552
+ expect(resp.shortDescription).toBe("Rafineri şirketi");
553
+ expect(resp.region).toBe(Region.Tr);
554
+ expect(resp.localized_description).toEqual({
555
+ tr: "Türkiye'nin en büyük rafineri şirketi",
556
+ en: "Turkey's largest refinery company"
557
+ });
558
+ expect(resp.localizedShortDescription).toEqual({
559
+ tr: "Rafineri şirketi",
560
+ en: "Refinery company"
561
+ });
562
+ expect(resp.markets).toEqual([Market.Yildiz]);
563
+
564
+ expect(client.getStockDetailById).toHaveBeenCalledWith("61dd0d6f0ec2114146342fd0", Locale.Tr);
565
+ });
566
+
567
+ test("should handle API errors for stock detail", async () => {
568
+ jest.spyOn(client, 'getStockDetailById').mockRejectedValue(new Error("Stock not found"));
569
+
570
+ await expect(client.getStockDetailById("invalid_id", Locale.Tr))
571
+ .rejects.toThrow("Stock not found");
572
+ });
573
+ });
186
574
 
187
- expect(Array.isArray(resp)).toBe(true);
575
+ describe("getHistoricalPrices", () => {
576
+ test("should return historical prices for multiple symbols with mock data", async () => {
577
+ jest.spyOn(client, 'getHistoricalPrices').mockResolvedValue(mockHistoricalPricesResponse);
188
578
 
189
- if (resp.length > 0) {
579
+ const symbols = ["TUPRS"];
580
+ const periods = [
581
+ HistoricalPricePeriod.OneDay,
582
+ HistoricalPricePeriod.OneWeek,
583
+ HistoricalPricePeriod.OneMonth
584
+ ];
585
+
586
+ const resp = await client.getHistoricalPrices(symbols, Region.Tr, periods);
587
+
588
+ expect(resp).toHaveLength(1);
589
+
590
+ const firstPriceGraph = resp[0];
591
+ expect(firstPriceGraph.symbol).toBe("TUPRS");
592
+
593
+ expect(firstPriceGraph["1D"]).toHaveLength(2);
594
+ const firstDayPoint = firstPriceGraph["1D"][0];
595
+ expect(firstDayPoint.d).toBe(1710374400000);
596
+ expect(firstDayPoint.c).toBe(425.5);
597
+ expect(firstDayPoint.h).toBe(428.0);
598
+ expect(firstDayPoint.l).toBe(422.0);
599
+ expect(firstDayPoint.o).toBe(423.0);
600
+ expect(firstPriceGraph["1W"]).toHaveLength(2);
601
+ expect(firstPriceGraph["1M"]).toHaveLength(2);
602
+
603
+ expect(client.getHistoricalPrices).toHaveBeenCalledWith(
604
+ symbols,
605
+ Region.Tr,
606
+ periods
607
+ );
608
+ });
609
+
610
+ test("should handle API errors for historical prices", async () => {
611
+ jest.spyOn(client, 'getHistoricalPrices').mockRejectedValue(new Error("Failed to fetch historical prices"));
612
+
613
+ await expect(client.getHistoricalPrices(
614
+ ["TUPRS"],
615
+ Region.Tr,
616
+ [HistoricalPricePeriod.OneDay]
617
+ )).rejects.toThrow("Failed to fetch historical prices");
618
+ });
619
+ });
620
+
621
+ describe("getStockRestrictions", () => {
622
+ test("should return stock restrictions with mock data", async () => {
623
+ jest.spyOn(client, 'getStockRestrictions').mockResolvedValue(mockStockRestrictionsResponse);
624
+
625
+ const resp = await client.getStockRestrictions("TUPRS", Region.Tr);
626
+
627
+ expect(resp).toHaveLength(2);
628
+
190
629
  const firstRestriction = resp[0];
191
- expect(typeof firstRestriction.id).toBe("number");
192
- expect(typeof firstRestriction.title).toBe("string");
193
- expect(typeof firstRestriction.description).toBe("string");
194
- expect(typeof firstRestriction.startDate).toBe("string");
195
- expect(typeof firstRestriction.endDate).toBe("string");
196
- }
630
+ expect(firstRestriction.id).toBe(1);
631
+ expect(firstRestriction.title).toBe("Bedelli Sermaye Artırımı");
632
+ expect(firstRestriction.description).toBe("Şirket bedelli sermaye artırımı yapacaktır");
633
+ expect(firstRestriction.symbol).toBe("TUPRS");
634
+ expect(firstRestriction.startDate).toBe("2024-03-15T00:00:00Z");
635
+ expect(firstRestriction.endDate).toBe("2024-03-20T00:00:00Z");
636
+ expect(firstRestriction.market).toBe(Market.Yildiz);
637
+
638
+ expect(client.getStockRestrictions).toHaveBeenCalledWith("TUPRS", Region.Tr);
639
+ });
640
+
641
+ test("should handle API errors for stock restrictions", async () => {
642
+ jest.spyOn(client, 'getStockRestrictions').mockRejectedValue(new Error("Failed to fetch restrictions"));
643
+
644
+ await expect(client.getStockRestrictions("TUPRS", Region.Tr))
645
+ .rejects.toThrow("Failed to fetch restrictions");
646
+ });
197
647
  });
198
- });
199
648
 
200
- describe("getTickRules", () => {
201
- test("should return tick rules for symbol", async () => {
202
- const resp = await client.getTickRules("TUPRS", Region.Tr);
649
+ describe("getTickRules", () => {
650
+ test("should return tick rules with mock data", async () => {
651
+ jest.spyOn(client, 'getTickRules').mockResolvedValue(mockTickRulesResponse);
652
+
653
+ const resp = await client.getTickRules("TUPRS", Region.Tr);
654
+
655
+ expect(resp.basePrice).toBe(425.5);
656
+ expect(resp.additionalPrice).toBe(0.1);
657
+ expect(resp.lowerPriceLimit).toBe(382.95);
658
+ expect(resp.upperPriceLimit).toBe(468.05);
659
+ expect(resp.rules).toHaveLength(3);
660
+
661
+ const firstRule = resp.rules![0];
662
+ expect(firstRule.priceFrom).toBe(0);
663
+ expect(firstRule.priceTo).toBe(20);
664
+ expect(firstRule.tickSize).toBe(0.01);
665
+
666
+ expect(client.getTickRules).toHaveBeenCalledWith("TUPRS", Region.Tr);
667
+ });
668
+
669
+ test("should handle API errors for tick rules", async () => {
670
+ jest.spyOn(client, 'getTickRules').mockRejectedValue(new Error("Failed to fetch tick rules"));
671
+
672
+ await expect(client.getTickRules("TUPRS", Region.Tr))
673
+ .rejects.toThrow("Failed to fetch tick rules");
674
+ });
675
+ });
676
+
677
+ describe("getEarningsTranscripts", () => {
678
+ test("should return earnings transcript list with mock data", async () => {
679
+ jest.spyOn(client, 'getEarningsTranscripts').mockResolvedValue(mockEarningsTranscriptList);
680
+
681
+ const resp = await client.getEarningsTranscripts("TUPRS", Region.Tr);
682
+
683
+ expect(resp).toHaveLength(2);
684
+
685
+ const firstTranscript = resp[0];
686
+ expect(firstTranscript.symbol).toBe("TUPRS");
687
+ expect(firstTranscript.year).toBe(2024);
688
+ expect(firstTranscript.quarter).toBe(1);
689
+ expect(firstTranscript.date).toBe("2024-05-15");
690
+ expect(firstTranscript.fiscal_year).toBe(2024);
691
+
692
+ const secondTranscript = resp[1];
693
+ expect(secondTranscript.year).toBe(2023);
694
+ expect(secondTranscript.quarter).toBe(4);
695
+
696
+ expect(client.getEarningsTranscripts).toHaveBeenCalledWith("TUPRS", Region.Tr);
697
+ });
698
+
699
+ test("should handle API errors for earnings transcripts", async () => {
700
+ jest.spyOn(client, 'getEarningsTranscripts').mockRejectedValue(new Error("Transcripts not found"));
701
+
702
+ await expect(client.getEarningsTranscripts("INVALID", Region.Tr))
703
+ .rejects.toThrow("Transcripts not found");
704
+ });
705
+ });
706
+
707
+ describe("getEarningsTranscript", () => {
708
+ test("should return earnings transcript detail with mock data", async () => {
709
+ jest.spyOn(client, 'getEarningsTranscript').mockResolvedValue(mockEarningsTranscriptDetail);
710
+
711
+ const resp = await client.getEarningsTranscript("TUPRS", 2024, 1);
712
+
713
+ expect(resp.symbol).toBe("TUPRS");
714
+ expect(resp.year).toBe(2024);
715
+ expect(resp.quarter).toBe(1);
716
+ expect(resp.date).toBe("2024-05-15");
717
+ expect(resp.content).toBe("Q1 2024 earnings call transcript content...");
718
+ expect(resp.summary).toBe("Strong Q1 performance with 15% revenue growth");
719
+ expect(resp.has_summary).toBe(true);
720
+
721
+ expect(client.getEarningsTranscript).toHaveBeenCalledWith("TUPRS", 2024, 1);
722
+ });
723
+
724
+ test("should handle API errors for earnings transcript detail", async () => {
725
+ jest.spyOn(client, 'getEarningsTranscript').mockRejectedValue(new Error("Transcript not found"));
726
+
727
+ await expect(client.getEarningsTranscript("TUPRS", 2020, 1))
728
+ .rejects.toThrow("Transcript not found");
729
+ });
730
+ });
731
+
732
+ describe("getStockStateAll", () => {
733
+ test("should return paginated stock states with mock data", async () => {
734
+ jest.spyOn(client, 'getStockStateAll').mockResolvedValue(mockPaginatedMarketStates);
735
+
736
+ const resp = await client.getStockStateAll(0, 10, Region.Tr);
737
+
738
+ expect(resp.items).toHaveLength(2);
739
+ expect(resp.recordCount).toBe(2);
740
+
741
+ const firstState = resp.items[0];
742
+ expect(firstState.id).toBe(1);
743
+ expect(firstState.marketSymbol).toBe("XIST");
744
+ expect(firstState.state).toBe("OPEN");
745
+ expect(firstState.stockSymbol).toBe("TUPRS");
746
+
747
+ expect(client.getStockStateAll).toHaveBeenCalledWith(0, 10, Region.Tr);
748
+ });
749
+
750
+ test("should handle API errors for stock state all", async () => {
751
+ jest.spyOn(client, 'getStockStateAll').mockRejectedValue(new Error("Failed to fetch stock states"));
752
+
753
+ await expect(client.getStockStateAll(0, 10, Region.Tr))
754
+ .rejects.toThrow("Failed to fetch stock states");
755
+ });
756
+ });
757
+
758
+ describe("getStockState", () => {
759
+ test("should return single stock state with mock data", async () => {
760
+ jest.spyOn(client, 'getStockState').mockResolvedValue(mockSingleMarketState);
761
+
762
+ const resp = await client.getStockState("TUPRS");
763
+
764
+ expect(resp.id).toBe(1);
765
+ expect(resp.marketSymbol).toBe("XIST");
766
+ expect(resp.state).toBe("OPEN");
767
+ expect(resp.lastTimestamp).toBe("2024-03-14T10:00:00Z");
768
+ expect(resp.stockSymbol).toBe("TUPRS");
769
+
770
+ expect(client.getStockState).toHaveBeenCalledWith("TUPRS");
771
+ });
772
+
773
+ test("should handle API errors for single stock state", async () => {
774
+ jest.spyOn(client, 'getStockState').mockRejectedValue(new Error("Stock state not found"));
775
+
776
+ await expect(client.getStockState("INVALID"))
777
+ .rejects.toThrow("Stock state not found");
778
+ });
779
+ });
780
+
781
+ describe("getStateAll", () => {
782
+ test("should return paginated market states with mock data", async () => {
783
+ jest.spyOn(client, 'getStateAll').mockResolvedValue(mockPaginatedMarketStates);
784
+
785
+ const resp = await client.getStateAll(0, 10, Region.Tr);
786
+
787
+ expect(resp.items).toHaveLength(2);
788
+ expect(resp.recordCount).toBe(2);
789
+
790
+ const firstState = resp.items[0];
791
+ expect(firstState.state).toBe("OPEN");
792
+ expect(firstState.lastTimestamp).toBe("2024-03-14T10:00:00Z");
793
+
794
+ expect(client.getStateAll).toHaveBeenCalledWith(0, 10, Region.Tr);
795
+ });
796
+
797
+ test("should handle API errors for state all", async () => {
798
+ jest.spyOn(client, 'getStateAll').mockRejectedValue(new Error("Failed to fetch states"));
799
+
800
+ await expect(client.getStateAll(0, 10, Region.Tr))
801
+ .rejects.toThrow("Failed to fetch states");
802
+ });
803
+ });
804
+
805
+ describe("getState", () => {
806
+ test("should return single market state with mock data", async () => {
807
+ jest.spyOn(client, 'getState').mockResolvedValue(mockSingleMarketState);
808
+
809
+ const resp = await client.getState("XIST");
810
+
811
+ expect(resp.id).toBe(1);
812
+ expect(resp.marketSymbol).toBe("XIST");
813
+ expect(resp.state).toBe("OPEN");
814
+ expect(resp.lastTimestamp).toBe("2024-03-14T10:00:00Z");
815
+
816
+ expect(client.getState).toHaveBeenCalledWith("XIST");
817
+ });
203
818
 
204
- expect(resp).toBeDefined();
205
- expect(typeof resp.basePrice).toBe("number");
206
- expect(typeof resp.additionalPrice).toBe("number");
207
- expect(typeof resp.lowerPriceLimit).toBe("number");
208
- expect(typeof resp.upperPriceLimit).toBe("number");
819
+ test("should handle API errors for single state", async () => {
820
+ jest.spyOn(client, 'getState').mockRejectedValue(new Error("Market state not found"));
209
821
 
210
- if (resp.rules !== null) {
211
- expect(Array.isArray(resp.rules)).toBe(true);
212
- }
822
+ await expect(client.getState("INVALID"))
823
+ .rejects.toThrow("Market state not found");
824
+ });
213
825
  });
214
826
  });
215
827
  });