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.
@@ -7,7 +7,99 @@ import {
7
7
  BrokerSort,
8
8
  SortDirection,
9
9
  BrokerStats,
10
+ Broker,
11
+ BrokerStock,
12
+ BrokerList,
13
+ BrokerItem,
10
14
  } from "../client/broker";
15
+ import { AssetType, AssetClass } from "../client/stocks";
16
+ import { PaginatedResponse } from "../client/capital_increase";
17
+
18
+ const mockBroker: Broker = {
19
+ id: 1001,
20
+ symbol: "BIYKR",
21
+ name: "BİYİKLI YATIRIM",
22
+ longName: "Bıyıklı Yatırım Menkul Değerler A.Ş.",
23
+ logo: "https://example.com/biykr.png"
24
+ };
25
+
26
+ const mockBroker2: Broker = {
27
+ id: 1002,
28
+ symbol: "GEDIK",
29
+ name: "GEDİK YATIRIM",
30
+ longName: "Gedik Yatırım Menkul Değerler A.Ş.",
31
+ logo: "https://example.com/gedik.png"
32
+ };
33
+
34
+ const mockBroker3: Broker = {
35
+ id: 1001,
36
+ symbol: "BIYKR",
37
+ name: "BİYİKLI YATIRIM",
38
+ longName: "Bıyıklı Yatırım Menkul Değerler A.Ş.",
39
+ logo: "https://example.com/biykr.png",
40
+ supportedAssetClasses: [AssetClass.Equity]
41
+ };
42
+
43
+ const mockBroker4: Broker = {
44
+ id: 1002,
45
+ symbol: "GEDIK",
46
+ name: "GEDİK YATIRIM",
47
+ longName: "Gedik Yatırım Menkul Değerler A.Ş.",
48
+ logo: "https://example.com/gedik.png",
49
+ supportedAssetClasses: [AssetClass.Equity]
50
+ };
51
+
52
+ const mockStock: BrokerStock = {
53
+ id: "61dd0d6f0ec2114146342fd0",
54
+ symbol: "TUPRS",
55
+ name: "Tüpraş",
56
+ assetType: AssetType.Stock,
57
+ assetClass: AssetClass.Equity
58
+ };
59
+
60
+ const mockStock2: BrokerStock = {
61
+ id: "61dd0d6f0ec2114146342fd1",
62
+ symbol: "GARAN",
63
+ name: "Garanti Bankası",
64
+ assetType: AssetType.Stock,
65
+ assetClass: AssetClass.Equity
66
+ };
67
+
68
+ const mockBrokerStats: BrokerStats = {
69
+ totalBuyAmount: 1000000,
70
+ totalSellAmount: 800000,
71
+ netAmount: 200000,
72
+ totalBuyVolume: 50000,
73
+ totalSellVolume: 40000,
74
+ totalVolume: 90000,
75
+ totalAmount: 1800000,
76
+ averageCost: 20.5
77
+ };
78
+
79
+ const mockBrokerItem: BrokerItem = {
80
+ ...mockBrokerStats,
81
+ broker: mockBroker,
82
+ stock: mockStock
83
+ };
84
+
85
+ const mockBrokerItem2: BrokerItem = {
86
+ ...mockBrokerStats,
87
+ totalBuyAmount: 900000,
88
+ totalSellAmount: 700000,
89
+ broker: mockBroker2,
90
+ stock: mockStock2
91
+ };
92
+
93
+ const mockBrokerList: BrokerList = {
94
+ recordCount: 2,
95
+ items: [mockBrokerItem, mockBrokerItem2],
96
+ totalStats: mockBrokerStats
97
+ };
98
+
99
+ const mockBrokersPaginatedResponse: PaginatedResponse<Broker> = {
100
+ recordCount: 2,
101
+ items: [mockBroker3, mockBroker4]
102
+ };
11
103
 
