laplace-api 4.7.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 -68
- 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
package/src/test/broker.test.ts
CHANGED
|
@@ -14,91 +14,151 @@ import {
|
|
|
14
14
|
} from "../client/broker";
|
|
15
15
|
import { AssetType, AssetClass } from "../client/stocks";
|
|
16
16
|
import { PaginatedResponse } from "../client/capital_increase";
|
|
17
|
+
import { AxiosInstance } from "axios";
|
|
17
18
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
longName: "Gedik Yatırım Menkul Değerler A.Ş.",
|
|
48
|
-
logo: "https://example.com/gedik.png",
|
|
49
|
-
supportedAssetClasses: [AssetClass.Equity]
|
|
19
|
+
const fxGetMarketBrokers = {
|
|
20
|
+
recordCount: 2,
|
|
21
|
+
items: [
|
|
22
|
+
{
|
|
23
|
+
broker: {
|
|
24
|
+
id: 1,
|
|
25
|
+
symbol: "BIDZY",
|
|
26
|
+
name: "DENIZ YATIRIM",
|
|
27
|
+
longName: "DENIZ YATIRIM MENKUL KIYMETLER A.S.",
|
|
28
|
+
logo: "https://finfree-storage.s3.eu-central-1.amazonaws.com/brokers/BIDZY.svg",
|
|
29
|
+
},
|
|
30
|
+
netAmount: 2500000.0,
|
|
31
|
+
totalAmount: 10000000.0,
|
|
32
|
+
totalVolume: 200000,
|
|
33
|
+
totalBuyAmount: 6250000.0,
|
|
34
|
+
totalBuyVolume: 100000,
|
|
35
|
+
totalSellAmount: 3750000.0,
|
|
36
|
+
totalSellVolume: 100000,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
totalStats: {
|
|
40
|
+
netAmount: 4000000.0,
|
|
41
|
+
totalAmount: 17500000.0,
|
|
42
|
+
totalVolume: 350000,
|
|
43
|
+
totalBuyAmount: 10750000.0,
|
|
44
|
+
totalBuyVolume: 175000,
|
|
45
|
+
totalSellAmount: 6750000.0,
|
|
46
|
+
totalSellVolume: 175000,
|
|
47
|
+
},
|
|
50
48
|
};
|
|
51
49
|
|
|
52
|
-
const mockStock: BrokerStock = {
|
|
53
|
-
id: "61dd0d6f0ec2114146342fd0",
|
|
54
|
-
symbol: "TUPRS",
|
|
55
|
-
name: "Tüpraş",
|
|
56
|
-
assetType: AssetType.Stock,
|
|
57
|
-
assetClass: AssetClass.Equity
|
|
58
|
-
};
|
|
59
50
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
51
|
+
const fxGetMarketStocks = {
|
|
52
|
+
recordCount: 2,
|
|
53
|
+
items: [
|
|
54
|
+
{
|
|
55
|
+
stock: {
|
|
56
|
+
id: "61dd0d670ec2114146342fa5",
|
|
57
|
+
name: "SASA Polyester",
|
|
58
|
+
symbol: "SASA",
|
|
59
|
+
assetType: AssetType.Stock,
|
|
60
|
+
assetClass: AssetClass.Equity,
|
|
61
|
+
},
|
|
62
|
+
averageCost: 2.91,
|
|
63
|
+
netAmount: 1000000.0,
|
|
64
|
+
totalAmount: 5000000.0,
|
|
65
|
+
totalVolume: 100000,
|
|
66
|
+
totalBuyAmount: 3000000.0,
|
|
67
|
+
totalBuyVolume: 50000,
|
|
68
|
+
totalSellAmount: 2000000.0,
|
|
69
|
+
totalSellVolume: 50000,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
totalStats: {
|
|
73
|
+
averageCost: 2.91,
|
|
74
|
+
netAmount: 1750000.0,
|
|
75
|
+
totalAmount: 8750000.0,
|
|
76
|
+
totalVolume: 175000,
|
|
77
|
+
totalBuyAmount: 5250000.0,
|
|
78
|
+
totalBuyVolume: 87500,
|
|
79
|
+
totalSellAmount: 3500000.0,
|
|
80
|
+
totalSellVolume: 87500,
|
|
81
|
+
},
|
|
66
82
|
};
|
|
67
83
|
|
|
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
84
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
const fxGetBrokersByStock = {
|
|
86
|
+
recordCount: 2,
|
|
87
|
+
items: [
|
|
88
|
+
{
|
|
89
|
+
broker: {
|
|
90
|
+
id: 1,
|
|
91
|
+
symbol: "BIMLB",
|
|
92
|
+
name: "BIMLB",
|
|
93
|
+
longName: "BIM Yatırım Menkul Değerler A.Ş.",
|
|
94
|
+
logo: "https://finfree-storage.s3.eu-central-1.amazonaws.com/broker-logos/bimlb.png",
|
|
95
|
+
},
|
|
96
|
+
averageCost: 2.91,
|
|
97
|
+
netAmount: 500000.0,
|
|
98
|
+
totalAmount: 2000000.0,
|
|
99
|
+
totalVolume: 40000,
|
|
100
|
+
totalBuyAmount: 1250000.0,
|
|
101
|
+
totalBuyVolume: 20000,
|
|
102
|
+
totalSellAmount: 750000.0,
|
|
103
|
+
totalSellVolume: 20000,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
totalStats: {
|
|
107
|
+
averageCost: 2.91,
|
|
108
|
+
netAmount: 800000.0,
|
|
109
|
+
totalAmount: 3500000.0,
|
|
110
|
+
totalVolume: 70000,
|
|
111
|
+
totalBuyAmount: 2150000.0,
|
|
112
|
+
totalBuyVolume: 35000,
|
|
113
|
+
totalSellAmount: 1350000.0,
|
|
114
|
+
totalSellVolume: 35000,
|
|
115
|
+
},
|
|
83
116
|
};
|
|
84
117
|
|
|
85
|
-
const mockBrokerItem2: BrokerItem = {
|
|
86
|
-
...mockBrokerStats,
|
|
87
|
-
totalBuyAmount: 900000,
|
|
88
|
-
totalSellAmount: 700000,
|
|
89
|
-
broker: mockBroker2,
|
|
90
|
-
stock: mockStock2
|
|
91
|
-
};
|
|
92
118
|
|
|
93
|
-
const
|
|
119
|
+
const fxGetStocksByBroker = {
|
|
94
120
|
recordCount: 2,
|
|
95
|
-
items: [
|
|
96
|
-
|
|
121
|
+
items: [
|
|
122
|
+
{
|
|
123
|
+
stock: {
|
|
124
|
+
id: "61dd0d670ec2114146342fa5",
|
|
125
|
+
name: "SASA Polyester",
|
|
126
|
+
symbol: "SASA",
|
|
127
|
+
assetType: AssetType.Stock,
|
|
128
|
+
assetClass: AssetClass.Equity,
|
|
129
|
+
},
|
|
130
|
+
netAmount: 500000.0,
|
|
131
|
+
totalAmount: 2000000.0,
|
|
132
|
+
totalVolume: 40000,
|
|
133
|
+
totalBuyAmount: 1250000.0,
|
|
134
|
+
totalBuyVolume: 20000,
|
|
135
|
+
totalSellAmount: 750000.0,
|
|
136
|
+
totalSellVolume: 20000,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
totalStats: {
|
|
140
|
+
netAmount: 800000.0,
|
|
141
|
+
totalAmount: 3500000.0,
|
|
142
|
+
totalVolume: 70000,
|
|
143
|
+
totalBuyAmount: 2150000.0,
|
|
144
|
+
totalBuyVolume: 35000,
|
|
145
|
+
totalSellAmount: 1350000.0,
|
|
146
|
+
totalSellVolume: 35000,
|
|
147
|
+
},
|
|
97
148
|
};
|
|
98
149
|
|
|
99
|
-
const
|
|
100
|
-
recordCount:
|
|
101
|
-
items: [
|
|
150
|
+
const fxGetBrokers = {
|
|
151
|
+
recordCount: 239,
|
|
152
|
+
items: [
|
|
153
|
+
{
|
|
154
|
+
id: 1,
|
|
155
|
+
symbol: "BIDZY",
|
|
156
|
+
name: "DENIZ YATIRIM",
|
|
157
|
+
longName: "DENIZ YATIRIM MENKUL KIYMETLER A.S.",
|
|
158
|
+
logo: "https://finfree-storage.s3.eu-central-1.amazonaws.com/brokers/BIDZY.svg",
|
|
159
|
+
supportedAssetClasses: [AssetClass.Equity],
|
|
160
|
+
},
|
|
161
|
+
],
|
|
102
162
|
};
|
|
103
163
|
|
|
104
164
|
describe("BrokerClient", () => {
|
|
@@ -118,57 +178,57 @@ describe("BrokerClient", () => {
|
|
|
118
178
|
});
|
|
119
179
|
|
|
120
180
|
const region = Region.Tr;
|
|
121
|
-
const fromDate = "2025-
|
|
122
|
-
const toDate = "2025-
|
|
181
|
+
const fromDate = "2025-06-01";
|
|
182
|
+
const toDate = "2025-06-30";
|
|
123
183
|
|
|
124
184
|
describe("Integration Tests", () => {
|
|
125
|
-
|
|
185
|
+
jest.setTimeout(60_000);
|
|
186
|
+
test("getMarketBrokers returns valid data", async () => {
|
|
126
187
|
const response = await brokerClient.getMarketBrokers(
|
|
127
188
|
Region.Tr,
|
|
128
189
|
BrokerSort.TotalVolume,
|
|
129
190
|
SortDirection.Desc,
|
|
130
191
|
"2025-05-27",
|
|
131
192
|
"2025-05-28",
|
|
132
|
-
|
|
133
|
-
|
|
193
|
+
5,
|
|
194
|
+
0
|
|
134
195
|
);
|
|
135
196
|
|
|
136
197
|
expect(response).toBeDefined();
|
|
137
198
|
expect(typeof response.recordCount).toBe("number");
|
|
199
|
+
expect(response.recordCount).toBeGreaterThanOrEqual(0);
|
|
138
200
|
|
|
139
201
|
const stats = response.totalStats;
|
|
140
|
-
expect(stats).
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
totalAmount: expect.any(Number),
|
|
148
|
-
});
|
|
202
|
+
expect(typeof stats.totalBuyAmount).toBe("number");
|
|
203
|
+
expect(typeof stats.totalSellAmount).toBe("number");
|
|
204
|
+
expect(typeof stats.netAmount).toBe("number");
|
|
205
|
+
expect(typeof stats.totalBuyVolume).toBe("number");
|
|
206
|
+
expect(typeof stats.totalSellVolume).toBe("number");
|
|
207
|
+
expect(typeof stats.totalVolume).toBe("number");
|
|
208
|
+
expect(typeof stats.totalAmount).toBe("number");
|
|
149
209
|
|
|
150
210
|
expect(Array.isArray(response.items)).toBe(true);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
});
|
|
211
|
+
|
|
212
|
+
if (response.items.length > 0) {
|
|
213
|
+
const item = response.items[0];
|
|
214
|
+
|
|
215
|
+
expect(typeof item.totalBuyAmount).toBe("number");
|
|
216
|
+
expect(typeof item.totalSellAmount).toBe("number");
|
|
217
|
+
expect(typeof item.netAmount).toBe("number");
|
|
218
|
+
expect(typeof item.totalBuyVolume).toBe("number");
|
|
219
|
+
expect(typeof item.totalSellVolume).toBe("number");
|
|
220
|
+
expect(typeof item.totalVolume).toBe("number");
|
|
221
|
+
expect(typeof item.totalAmount).toBe("number");
|
|
163
222
|
|
|
164
223
|
if (item.broker) {
|
|
165
|
-
expect(item.broker).
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
224
|
+
expect(typeof item.broker.id).toBe("number");
|
|
225
|
+
expect(typeof item.broker.symbol).toBe("string");
|
|
226
|
+
expect(typeof item.broker.name).toBe("string");
|
|
227
|
+
expect(typeof item.broker.longName).toBe("string");
|
|
228
|
+
// python tarafında logo None olabilir kuralı vardı -> burada da izin ver
|
|
229
|
+
expect(
|
|
230
|
+
typeof item.broker.logo === "string" || item.broker.logo == null
|
|
231
|
+
).toBe(true);
|
|
172
232
|
}
|
|
173
233
|
}
|
|
174
234
|
});
|
|
@@ -180,45 +240,47 @@ describe("BrokerClient", () => {
|
|
|
180
240
|
SortDirection.Desc,
|
|
181
241
|
fromDate,
|
|
182
242
|
toDate,
|
|
183
|
-
|
|
184
|
-
|
|
243
|
+
5,
|
|
244
|
+
0
|
|
185
245
|
);
|
|
186
246
|
|
|
187
247
|
expect(response).toBeDefined();
|
|
188
248
|
expect(typeof response.recordCount).toBe("number");
|
|
249
|
+
expect(response.recordCount).toBeGreaterThanOrEqual(0);
|
|
189
250
|
|
|
190
251
|
const stats = response.totalStats;
|
|
191
|
-
expect(stats).
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
totalAmount: expect.any(Number),
|
|
199
|
-
});
|
|
252
|
+
expect(typeof stats.totalBuyAmount).toBe("number");
|
|
253
|
+
expect(typeof stats.totalSellAmount).toBe("number");
|
|
254
|
+
expect(typeof stats.netAmount).toBe("number");
|
|
255
|
+
expect(typeof stats.totalBuyVolume).toBe("number");
|
|
256
|
+
expect(typeof stats.totalSellVolume).toBe("number");
|
|
257
|
+
expect(typeof stats.totalVolume).toBe("number");
|
|
258
|
+
expect(typeof stats.totalAmount).toBe("number");
|
|
200
259
|
|
|
201
260
|
expect(Array.isArray(response.items)).toBe(true);
|
|
202
261
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
262
|
+
if (response.items.length > 0) {
|
|
263
|
+
const item = response.items[0];
|
|
264
|
+
|
|
265
|
+
expect(typeof item.totalBuyAmount).toBe("number");
|
|
266
|
+
expect(typeof item.totalSellAmount).toBe("number");
|
|
267
|
+
expect(typeof item.netAmount).toBe("number");
|
|
268
|
+
expect(typeof item.totalBuyVolume).toBe("number");
|
|
269
|
+
expect(typeof item.totalSellVolume).toBe("number");
|
|
270
|
+
expect(typeof item.totalVolume).toBe("number");
|
|
271
|
+
expect(typeof item.totalAmount).toBe("number");
|
|
213
272
|
|
|
214
273
|
if (item.stock) {
|
|
215
|
-
expect(item.stock).
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
274
|
+
expect(typeof item.stock.id).toBe("string");
|
|
275
|
+
expect(typeof item.stock.symbol).toBe("string");
|
|
276
|
+
expect(typeof item.stock.name).toBe("string");
|
|
277
|
+
expect(typeof item.stock.assetType).toBe("string");
|
|
278
|
+
expect(typeof item.stock.assetClass).toBe("string");
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// bu endpoint averageCost döndürüyorsa kontrol et (python’da market stock list’te vardı)
|
|
282
|
+
if ("averageCost" in item) {
|
|
283
|
+
expect(typeof (item as any).averageCost).toBe("number");
|
|
222
284
|
}
|
|
223
285
|
}
|
|
224
286
|
});
|
|
@@ -231,49 +293,48 @@ describe("BrokerClient", () => {
|
|
|
231
293
|
SortDirection.Desc,
|
|
232
294
|
fromDate,
|
|
233
295
|
toDate,
|
|
234
|
-
|
|
235
|
-
|
|
296
|
+
5,
|
|
297
|
+
0
|
|
236
298
|
);
|
|
237
299
|
|
|
238
300
|
expect(response).toBeDefined();
|
|
239
301
|
expect(typeof response.recordCount).toBe("number");
|
|
302
|
+
expect(response.recordCount).toBeGreaterThanOrEqual(0);
|
|
240
303
|
|
|
241
304
|
const stats = response.totalStats;
|
|
242
|
-
expect(stats).
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
totalAmount: expect.any(Number),
|
|
250
|
-
});
|
|
305
|
+
expect(typeof stats.totalBuyAmount).toBe("number");
|
|
306
|
+
expect(typeof stats.totalSellAmount).toBe("number");
|
|
307
|
+
expect(typeof stats.netAmount).toBe("number");
|
|
308
|
+
expect(typeof stats.totalBuyVolume).toBe("number");
|
|
309
|
+
expect(typeof stats.totalSellVolume).toBe("number");
|
|
310
|
+
expect(typeof stats.totalVolume).toBe("number");
|
|
311
|
+
expect(typeof stats.totalAmount).toBe("number");
|
|
251
312
|
|
|
252
313
|
expect(Array.isArray(response.items)).toBe(true);
|
|
253
314
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
315
|
+
if (response.items.length > 0) {
|
|
316
|
+
const item = response.items[0];
|
|
317
|
+
|
|
318
|
+
expect(typeof item.totalBuyAmount).toBe("number");
|
|
319
|
+
expect(typeof item.totalSellAmount).toBe("number");
|
|
320
|
+
expect(typeof item.netAmount).toBe("number");
|
|
321
|
+
expect(typeof item.totalBuyVolume).toBe("number");
|
|
322
|
+
expect(typeof item.totalSellVolume).toBe("number");
|
|
323
|
+
expect(typeof item.totalVolume).toBe("number");
|
|
324
|
+
expect(typeof item.totalAmount).toBe("number");
|
|
264
325
|
|
|
265
326
|
if (item.broker) {
|
|
266
|
-
expect(item.broker).
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
logo
|
|
272
|
-
|
|
327
|
+
expect(typeof item.broker.id).toBe("number");
|
|
328
|
+
expect(typeof item.broker.symbol).toBe("string");
|
|
329
|
+
expect(typeof item.broker.name).toBe("string");
|
|
330
|
+
expect(typeof item.broker.longName).toBe("string");
|
|
331
|
+
expect(
|
|
332
|
+
typeof item.broker.logo === "string" || item.broker.logo == null
|
|
333
|
+
).toBe(true);
|
|
273
334
|
}
|
|
274
335
|
|
|
275
336
|
if ("averageCost" in item) {
|
|
276
|
-
expect(item.averageCost).
|
|
337
|
+
expect(typeof (item as any).averageCost).toBe("number");
|
|
277
338
|
}
|
|
278
339
|
}
|
|
279
340
|
});
|
|
@@ -286,45 +347,46 @@ describe("BrokerClient", () => {
|
|
|
286
347
|
SortDirection.Desc,
|
|
287
348
|
fromDate,
|
|
288
349
|
toDate,
|
|
289
|
-
|
|
290
|
-
|
|
350
|
+
5,
|
|
351
|
+
0
|
|
291
352
|
);
|
|
292
353
|
|
|
293
354
|
expect(response).toBeDefined();
|
|
294
355
|
expect(typeof response.recordCount).toBe("number");
|
|
356
|
+
expect(response.recordCount).toBeGreaterThanOrEqual(0);
|
|
295
357
|
|
|
296
358
|
const stats = response.totalStats;
|
|
297
|
-
expect(stats).
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
totalAmount: expect.any(Number),
|
|
305
|
-
});
|
|
359
|
+
expect(typeof stats.totalBuyAmount).toBe("number");
|
|
360
|
+
expect(typeof stats.totalSellAmount).toBe("number");
|
|
361
|
+
expect(typeof stats.netAmount).toBe("number");
|
|
362
|
+
expect(typeof stats.totalBuyVolume).toBe("number");
|
|
363
|
+
expect(typeof stats.totalSellVolume).toBe("number");
|
|
364
|
+
expect(typeof stats.totalVolume).toBe("number");
|
|
365
|
+
expect(typeof stats.totalAmount).toBe("number");
|
|
306
366
|
|
|
307
367
|
expect(Array.isArray(response.items)).toBe(true);
|
|
308
368
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
369
|
+
if (response.items.length > 0) {
|
|
370
|
+
const item = response.items[0];
|
|
371
|
+
|
|
372
|
+
expect(typeof item.totalBuyAmount).toBe("number");
|
|
373
|
+
expect(typeof item.totalSellAmount).toBe("number");
|
|
374
|
+
expect(typeof item.netAmount).toBe("number");
|
|
375
|
+
expect(typeof item.totalBuyVolume).toBe("number");
|
|
376
|
+
expect(typeof item.totalSellVolume).toBe("number");
|
|
377
|
+
expect(typeof item.totalVolume).toBe("number");
|
|
378
|
+
expect(typeof item.totalAmount).toBe("number");
|
|
319
379
|
|
|
320
380
|
if (item.stock) {
|
|
321
|
-
expect(item.stock).
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
381
|
+
expect(typeof item.stock.id).toBe("string");
|
|
382
|
+
expect(typeof item.stock.symbol).toBe("string");
|
|
383
|
+
expect(typeof item.stock.name).toBe("string");
|
|
384
|
+
expect(typeof item.stock.assetType).toBe("string");
|
|
385
|
+
expect(typeof item.stock.assetClass).toBe("string");
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if ("averageCost" in item) {
|
|
389
|
+
expect(typeof (item as any).averageCost).toBe("number");
|
|
328
390
|
}
|
|
329
391
|
}
|
|
330
392
|
});
|
|
@@ -332,342 +394,407 @@ describe("BrokerClient", () => {
|
|
|
332
394
|
test("getBrokers with assetClass parameter", async () => {
|
|
333
395
|
const response = await brokerClient.getBrokers(
|
|
334
396
|
Region.Tr,
|
|
335
|
-
0,
|
|
336
397
|
10,
|
|
398
|
+
0,
|
|
337
399
|
AssetClass.Equity
|
|
338
400
|
);
|
|
339
401
|
|
|
340
402
|
expect(response).toBeDefined();
|
|
341
403
|
expect(typeof response.recordCount).toBe("number");
|
|
404
|
+
expect(response.recordCount).toBeGreaterThanOrEqual(0);
|
|
342
405
|
expect(Array.isArray(response.items)).toBe(true);
|
|
343
406
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
407
|
+
if (response.items.length > 0) {
|
|
408
|
+
const broker = response.items[0];
|
|
409
|
+
|
|
410
|
+
expect(typeof broker.id).toBe("number");
|
|
411
|
+
expect(typeof broker.symbol).toBe("string");
|
|
412
|
+
expect(typeof broker.name).toBe("string");
|
|
413
|
+
expect(typeof broker.longName).toBe("string");
|
|
414
|
+
expect(typeof broker.logo === "string" || broker.logo == null).toBe(
|
|
415
|
+
true
|
|
416
|
+
);
|
|
417
|
+
|
|
352
418
|
expect(Array.isArray(broker.supportedAssetClasses)).toBe(true);
|
|
353
419
|
expect(broker.supportedAssetClasses).toEqual([AssetClass.Equity]);
|
|
354
420
|
}
|
|
355
421
|
});
|
|
356
422
|
|
|
357
423
|
test("getBrokers without assetClass parameter", async () => {
|
|
358
|
-
const response = await brokerClient.getBrokers(
|
|
359
|
-
Region.Tr,
|
|
360
|
-
0,
|
|
361
|
-
10
|
|
362
|
-
);
|
|
424
|
+
const response = await brokerClient.getBrokers(Region.Tr, 10, 0);
|
|
363
425
|
|
|
364
426
|
expect(response).toBeDefined();
|
|
365
427
|
expect(typeof response.recordCount).toBe("number");
|
|
428
|
+
expect(response.recordCount).toBeGreaterThanOrEqual(0);
|
|
366
429
|
expect(Array.isArray(response.items)).toBe(true);
|
|
367
430
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
431
|
+
if (response.items.length > 0) {
|
|
432
|
+
const broker = response.items[0];
|
|
433
|
+
|
|
434
|
+
expect(typeof broker.id).toBe("number");
|
|
435
|
+
expect(typeof broker.symbol).toBe("string");
|
|
436
|
+
expect(typeof broker.name).toBe("string");
|
|
437
|
+
expect(typeof broker.longName).toBe("string");
|
|
438
|
+
expect(typeof broker.logo === "string" || broker.logo == null).toBe(
|
|
439
|
+
true
|
|
440
|
+
);
|
|
376
441
|
}
|
|
377
442
|
});
|
|
378
443
|
});
|
|
379
444
|
|
|
380
445
|
describe("Mock Tests", () => {
|
|
446
|
+
const region = Region.Tr;
|
|
447
|
+
const fromDate = "2025-06-01";
|
|
448
|
+
const toDate = "2025-06-30";
|
|
449
|
+
const page = 0;
|
|
450
|
+
const size = 5;
|
|
451
|
+
|
|
452
|
+
let brokerClient: BrokerClient;
|
|
453
|
+
let cli: { request: jest.Mock };
|
|
454
|
+
|
|
381
455
|
beforeEach(() => {
|
|
382
|
-
|
|
456
|
+
cli = {
|
|
457
|
+
request: jest.fn(),
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
const config = (global as any).testSuite.config as LaplaceConfiguration;
|
|
461
|
+
const logger: Logger = {
|
|
462
|
+
info: jest.fn(),
|
|
463
|
+
error: jest.fn(),
|
|
464
|
+
warn: jest.fn(),
|
|
465
|
+
debug: jest.fn(),
|
|
466
|
+
} as unknown as Logger;
|
|
467
|
+
|
|
468
|
+
// IMPORTANT: Client ctor artık cli kabul ediyor
|
|
469
|
+
brokerClient = new BrokerClient(config, logger, cli as any);
|
|
383
470
|
});
|
|
384
|
-
|
|
471
|
+
|
|
385
472
|
describe("getMarketBrokers", () => {
|
|
386
|
-
test("should
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const
|
|
390
|
-
|
|
473
|
+
test("should call correct endpoint/params and read values", async () => {
|
|
474
|
+
cli.request.mockResolvedValueOnce({ data: fxGetMarketBrokers });
|
|
475
|
+
|
|
476
|
+
const res = await brokerClient.getMarketBrokers(
|
|
477
|
+
region,
|
|
391
478
|
BrokerSort.TotalVolume,
|
|
392
479
|
SortDirection.Desc,
|
|
393
480
|
fromDate,
|
|
394
481
|
toDate,
|
|
395
|
-
|
|
396
|
-
|
|
482
|
+
size,
|
|
483
|
+
page
|
|
397
484
|
);
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
expect(
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
expect(
|
|
405
|
-
expect(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
Region.Tr,
|
|
410
|
-
BrokerSort.TotalVolume,
|
|
411
|
-
SortDirection.Desc,
|
|
485
|
+
|
|
486
|
+
// request shape
|
|
487
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
488
|
+
const call = cli.request.mock.calls[0][0];
|
|
489
|
+
|
|
490
|
+
expect(call.method).toBe("GET");
|
|
491
|
+
expect(call.url).toBe("/api/v1/brokers/market");
|
|
492
|
+
expect(call.params).toEqual({
|
|
493
|
+
region,
|
|
494
|
+
sortBy: BrokerSort.TotalVolume,
|
|
495
|
+
sortDirection: SortDirection.Desc,
|
|
412
496
|
fromDate,
|
|
413
497
|
toDate,
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
);
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
BrokerSort.TotalVolume,
|
|
438
|
-
SortDirection.Desc,
|
|
439
|
-
fromDate,
|
|
440
|
-
toDate,
|
|
441
|
-
0,
|
|
442
|
-
5
|
|
498
|
+
page,
|
|
499
|
+
size,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
// response values
|
|
503
|
+
expect(res.recordCount).toBe(2);
|
|
504
|
+
expect(res.items).toHaveLength(1);
|
|
505
|
+
|
|
506
|
+
expect(res.totalStats.netAmount).toBe(4000000.0);
|
|
507
|
+
expect(res.totalStats.totalAmount).toBe(17500000.0);
|
|
508
|
+
expect(res.totalStats.totalVolume).toBe(350000);
|
|
509
|
+
expect(res.totalStats.totalBuyAmount).toBe(10750000.0);
|
|
510
|
+
expect(res.totalStats.totalBuyVolume).toBe(175000);
|
|
511
|
+
expect(res.totalStats.totalSellAmount).toBe(6750000.0);
|
|
512
|
+
expect(res.totalStats.totalSellVolume).toBe(175000);
|
|
513
|
+
|
|
514
|
+
const item = res.items[0];
|
|
515
|
+
expect(item.broker?.id).toBe(1);
|
|
516
|
+
expect(item.broker?.symbol).toBe("BIDZY");
|
|
517
|
+
expect(item.broker?.name).toBe("DENIZ YATIRIM");
|
|
518
|
+
expect(item.broker?.longName).toBe("DENIZ YATIRIM MENKUL KIYMETLER A.S.");
|
|
519
|
+
expect(item.broker?.logo).toBe(
|
|
520
|
+
"https://finfree-storage.s3.eu-central-1.amazonaws.com/brokers/BIDZY.svg"
|
|
443
521
|
);
|
|
444
|
-
|
|
445
|
-
expect(
|
|
446
|
-
expect(
|
|
447
|
-
expect(
|
|
522
|
+
|
|
523
|
+
expect(item.netAmount).toBe(2500000.0);
|
|
524
|
+
expect(item.totalAmount).toBe(10000000.0);
|
|
525
|
+
expect(item.totalVolume).toBe(200000);
|
|
526
|
+
expect(item.totalBuyAmount).toBe(6250000.0);
|
|
527
|
+
expect(item.totalBuyVolume).toBe(100000);
|
|
528
|
+
expect(item.totalSellAmount).toBe(3750000.0);
|
|
529
|
+
expect(item.totalSellVolume).toBe(100000);
|
|
448
530
|
});
|
|
449
531
|
});
|
|
450
|
-
|
|
532
|
+
|
|
451
533
|
describe("getMarketStocks", () => {
|
|
452
|
-
test("should
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
const
|
|
456
|
-
|
|
534
|
+
test("should call correct endpoint/params and read values", async () => {
|
|
535
|
+
cli.request.mockResolvedValueOnce({ data: fxGetMarketStocks });
|
|
536
|
+
|
|
537
|
+
const res = await brokerClient.getMarketStocks(
|
|
538
|
+
region,
|
|
457
539
|
BrokerSort.TotalVolume,
|
|
458
540
|
SortDirection.Desc,
|
|
459
541
|
fromDate,
|
|
460
542
|
toDate,
|
|
461
|
-
|
|
462
|
-
|
|
543
|
+
size,
|
|
544
|
+
page
|
|
463
545
|
);
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
expect(
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
expect(
|
|
471
|
-
expect(
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
Region.Tr,
|
|
476
|
-
BrokerSort.TotalVolume,
|
|
477
|
-
SortDirection.Desc,
|
|
546
|
+
|
|
547
|
+
// request shape
|
|
548
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
549
|
+
const call = cli.request.mock.calls[0][0];
|
|
550
|
+
|
|
551
|
+
expect(call.method).toBe("GET");
|
|
552
|
+
expect(call.url).toBe("/api/v1/brokers/market/stock");
|
|
553
|
+
expect(call.params).toEqual({
|
|
554
|
+
region,
|
|
555
|
+
sortBy: BrokerSort.TotalVolume,
|
|
556
|
+
sortDirection: SortDirection.Desc,
|
|
478
557
|
fromDate,
|
|
479
558
|
toDate,
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
);
|
|
559
|
+
page,
|
|
560
|
+
size,
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
// response values
|
|
564
|
+
expect(res.recordCount).toBe(2);
|
|
565
|
+
expect(res.items).toHaveLength(1);
|
|
566
|
+
|
|
567
|
+
expect(res.totalStats.averageCost).toBe(2.91);
|
|
568
|
+
expect(res.totalStats.netAmount).toBe(1750000.0);
|
|
569
|
+
expect(res.totalStats.totalAmount).toBe(8750000.0);
|
|
570
|
+
expect(res.totalStats.totalVolume).toBe(175000);
|
|
571
|
+
expect(res.totalStats.totalBuyAmount).toBe(5250000.0);
|
|
572
|
+
expect(res.totalStats.totalBuyVolume).toBe(87500);
|
|
573
|
+
expect(res.totalStats.totalSellAmount).toBe(3500000.0);
|
|
574
|
+
expect(res.totalStats.totalSellVolume).toBe(87500);
|
|
575
|
+
|
|
576
|
+
const item = res.items[0];
|
|
577
|
+
expect(item.stock?.id).toBe("61dd0d670ec2114146342fa5");
|
|
578
|
+
expect(item.stock?.name).toBe("SASA Polyester");
|
|
579
|
+
expect(item.stock?.symbol).toBe("SASA");
|
|
580
|
+
expect(item.stock?.assetType).toBe(AssetType.Stock);
|
|
581
|
+
expect(item.stock?.assetClass).toBe(AssetClass.Equity);
|
|
582
|
+
|
|
583
|
+
expect(item.averageCost).toBe(2.91);
|
|
584
|
+
expect(item.netAmount).toBe(1000000.0);
|
|
585
|
+
expect(item.totalAmount).toBe(5000000.0);
|
|
586
|
+
expect(item.totalVolume).toBe(100000);
|
|
587
|
+
expect(item.totalBuyAmount).toBe(3000000.0);
|
|
588
|
+
expect(item.totalBuyVolume).toBe(50000);
|
|
589
|
+
expect(item.totalSellAmount).toBe(2000000.0);
|
|
590
|
+
expect(item.totalSellVolume).toBe(50000);
|
|
483
591
|
});
|
|
484
592
|
});
|
|
485
|
-
|
|
593
|
+
|
|
486
594
|
describe("getBrokersByStock", () => {
|
|
487
|
-
test("should
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
const
|
|
491
|
-
"
|
|
492
|
-
|
|
595
|
+
test("should call correct endpoint/params and read values", async () => {
|
|
596
|
+
cli.request.mockResolvedValueOnce({ data: fxGetBrokersByStock });
|
|
597
|
+
|
|
598
|
+
const res = await brokerClient.getBrokersByStock(
|
|
599
|
+
"SASA",
|
|
600
|
+
region,
|
|
493
601
|
BrokerSort.TotalVolume,
|
|
494
602
|
SortDirection.Desc,
|
|
495
603
|
fromDate,
|
|
496
604
|
toDate,
|
|
497
|
-
|
|
498
|
-
|
|
605
|
+
size,
|
|
606
|
+
page
|
|
499
607
|
);
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
expect(
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
expect(
|
|
507
|
-
expect(
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
Region.Tr,
|
|
512
|
-
BrokerSort.TotalVolume,
|
|
513
|
-
SortDirection.Desc,
|
|
608
|
+
|
|
609
|
+
// request shape
|
|
610
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
611
|
+
const call = cli.request.mock.calls[0][0];
|
|
612
|
+
|
|
613
|
+
expect(call.method).toBe("GET");
|
|
614
|
+
expect(call.url).toBe("/api/v1/brokers/SASA");
|
|
615
|
+
expect(call.params).toEqual({
|
|
616
|
+
region,
|
|
617
|
+
sortBy: BrokerSort.TotalVolume,
|
|
618
|
+
sortDirection: SortDirection.Desc,
|
|
514
619
|
fromDate,
|
|
515
620
|
toDate,
|
|
516
|
-
|
|
517
|
-
|
|
621
|
+
page,
|
|
622
|
+
size,
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
// response values
|
|
626
|
+
expect(res.recordCount).toBe(2);
|
|
627
|
+
expect(res.items).toHaveLength(1);
|
|
628
|
+
|
|
629
|
+
expect(res.totalStats.averageCost).toBe(2.91);
|
|
630
|
+
expect(res.totalStats.netAmount).toBe(800000.0);
|
|
631
|
+
expect(res.totalStats.totalAmount).toBe(3500000.0);
|
|
632
|
+
expect(res.totalStats.totalVolume).toBe(70000);
|
|
633
|
+
expect(res.totalStats.totalBuyAmount).toBe(2150000.0);
|
|
634
|
+
expect(res.totalStats.totalBuyVolume).toBe(35000);
|
|
635
|
+
expect(res.totalStats.totalSellAmount).toBe(1350000.0);
|
|
636
|
+
expect(res.totalStats.totalSellVolume).toBe(35000);
|
|
637
|
+
|
|
638
|
+
const item = res.items[0];
|
|
639
|
+
expect(item.broker?.id).toBe(1);
|
|
640
|
+
expect(item.broker?.symbol).toBe("BIMLB");
|
|
641
|
+
expect(item.broker?.name).toBe("BIMLB");
|
|
642
|
+
expect(item.broker?.longName).toBe("BIM Yatırım Menkul Değerler A.Ş.");
|
|
643
|
+
expect(item.broker?.logo).toBe(
|
|
644
|
+
"https://finfree-storage.s3.eu-central-1.amazonaws.com/broker-logos/bimlb.png"
|
|
518
645
|
);
|
|
646
|
+
|
|
647
|
+
expect(item.averageCost).toBe(2.91);
|
|
648
|
+
expect(item.netAmount).toBe(500000.0);
|
|
649
|
+
expect(item.totalAmount).toBe(2000000.0);
|
|
650
|
+
expect(item.totalVolume).toBe(40000);
|
|
651
|
+
expect(item.totalBuyAmount).toBe(1250000.0);
|
|
652
|
+
expect(item.totalBuyVolume).toBe(20000);
|
|
653
|
+
expect(item.totalSellAmount).toBe(750000.0);
|
|
654
|
+
expect(item.totalSellVolume).toBe(20000);
|
|
519
655
|
});
|
|
520
|
-
|
|
521
|
-
test("should
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
await expect(
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
656
|
+
|
|
657
|
+
test("should bubble up request error", async () => {
|
|
658
|
+
cli.request.mockRejectedValueOnce(new Error("Invalid stock symbol"));
|
|
659
|
+
|
|
660
|
+
await expect(
|
|
661
|
+
brokerClient.getBrokersByStock(
|
|
662
|
+
"INVALID",
|
|
663
|
+
region,
|
|
664
|
+
BrokerSort.TotalVolume,
|
|
665
|
+
SortDirection.Desc,
|
|
666
|
+
fromDate,
|
|
667
|
+
toDate,
|
|
668
|
+
size,
|
|
669
|
+
page
|
|
670
|
+
)
|
|
671
|
+
).rejects.toThrow("Invalid stock symbol");
|
|
534
672
|
});
|
|
535
673
|
});
|
|
536
|
-
|
|
674
|
+
|
|
537
675
|
describe("getStocksByBroker", () => {
|
|
538
|
-
test("should
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const
|
|
542
|
-
"
|
|
543
|
-
|
|
676
|
+
test("should call correct endpoint/params and read values", async () => {
|
|
677
|
+
cli.request.mockResolvedValueOnce({ data: fxGetStocksByBroker });
|
|
678
|
+
|
|
679
|
+
const res = await brokerClient.getStocksByBroker(
|
|
680
|
+
"BIMLB",
|
|
681
|
+
region,
|
|
544
682
|
BrokerSort.TotalVolume,
|
|
545
683
|
SortDirection.Desc,
|
|
546
684
|
fromDate,
|
|
547
685
|
toDate,
|
|
548
|
-
|
|
549
|
-
|
|
686
|
+
size,
|
|
687
|
+
page
|
|
550
688
|
);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
expect(
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
expect(
|
|
558
|
-
expect(
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
Region.Tr,
|
|
563
|
-
BrokerSort.TotalVolume,
|
|
564
|
-
SortDirection.Desc,
|
|
689
|
+
|
|
690
|
+
// request shape
|
|
691
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
692
|
+
const call = cli.request.mock.calls[0][0];
|
|
693
|
+
|
|
694
|
+
expect(call.method).toBe("GET");
|
|
695
|
+
expect(call.url).toBe("/api/v1/brokers/stock/BIMLB");
|
|
696
|
+
expect(call.params).toEqual({
|
|
697
|
+
region,
|
|
698
|
+
sortBy: BrokerSort.TotalVolume,
|
|
699
|
+
sortDirection: SortDirection.Desc,
|
|
565
700
|
fromDate,
|
|
566
701
|
toDate,
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
);
|
|
702
|
+
page,
|
|
703
|
+
size,
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
// response values
|
|
707
|
+
expect(res.recordCount).toBe(2);
|
|
708
|
+
expect(res.items).toHaveLength(1);
|
|
709
|
+
|
|
710
|
+
expect(res.totalStats.netAmount).toBe(800000.0);
|
|
711
|
+
expect(res.totalStats.totalAmount).toBe(3500000.0);
|
|
712
|
+
expect(res.totalStats.totalVolume).toBe(70000);
|
|
713
|
+
expect(res.totalStats.totalBuyAmount).toBe(2150000.0);
|
|
714
|
+
expect(res.totalStats.totalBuyVolume).toBe(35000);
|
|
715
|
+
expect(res.totalStats.totalSellAmount).toBe(1350000.0);
|
|
716
|
+
expect(res.totalStats.totalSellVolume).toBe(35000);
|
|
717
|
+
|
|
718
|
+
const item = res.items[0];
|
|
719
|
+
expect(item.stock?.id).toBe("61dd0d670ec2114146342fa5");
|
|
720
|
+
expect(item.stock?.name).toBe("SASA Polyester");
|
|
721
|
+
expect(item.stock?.symbol).toBe("SASA");
|
|
722
|
+
expect(item.stock?.assetType).toBe(AssetType.Stock);
|
|
723
|
+
expect(item.stock?.assetClass).toBe(AssetClass.Equity);
|
|
724
|
+
|
|
725
|
+
expect(item.netAmount).toBe(500000.0);
|
|
726
|
+
expect(item.totalAmount).toBe(2000000.0);
|
|
727
|
+
expect(item.totalVolume).toBe(40000);
|
|
728
|
+
expect(item.totalBuyAmount).toBe(1250000.0);
|
|
729
|
+
expect(item.totalBuyVolume).toBe(20000);
|
|
730
|
+
expect(item.totalSellAmount).toBe(750000.0);
|
|
731
|
+
expect(item.totalSellVolume).toBe(20000);
|
|
570
732
|
});
|
|
571
|
-
|
|
572
|
-
test("should
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
await expect(
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
733
|
+
|
|
734
|
+
test("should bubble up request error", async () => {
|
|
735
|
+
cli.request.mockRejectedValueOnce(new Error("Invalid broker symbol"));
|
|
736
|
+
|
|
737
|
+
await expect(
|
|
738
|
+
brokerClient.getStocksByBroker(
|
|
739
|
+
"INVALID",
|
|
740
|
+
region,
|
|
741
|
+
BrokerSort.TotalVolume,
|
|
742
|
+
SortDirection.Desc,
|
|
743
|
+
fromDate,
|
|
744
|
+
toDate,
|
|
745
|
+
size,
|
|
746
|
+
page
|
|
747
|
+
)
|
|
748
|
+
).rejects.toThrow("Invalid broker symbol");
|
|
585
749
|
});
|
|
586
750
|
});
|
|
587
|
-
|
|
751
|
+
|
|
588
752
|
describe("getBrokers", () => {
|
|
589
|
-
test("should
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
expect(
|
|
600
|
-
expect(
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
expect(
|
|
608
|
-
expect(
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
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
|
|
753
|
+
test("should call correct endpoint/params and read values", async () => {
|
|
754
|
+
cli.request.mockResolvedValueOnce({ data: fxGetBrokers });
|
|
755
|
+
|
|
756
|
+
const res = await brokerClient.getBrokers(region, 10, 0);
|
|
757
|
+
|
|
758
|
+
// request shape
|
|
759
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
760
|
+
const call = cli.request.mock.calls[0][0];
|
|
761
|
+
|
|
762
|
+
expect(call.method).toBe("GET");
|
|
763
|
+
expect(call.url).toBe("/api/v1/brokers");
|
|
764
|
+
expect(call.params).toEqual({
|
|
765
|
+
region,
|
|
766
|
+
size: 10,
|
|
767
|
+
page: 0,
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
// response values
|
|
771
|
+
expect(res.recordCount).toBe(239);
|
|
772
|
+
expect(res.items).toHaveLength(1);
|
|
773
|
+
|
|
774
|
+
const broker = res.items[0];
|
|
775
|
+
expect(broker.id).toBe(1);
|
|
776
|
+
expect(broker.symbol).toBe("BIDZY");
|
|
777
|
+
expect(broker.name).toBe("DENIZ YATIRIM");
|
|
778
|
+
expect(broker.longName).toBe("DENIZ YATIRIM MENKUL KIYMETLER A.S.");
|
|
779
|
+
expect(broker.logo).toBe(
|
|
780
|
+
"https://finfree-storage.s3.eu-central-1.amazonaws.com/brokers/BIDZY.svg"
|
|
655
781
|
);
|
|
656
|
-
|
|
657
|
-
expect(response.recordCount).toBe(0);
|
|
658
|
-
expect(response.items).toHaveLength(0);
|
|
782
|
+
expect(broker.supportedAssetClasses).toEqual([AssetClass.Equity]);
|
|
659
783
|
});
|
|
660
|
-
|
|
661
|
-
test("should
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
await
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
784
|
+
|
|
785
|
+
test("should include assetClass when provided", async () => {
|
|
786
|
+
cli.request.mockResolvedValueOnce({ data: fxGetBrokers });
|
|
787
|
+
|
|
788
|
+
await brokerClient.getBrokers(region, 10, 0, AssetClass.Equity);
|
|
789
|
+
|
|
790
|
+
const call = cli.request.mock.calls[0][0];
|
|
791
|
+
expect(call.params).toEqual({
|
|
792
|
+
region,
|
|
793
|
+
size: 10,
|
|
794
|
+
page: 0,
|
|
795
|
+
assetClass: AssetClass.Equity,
|
|
796
|
+
});
|
|
670
797
|
});
|
|
671
798
|
});
|
|
672
799
|
});
|
|
673
|
-
});
|
|
800
|
+
});
|