laplace-api 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +37 -0
- package/.github/workflows/test.yml +25 -0
- package/README.md +461 -2
- package/package.json +1 -1
- package/src/client/broker.ts +9 -7
- package/src/client/capital_increase.ts +7 -12
- package/src/client/collections.ts +57 -28
- package/src/client/financial_fundamentals.ts +2 -5
- package/src/client/financial_ratios.ts +114 -95
- package/src/client/live-price-web-socket.ts +84 -11
- package/src/client/live-price.ts +204 -77
- package/src/client/politician.ts +75 -0
- package/src/client/stocks.ts +73 -0
- package/src/test/broker.test.ts +583 -148
- package/src/test/capital_increase.test.ts +186 -39
- package/src/test/collections.test.ts +445 -60
- package/src/test/custom_theme.test.ts +242 -60
- package/src/test/financial_fundamentals.test.ts +297 -56
- package/src/test/financial_ratios.test.ts +363 -92
- package/src/test/funds.test.ts +275 -68
- package/src/test/key-insight.test.ts +81 -19
- package/src/test/live-price.test.ts +425 -64
- package/src/test/politician.test.ts +253 -0
- package/src/test/readme.test.ts +483 -0
- package/src/test/search.test.ts +301 -65
- package/src/test/stocks.test.ts +764 -152
- package/src/utilities/configuration.ts +23 -10
- package/src/utilities/test.env +2 -2
package/src/test/stocks.test.ts
CHANGED
|
@@ -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("
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
34
|
-
|
|
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
|
-
|
|
44
|
-
expect(
|
|
45
|
-
}
|
|
223
|
+
expect(resp).not.toBeEmpty();
|
|
224
|
+
expect(resp.length).toBeLessThanOrEqual(10);
|
|
225
|
+
});
|
|
46
226
|
});
|
|
47
227
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
355
|
+
describe("getAllStockRestrictions", () => {
|
|
356
|
+
test("should return all stock restrictions for region", async () => {
|
|
357
|
+
const resp = await client.getAllStockRestrictions(Region.Tr);
|
|
164
358
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
177
|
-
|
|
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("
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
192
|
-
expect(
|
|
193
|
-
expect(
|
|
194
|
-
expect(
|
|
195
|
-
expect(
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
205
|
-
|
|
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
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
822
|
+
await expect(client.getState("INVALID"))
|
|
823
|
+
.rejects.toThrow("Market state not found");
|
|
824
|
+
});
|
|
213
825
|
});
|
|
214
826
|
});
|
|
215
827
|
});
|