12
104
  describe("BrokerClient", () => {
13
105
  let brokerClient: BrokerClient;
@@ -29,36 +121,23 @@ describe("BrokerClient", () => {
29
121
  const fromDate = "2025-05-20";
30
122
  const toDate = "2025-05-28";
31
123
 
32
- test("getMarketBrokers returns valid and fully typed data", async () => {
33
- const response = await brokerClient.getMarketBrokers(
34
- Region.Tr,
35
- BrokerSort.TotalVolume,
36
- SortDirection.Desc,
37
- "2025-05-27",
38
- "2025-05-28",
39
- 0,
40
- 5
41
- );
42
-
43
- expect(response).toBeDefined();
44
- expect(typeof response.recordCount).toBe("number");
45
-
46
- const stats = response.totalStats;
47
- expect(stats).toMatchObject<BrokerStats>({
48
- totalBuyAmount: expect.any(Number),
49
- totalSellAmount: expect.any(Number),
50
- netAmount: expect.any(Number),
51
- totalBuyVolume: expect.any(Number),
52
- totalSellVolume: expect.any(Number),
53
- totalVolume: expect.any(Number),
54
- totalAmount: expect.any(Number),
55
- });
124
+ describe("Integration Tests", () => {
125
+ test("getMarketBrokers returns valid and fully typed data", async () => {
126
+ const response = await brokerClient.getMarketBrokers(
127
+ Region.Tr,
128
+ BrokerSort.TotalVolume,
129
+ SortDirection.Desc,
130
+ "2025-05-27",
131
+ "2025-05-28",
132
+ 0,
133
+ 5
134
+ );
56
135
 
57
- expect(Array.isArray(response.items)).toBe(true);
58
- expect(response.items.length).toBeGreaterThan(0);
136
+ expect(response).toBeDefined();
137
+ expect(typeof response.recordCount).toBe("number");
59
138
 
60
- for (const item of response.items) {
61
- expect(item).toMatchObject<BrokerStats>({
139
+ const stats = response.totalStats;
140
+ expect(stats).toMatchObject<BrokerStats>({
62
141
  totalBuyAmount: expect.any(Number),
63
142
  totalSellAmount: expect.any(Number),
64
143
  netAmount: expect.any(Number),
@@ -68,47 +147,48 @@ describe("BrokerClient", () => {
68
147
  totalAmount: expect.any(Number),
69
148
  });
70
149
 
71
- if (item.broker) {
72
- expect(item.broker).toMatchObject({
73
- id: expect.any(Number),
74
- symbol: expect.any(String),
75
- name: expect.any(String),
76
- longName: expect.any(String),
77
- logo: expect.any(String),
150
+ expect(Array.isArray(response.items)).toBe(true);
151
+ expect(response.items.length).toBeGreaterThan(0);
152
+
153
+ for (const item of response.items) {
154
+ expect(item).toMatchObject<BrokerStats>({
155
+ totalBuyAmount: expect.any(Number),
156
+ totalSellAmount: expect.any(Number),
157
+ netAmount: expect.any(Number),
158
+ totalBuyVolume: expect.any(Number),
159
+ totalSellVolume: expect.any(Number),
160
+ totalVolume: expect.any(Number),
161
+ totalAmount: expect.any(Number),
78
162
  });
79
- }
80
- }
81
- });
82
163
 
83
- test("getMarketStocks returns valid stock data", async () => {
84
- const response = await brokerClient.getMarketStocks(
85
- region,
86
- BrokerSort.TotalVolume,
87
- SortDirection.Desc,
88
- fromDate,
89
- toDate,
90
- 0,
91
- 5
92
- );
93
-
94
- expect(response).toBeDefined();
95
- expect(typeof response.recordCount).toBe("number");
96
-
97
- const stats = response.totalStats;
98
- expect(stats).toMatchObject<BrokerStats>({
99
- totalBuyAmount: expect.any(Number),
100
- totalSellAmount: expect.any(Number),
101
- netAmount: expect.any(Number),
102
- totalBuyVolume: expect.any(Number),
103
- totalSellVolume: expect.any(Number),
104
- totalVolume: expect.any(Number),
105
- totalAmount: expect.any(Number),
164
+ if (item.broker) {
165
+ expect(item.broker).toMatchObject({
166
+ id: expect.any(Number),
167
+ symbol: expect.any(String),
168
+ name: expect.any(String),
169
+ longName: expect.any(String),
170
+ logo: expect.any(String),
171
+ });
172
+ }
173
+ }
106
174
  });
107
175
 
108
- expect(Array.isArray(response.items)).toBe(true);
176
+ test("getMarketStocks returns valid stock data", async () => {
177
+ const response = await brokerClient.getMarketStocks(
178
+ region,
179
+ BrokerSort.TotalVolume,
180
+ SortDirection.Desc,
181
+ fromDate,
182
+ toDate,
183
+ 0,
184
+ 5
185
+ );
186
+
187
+ expect(response).toBeDefined();
188
+ expect(typeof response.recordCount).toBe("number");
109
189
 
110
- for (const item of response.items) {
111
- expect(item).toMatchObject<BrokerStats>({
190
+ const stats = response.totalStats;
191
+ expect(stats).toMatchObject<BrokerStats>({
112
192
  totalBuyAmount: expect.any(Number),
113
193
  totalSellAmount: expect.any(Number),
114
194
  netAmount: expect.any(Number),
@@ -118,48 +198,48 @@ describe("BrokerClient", () => {
118
198
  totalAmount: expect.any(Number),
119
199
  });
120
200
 
121
- if (item.stock) {
122
- expect(item.stock).toMatchObject({
123
- id: expect.any(String),
124
- symbol: expect.any(String),
125
- name: expect.any(String),
126
- assetType: expect.any(String),
127
- assetClass: expect.any(String),
201
+ expect(Array.isArray(response.items)).toBe(true);
202
+
203
+ for (const item of response.items) {
204
+ expect(item).toMatchObject<BrokerStats>({
205
+ totalBuyAmount: expect.any(Number),
206
+ totalSellAmount: expect.any(Number),
207
+ netAmount: expect.any(Number),
208
+ totalBuyVolume: expect.any(Number),
209
+ totalSellVolume: expect.any(Number),
210
+ totalVolume: expect.any(Number),
211
+ totalAmount: expect.any(Number),
128
212
  });
129
- }
130
- }
131
- });
132
213
 
133
- test("getBrokersByStock returns brokers for specific stock", async () => {
134
- const response = await brokerClient.getBrokersByStock(
135
- "TUPRS",
136
- region,
137
- BrokerSort.TotalVolume,
138
- SortDirection.Desc,
139
- fromDate,
140
- toDate,
141
- 0,
142
- 5
143
- );
144
-
145
- expect(response).toBeDefined();
146
- expect(typeof response.recordCount).toBe("number");
147
-
148
- const stats = response.totalStats;
149
- expect(stats).toMatchObject<BrokerStats>({
150
- totalBuyAmount: expect.any(Number),
151
- totalSellAmount: expect.any(Number),
152
- netAmount: expect.any(Number),
153
- totalBuyVolume: expect.any(Number),
154
- totalSellVolume: expect.any(Number),
155
- totalVolume: expect.any(Number),
156
- totalAmount: expect.any(Number),
214
+ if (item.stock) {
215
+ expect(item.stock).toMatchObject({
216
+ id: expect.any(String),
217
+ symbol: expect.any(String),
218
+ name: expect.any(String),
219
+ assetType: expect.any(String),
220
+ assetClass: expect.any(String),
221
+ });
222
+ }
223
+ }
157
224
  });
158
225
 
159
- expect(Array.isArray(response.items)).toBe(true);
226
+ test("getBrokersByStock returns brokers for specific stock", async () => {
227
+ const response = await brokerClient.getBrokersByStock(
228
+ "TUPRS",
229
+ region,
230
+ BrokerSort.TotalVolume,
231
+ SortDirection.Desc,
232
+ fromDate,
233
+ toDate,
234
+ 0,
235
+ 5
236
+ );
160
237
 
161
- for (const item of response.items) {
162
- expect(item).toMatchObject<BrokerStats>({
238
+ expect(response).toBeDefined();
239
+ expect(typeof response.recordCount).toBe("number");
240
+
241
+ const stats = response.totalStats;
242
+ expect(stats).toMatchObject<BrokerStats>({
163
243
  totalBuyAmount: expect.any(Number),
164
244
  totalSellAmount: expect.any(Number),
165
245
  netAmount: expect.any(Number),
@@ -169,52 +249,52 @@ describe("BrokerClient", () => {
169
249
  totalAmount: expect.any(Number),
170
250
  });
171
251
 
172
- if (item.broker) {
173
- expect(item.broker).toMatchObject({
174
- id: expect.any(Number),
175
- symbol: expect.any(String),
176
- name: expect.any(String),
177
- longName: expect.any(String),
178
- logo: expect.any(String),
252
+ expect(Array.isArray(response.items)).toBe(true);
253
+
254
+ for (const item of response.items) {
255
+ expect(item).toMatchObject<BrokerStats>({
256
+ totalBuyAmount: expect.any(Number),
257
+ totalSellAmount: expect.any(Number),
258
+ netAmount: expect.any(Number),
259
+ totalBuyVolume: expect.any(Number),
260
+ totalSellVolume: expect.any(Number),
261
+ totalVolume: expect.any(Number),
262
+ totalAmount: expect.any(Number),
179
263
  });
180
- }
181
264
 
182
- if ("averageCost" in item) {
183
- expect(item.averageCost).toEqual(expect.any(Number));
184
- }
185
- }
186
- });
265
+ if (item.broker) {
266
+ expect(item.broker).toMatchObject({
267
+ id: expect.any(Number),
268
+ symbol: expect.any(String),
269
+ name: expect.any(String),
270
+ longName: expect.any(String),
271
+ logo: expect.any(String),
272
+ });
273
+ }
187
274
 
188
- test("getStocksByBroker returns stocks for specific broker", async () => {
189
- const response = await brokerClient.getStocksByBroker(
190
- "BIYKR",
191
- region,
192
- BrokerSort.TotalVolume,
193
- SortDirection.Desc,
194
- fromDate,
195
- toDate,
196
- 0,
197
- 5
198
- );
199
-
200
- expect(response).toBeDefined();
201
- expect(typeof response.recordCount).toBe("number");
202
-
203
- const stats = response.totalStats;
204
- expect(stats).toMatchObject<BrokerStats>({
205
- totalBuyAmount: expect.any(Number),
206
- totalSellAmount: expect.any(Number),
207
- netAmount: expect.any(Number),
208
- totalBuyVolume: expect.any(Number),
209
- totalSellVolume: expect.any(Number),
210
- totalVolume: expect.any(Number),
211
- totalAmount: expect.any(Number),
275
+ if ("averageCost" in item) {
276
+ expect(item.averageCost).toEqual(expect.any(Number));
277
+ }
278
+ }
212
279
  });
213
280
 
214
- expect(Array.isArray(response.items)).toBe(true);
281
+ test("getStocksByBroker returns stocks for specific broker", async () => {
282
+ const response = await brokerClient.getStocksByBroker(
283
+ "BIYKR",
284
+ region,
285
+ BrokerSort.TotalVolume,
286
+ SortDirection.Desc,
287
+ fromDate,
288
+ toDate,
289
+ 0,
290
+ 5
291
+ );
215
292
 
216
- for (const item of response.items) {
217
- expect(item).toMatchObject<BrokerStats>({
293
+ expect(response).toBeDefined();
294
+ expect(typeof response.recordCount).toBe("number");
295
+
296
+ const stats = response.totalStats;
297
+ expect(stats).toMatchObject<BrokerStats>({
218
298
  totalBuyAmount: expect.any(Number),
219
299
  totalSellAmount: expect.any(Number),
220
300
  netAmount: expect.any(Number),
@@ -224,15 +304,370 @@ describe("BrokerClient", () => {
224
304
  totalAmount: expect.any(Number),
225
305
  });
226
306
 
227
- if (item.stock) {
228
- expect(item.stock).toMatchObject({
229
- id: expect.any(String),
307
+ expect(Array.isArray(response.items)).toBe(true);
308
+
309
+ for (const item of response.items) {
310
+ expect(item).toMatchObject<BrokerStats>({
311
+ totalBuyAmount: expect.any(Number),
312
+ totalSellAmount: expect.any(Number),
313
+ netAmount: expect.any(Number),
314
+ totalBuyVolume: expect.any(Number),
315
+ totalSellVolume: expect.any(Number),
316
+ totalVolume: expect.any(Number),
317
+ totalAmount: expect.any(Number),
318
+ });
319
+
320
+ if (item.stock) {
321
+ expect(item.stock).toMatchObject({
322
+ id: expect.any(String),
323
+ symbol: expect.any(String),
324
+ name: expect.any(String),
325
+ assetType: expect.any(String),
326
+ assetClass: expect.any(String),
327
+ });
328
+ }
329
+ }
330
+ });
331
+
332
+ test("getBrokers with assetClass parameter", async () => {
333
+ const response = await brokerClient.getBrokers(
334
+ Region.Tr,
335
+ 0,
336
+ 10,
337
+ AssetClass.Equity
338
+ );
339
+
340
+ expect(response).toBeDefined();
341
+ expect(typeof response.recordCount).toBe("number");
342
+ expect(Array.isArray(response.items)).toBe(true);
343
+
344
+ for (const broker of response.items) {
345
+ expect(broker).toMatchObject({
346
+ id: expect.any(Number),
230
347
  symbol: expect.any(String),
231
348
  name: expect.any(String),
232
- assetType: expect.any(String),
233
- assetClass: expect.any(String),
349
+ longName: expect.any(String),
350
+ logo: expect.any(String),
351
+ });
352
+ expect(Array.isArray(broker.supportedAssetClasses)).toBe(true);
353
+ expect(broker.supportedAssetClasses).toEqual([AssetClass.Equity]);
354
+ }
355
+ });
356
+
357
+ test("getBrokers without assetClass parameter", async () => {
358
+ const response = await brokerClient.getBrokers(
359
+ Region.Tr,
360
+ 0,
361
+ 10
362
+ );
363
+
364
+ expect(response).toBeDefined();
365
+ expect(typeof response.recordCount).toBe("number");
366
+ expect(Array.isArray(response.items)).toBe(true);
367
+
368
+ for (const broker of response.items) {
369
+ expect(broker).toMatchObject({
370
+ id: expect.any(Number),
371
+ symbol: expect.any(String),
372
+ name: expect.any(String),
373
+ longName: expect.any(String),
374
+ logo: expect.any(String),
234
375
  });
235
376
  }
236
- }
377
+ });
378
+ });
379
+
380
+ describe("Mock Tests", () => {
381
+ beforeEach(() => {
382
+ jest.clearAllMocks();
383
+ });
384
+
385
+ describe("getMarketBrokers", () => {
386
+ test("should return market brokers with stats", async () => {
387
+ jest.spyOn(brokerClient, 'getMarketBrokers').mockResolvedValue(mockBrokerList);
388
+
389
+ const response = await brokerClient.getMarketBrokers(
390
+ Region.Tr,
391
+ BrokerSort.TotalVolume,
392
+ SortDirection.Desc,
393
+ fromDate,
394
+ toDate,
395
+ 0,
396
+ 5
397
+ );
398
+
399
+ expect(response.recordCount).toBe(2);
400
+ expect(response.items).toHaveLength(2);
401
+ expect(response.totalStats).toEqual(mockBrokerStats);
402
+
403
+ const firstItem = response.items[0];
404
+ expect(firstItem.broker?.symbol).toBe("BIYKR");
405
+ expect(firstItem.totalBuyAmount).toBe(1000000);
406
+ expect(firstItem.totalSellAmount).toBe(800000);
407
+
408
+ expect(brokerClient.getMarketBrokers).toHaveBeenCalledWith(
409
+ Region.Tr,
410
+ BrokerSort.TotalVolume,
411
+ SortDirection.Desc,
412
+ fromDate,
413
+ toDate,
414
+ 0,
415
+ 5
416
+ );
417
+ });
418
+
419
+ test("should handle empty response", async () => {
420
+ const emptyResponse: BrokerList = {
421
+ recordCount: 0,
422
+ items: [],
423
+ totalStats: {
424
+ totalBuyAmount: 0,
425
+ totalSellAmount: 0,
426
+ netAmount: 0,
427
+ totalBuyVolume: 0,
428
+ totalSellVolume: 0,
429
+ totalVolume: 0,
430
+ totalAmount: 0
431
+ }
432
+ };
433
+ jest.spyOn(brokerClient, 'getMarketBrokers').mockResolvedValue(emptyResponse);
434
+
435
+ const response = await brokerClient.getMarketBrokers(
436
+ Region.Tr,
437
+ BrokerSort.TotalVolume,
438
+ SortDirection.Desc,
439
+ fromDate,
440
+ toDate,
441
+ 0,
442
+ 5
443
+ );
444
+
445
+ expect(response.recordCount).toBe(0);
446
+ expect(response.items).toHaveLength(0);
447
+ expect(response.totalStats.totalAmount).toBe(0);
448
+ });
449
+ });
450
+
451
+ describe("getMarketStocks", () => {
452
+ test("should return market stocks with stats", async () => {
453
+ jest.spyOn(brokerClient, 'getMarketStocks').mockResolvedValue(mockBrokerList);
454
+
455
+ const response = await brokerClient.getMarketStocks(
456
+ Region.Tr,
457
+ BrokerSort.TotalVolume,
458
+ SortDirection.Desc,
459
+ fromDate,
460
+ toDate,
461
+ 0,
462
+ 5
463
+ );
464
+
465
+ expect(response.recordCount).toBe(2);
466
+ expect(response.items).toHaveLength(2);
467
+ expect(response.totalStats).toEqual(mockBrokerStats);
468
+
469
+ const firstItem = response.items[0];
470
+ expect(firstItem.stock?.symbol).toBe("TUPRS");
471
+ expect(firstItem.stock?.assetType).toBe(AssetType.Stock);
472
+ expect(firstItem.stock?.assetClass).toBe(AssetClass.Equity);
473
+
474
+ expect(brokerClient.getMarketStocks).toHaveBeenCalledWith(
475
+ Region.Tr,
476
+ BrokerSort.TotalVolume,
477
+ SortDirection.Desc,
478
+ fromDate,
479
+ toDate,
480
+ 0,
481
+ 5
482
+ );
483
+ });
484
+ });
485
+
486
+ describe("getBrokersByStock", () => {
487
+ test("should return brokers for specific stock", async () => {
488
+ jest.spyOn(brokerClient, 'getBrokersByStock').mockResolvedValue(mockBrokerList);
489
+
490
+ const response = await brokerClient.getBrokersByStock(
491
+ "TUPRS",
492
+ Region.Tr,
493
+ BrokerSort.TotalVolume,
494
+ SortDirection.Desc,
495
+ fromDate,
496
+ toDate,
497
+ 0,
498
+ 5
499
+ );
500
+
501
+ expect(response.recordCount).toBe(2);
502
+ expect(response.items).toHaveLength(2);
503
+ expect(response.totalStats).toEqual(mockBrokerStats);
504
+
505
+ const firstItem = response.items[0];
506
+ expect(firstItem.broker?.symbol).toBe("BIYKR");
507
+ expect(firstItem.averageCost).toBe(20.5);
508
+
509
+ expect(brokerClient.getBrokersByStock).toHaveBeenCalledWith(
510
+ "TUPRS",
511
+ Region.Tr,
512
+ BrokerSort.TotalVolume,
513
+ SortDirection.Desc,
514
+ fromDate,
515
+ toDate,
516
+ 0,
517
+ 5
518
+ );
519
+ });
520
+
521
+ test("should handle invalid stock symbol", async () => {
522
+ jest.spyOn(brokerClient, 'getBrokersByStock').mockRejectedValue(new Error("Invalid stock symbol"));
523
+
524
+ await expect(brokerClient.getBrokersByStock(
525
+ "INVALID",
526
+ Region.Tr,
527
+ BrokerSort.TotalVolume,
528
+ SortDirection.Desc,
529
+ fromDate,
530
+ toDate,
531
+ 0,
532
+ 5
533
+ )).rejects.toThrow("Invalid stock symbol");
534
+ });
535
+ });
536
+
537
+ describe("getStocksByBroker", () => {
538
+ test("should return stocks for specific broker", async () => {
539
+ jest.spyOn(brokerClient, 'getStocksByBroker').mockResolvedValue(mockBrokerList);
540
+
541
+ const response = await brokerClient.getStocksByBroker(
542
+ "BIYKR",
543
+ Region.Tr,
544
+ BrokerSort.TotalVolume,
545
+ SortDirection.Desc,
546
+ fromDate,
547
+ toDate,
548
+ 0,
549
+ 5
550
+ );
551
+
552
+ expect(response.recordCount).toBe(2);
553
+ expect(response.items).toHaveLength(2);
554
+ expect(response.totalStats).toEqual(mockBrokerStats);
555
+
556
+ const firstItem = response.items[0];
557
+ expect(firstItem.stock?.symbol).toBe("TUPRS");
558
+ expect(firstItem.stock?.assetType).toBe(AssetType.Stock);
559
+
560
+ expect(brokerClient.getStocksByBroker).toHaveBeenCalledWith(
561
+ "BIYKR",
562
+ Region.Tr,
563
+ BrokerSort.TotalVolume,
564
+ SortDirection.Desc,
565
+ fromDate,
566
+ toDate,
567
+ 0,
568
+ 5
569
+ );
570
+ });
571
+
572
+ test("should handle invalid broker symbol", async () => {
573
+ jest.spyOn(brokerClient, 'getStocksByBroker').mockRejectedValue(new Error("Invalid broker symbol"));
574
+
575
+ await expect(brokerClient.getStocksByBroker(
576
+ "INVALID",
577
+ Region.Tr,
578
+ BrokerSort.TotalVolume,
579
+ SortDirection.Desc,
580
+ fromDate,
581
+ toDate,
582
+ 0,
583
+ 5
584
+ )).rejects.toThrow("Invalid broker symbol");
585
+ });
586
+ });
587
+
588
+ describe("getBrokers", () => {
589
+ test("should return paginated broker list", async () => {
590
+ jest.spyOn(brokerClient, 'getBrokers').mockResolvedValue(mockBrokersPaginatedResponse);
591
+
592
+ const response = await brokerClient.getBrokers(
593
+ Region.Tr,
594
+ 0,
595
+ 5,
596
+ AssetClass.Equity
597
+ );
598
+
599
+ expect(response.recordCount).toBe(2);
600
+ expect(response.items).toHaveLength(2);
601
+
602
+ const firstBroker = response.items[0];
603
+ expect(firstBroker.id).toBe(1001);
604
+ expect(firstBroker.symbol).toBe("BIYKR");
605
+ expect(firstBroker.name).toBe("BİYİKLI YATIRIM");
606
+ expect(firstBroker.longName).toBe("Bıyıklı Yatırım Menkul Değerler A.Ş.");
607
+ expect(firstBroker.logo).toBe("https://example.com/biykr.png");
608
+ expect(firstBroker.supportedAssetClasses).toEqual([AssetClass.Equity]);
609
+
610
+ expect(brokerClient.getBrokers).toHaveBeenCalledWith(
611
+ Region.Tr,
612
+ 0,
613
+ 5,
614
+ AssetClass.Equity
615
+ );
616
+ });
617
+
618
+ test("should handle getBrokers without assetClass parameter", async () => {
619
+ jest.spyOn(brokerClient, 'getBrokers').mockResolvedValue(mockBrokersPaginatedResponse);
620
+
621
+ const response = await brokerClient.getBrokers(
622
+ Region.Tr,
623
+ 0,
624
+ 5
625
+ );
626
+
627
+ expect(response.recordCount).toBe(2);
628
+ expect(response.items).toHaveLength(2);
629
+
630
+ const firstBroker = response.items[0];
631
+ expect(firstBroker.id).toBe(1001);
632
+ expect(firstBroker.symbol).toBe("BIYKR");
633
+ expect(firstBroker.name).toBe("BİYİKLI YATIRIM");
634
+ expect(firstBroker.longName).toBe("Bıyıklı Yatırım Menkul Değerler A.Ş.");
635
+ expect(firstBroker.logo).toBe("https://example.com/biykr.png");
636
+
637
+ expect(brokerClient.getBrokers).toHaveBeenCalledWith(
638
+ Region.Tr,
639
+ 0,
640
+ 5
641
+ );
642
+ });
643
+
644
+ test("should handle empty brokers response", async () => {
645
+ const emptyResponse: PaginatedResponse<Broker> = {
646
+ recordCount: 0,
647
+ items: []
648
+ };
649
+ jest.spyOn(brokerClient, 'getBrokers').mockResolvedValue(emptyResponse);
650
+
651
+ const response = await brokerClient.getBrokers(
652
+ Region.Tr,
653
+ 0,
654
+ 10
655
+ );
656
+
657
+ expect(response.recordCount).toBe(0);
658
+ expect(response.items).toHaveLength(0);
659
+ });
660
+
661
+ test("should handle getBrokers error", async () => {
662
+ jest.spyOn(brokerClient, 'getBrokers').mockRejectedValue(new Error("Unsupported asset class"));
663
+
664
+ await expect(brokerClient.getBrokers(
665
+ Region.Tr,
666
+ 0,
667
+ 10,
668
+ AssetClass.Crypto
669
+ )).rejects.toThrow("Unsupported asset class");
670
+ });
671
+ });
237
672
  });
238
- });
673
+ });