laplace-api 5.1.0 → 5.2.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "laplace-api",
3
- "version": "5.1.0",
3
+ "version": "5.2.1",
4
4
  "description": "Client library for Laplace API for the US stock market and BIST (Istanbul stock market) fundamental financial data.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,124 +1,170 @@
1
- import {Client} from "./client";
2
- import {Locale, Region} from "./collections";
3
- import {PaginatedResponse} from "./capital_increase";
4
- import {SortDirection} from "./broker";
1
+ import { Client } from "./client";
2
+ import { Locale, Region } from "./collections";
3
+ import { PaginatedResponse } from "./capital_increase";
4
+ import { SortDirection } from "./broker";
5
5
 
6
6
  export interface NewsHighlights {
7
- consumer: string[];
8
- energyAndUtilities: string[];
9
- finance: string[];
10
- healthcare: string[];
11
- industrialsAndMaterials: string[];
12
- tech: string[];
13
- other: string[];
7
+ consumer: string[];
8
+ energyAndUtilities: string[];
9
+ finance: string[];
10
+ healthcare: string[];
11
+ industrialsAndMaterials: string[];
12
+ tech: string[];
13
+ other: string[];
14
14
  }
15
15
 
16
16
  export enum NewsType {
17
- BRIEFS = "briefs",
18
- BLOOMBERG = "bloomberg",
19
- FDA = "fda",
20
- REUTERS = "reuters",
17
+ BRIEFS = "briefs",
18
+ BLOOMBERG = "bloomberg",
19
+ FDA = "fda",
20
+ REUTERS = "reuters",
21
21
  }
22
22
 
23
23
  export enum NewsOrderBy {
24
- TIMESTAMP = "timestamp",
24
+ TIMESTAMP = "timestamp",
25
25
  }
26
26
 
27
27
  export interface News {
28
- url: string;
29
- imageUrl: string;
30
- timestamp: string;
31
- publisherUrl: string;
32
- publisher: NewsPublisher;
33
- relatedTickers: NewsTicker[];
34
- qualityScore: number;
35
- createdAt: string;
36
- tickers?: NewsTicker[];
37
- categories?: NewsCategories;
38
- sectors?: NewsSector;
39
- content?: NewsContent;
40
- industries?: NewsIndustry;
28
+ url: string;
29
+ imageUrl: string;
30
+ timestamp: string;
31
+ publisherUrl: string;
32
+ publisher: NewsPublisher;
33
+ relatedTickers: NewsTicker[];
34
+ qualityScore: number;
35
+ createdAt: string;
36
+ tickers?: NewsTicker[];
37
+ categories?: NewsCategories;
38
+ sectors?: NewsSector;
39
+ content?: NewsContent;
40
+ industries?: NewsIndustry;
41
41
  }
42
42
 
43
+ export type NewsV2 = Omit<News, "relatedTickers">;
44
+
43
45
  export interface NewsPublisher {
44
- name: string;
45
- logoUrl: string | null;
46
+ name: string;
47
+ logoUrl: string | null;
46
48
  }
47
49
 
48
50
  export interface NewsTicker {
49
- id: string;
50
- name: string;
51
- symbol?: string;
51
+ id: string;
52
+ name: string;
53
+ symbol?: string;
52
54
  }
53
55
 
54
56
  export interface NewsCategories {
55
- name: string;
56
- newsCount: number;
57
- categoryType?: string | null;
58
- meanType?: number | null;
57
+ name: string;
58
+ newsCount: number;
59
+ categoryType?: string | null;
60
+ meanType?: number | null;
59
61
  }
60
62
 
61
63
  export interface NewsSector {
62
- name: string;
63
- newsCount: number;
64
- categoryType?: string | null;
65
- meanType?: number | null;
64
+ name: string;
65
+ newsCount: number;
66
+ categoryType?: string | null;
67
+ meanType?: number | null;
66
68
  }
67
69
 
68
70
  export interface NewsContent {
69
- title: string;
70
- description: string;
71
- content: string[];
72
- summary: string[];
73
- investorInsight: string;
71
+ title: string;
72
+ description: string;
73
+ content: string[];
74
+ summary: string[];
75
+ investorInsight: string;
74
76
  }
75
77
 
76
78
  export interface NewsIndustry {
77
- name: string;
78
- meanType: number;
79
+ name: string;
80
+ meanType: number;
79
81
  }
80
82
 
81
83
  export class NewsClient extends Client {
82
- async getHighlights(
83
- region: Region,
84
- locale: Locale
85
- ): Promise<NewsHighlights> {
86
- return this.sendRequest<NewsHighlights>({
87
- method: "GET",
88
- url: "/api/v1/news/highlights",
89
- params: {
90
- region,
91
- locale,
92
- },
93
- });
94
- }
95
-
96
-
97
- async getNews(
98
- region: Region,
99
- locale: Locale,
100
- newsType?: NewsType,
101
- page?: number,
102
- size?: number,
103
- orderBy?: NewsOrderBy,
104
- orderByDirection?: SortDirection,
105
- extraFilters?: string
106
- ): Promise<PaginatedResponse<News>> {
107
- const params = {
108
- region,
109
- locale,
110
- ...(newsType != null && { newsType }),
111
- ...(page != null && { page }),
112
- ...(size != null && { size }),
113
- ...(orderBy != null && { orderBy }),
114
- ...(orderByDirection != null && { orderByDirection }),
115
- ...(extraFilters != null && { extraFilters }),
116
- };
117
-
118
- return this.sendRequest<PaginatedResponse<News>>({
119
- method: "GET",
120
- url: "/api/v1/news",
121
- params,
122
- });
123
- }
84
+ async getHighlights(
85
+ region: Region,
86
+ locale: Locale
87
+ ): Promise<NewsHighlights> {
88
+ return this.sendRequest<NewsHighlights>({
89
+ method: "GET",
90
+ url: "/api/v1/news/highlights",
91
+ params: {
92
+ region,
93
+ locale,
94
+ },
95
+ });
96
+ }
97
+
98
+
99
+ async getNews(
100
+ region: Region,
101
+ locale: Locale,
102
+ newsType?: NewsType,
103
+ page?: number,
104
+ size?: number,
105
+ orderBy?: NewsOrderBy,
106
+ orderByDirection?: SortDirection,
107
+ extraFilters?: string
108
+ ): Promise<PaginatedResponse<News>> {
109
+ const params = {
110
+ region,
111
+ locale,
112
+ ...(newsType != null && { newsType }),
113
+ ...(page != null && { page }),
114
+ ...(size != null && { size }),
115
+ ...(orderBy != null && { orderBy }),
116
+ ...(orderByDirection != null && { orderByDirection }),
117
+ ...(extraFilters != null && { extraFilters }),
118
+ };
119
+
120
+ return this.sendRequest<PaginatedResponse<News>>({
121
+ method: "GET",
122
+ url: "/api/v1/news",
123
+ params,
124
+ });
125
+ }
126
+
127
+ async getNewsV2(
128
+ region: Region,
129
+ locale: Locale,
130
+ newsType?: NewsType,
131
+ page?: number,
132
+ size?: number,
133
+ orderBy?: NewsOrderBy,
134
+ orderByDirection?: SortDirection,
135
+ extraFilters?: string
136
+ ): Promise<PaginatedResponse<NewsV2>> {
137
+ const params = {
138
+ region,
139
+ locale,
140
+ ...(newsType != null && { newsType }),
141
+ ...(page != null && { page }),
142
+ ...(size != null && { size }),
143
+ ...(orderBy != null && { orderBy }),
144
+ ...(orderByDirection != null && { orderByDirection }),
145
+ ...(extraFilters != null && { extraFilters }),
146
+ };
147
+
148
+ return this.sendRequest<PaginatedResponse<NewsV2>>({
149
+ method: "GET",
150
+ url: "/api/v2/news",
151
+ params,
152
+ });
153
+ }
154
+
155
+ streamNews(
156
+ region: Region,
157
+ locale: Locale,
158
+ sectors?: string[],
159
+ tickers?: string[],
160
+ categories?: string[],
161
+ industries?: string[]
162
+ ): { events: AsyncIterable<NewsV2[]>, cancel: () => void } {
163
+ let url = `${this["baseUrl"]}/api/v1/news/stream?locale=${locale}&region=${region}`;
164
+ if (sectors?.length) url += `&sectors=${encodeURIComponent(sectors.join(","))}`;
165
+ if (tickers?.length) url += `&tickers=${encodeURIComponent(tickers.join(","))}`;
166
+ if (categories?.length) url += `&categories=${encodeURIComponent(categories.join(","))}`;
167
+ if (industries?.length) url += `&industries=${encodeURIComponent(industries.join(","))}`;
168
+ return this.sendSSERequest<NewsV2[]>(url);
169
+ }
124
170
  }
@@ -1,4 +1,5 @@
1
1
  import { Logger } from "winston";
2
+ import axios from "axios";
2
3
  import { LaplaceConfiguration } from "../utilities/configuration";
3
4
  import {
4
5
  NewsClient,
@@ -10,61 +11,66 @@ import { Region, Locale } from "../client/collections";
10
11
  import { SortDirection } from "../client/broker";
11
12
 
12
13
  const mockNewsHighlightsResponse = {
13
- tech: [
14
- "Alphabet ve Amazon'un desteğiyle Anthropic, 2026 başlarında Hindistan'ın Bengaluru kentinde bir ofis açacak."
15
- ],
16
- other: [
17
- "ABD Yüksek Mahkemesi, Epic Games'in davası kapsamında Google'ın Play uygulamalarındaki değişikliği engellemeyecek."
18
- ],
19
- finance: [
20
- "Fifth Third Bank, Comerica'yı 10,9 milyar dolara satın alacak ve böylece ABD'nin 9. en büyük bankası olacak."
21
- ],
22
- consumer: [
23
- "Tesla, rekabet ortamında pazar payını geri almak için daha ucuz Model Y ve Model 3'ü piyasaya sürdü; duyuru hisseleri etkiledi."
24
- ],
25
- healthcare: [
26
- "İlaç üreticileri, Amgen ve Novo Nordisk'in de dahil olduğu şekilde, Trump'ın ilaç fiyatlarını düşürme planıyla uyumlu olarak tele-sağlık satışlarını artırıyor."
27
- ],
28
- energyAndUtilities: [
29
- "ABD Enerji Bakanlığı, Stellantis ve GM'ye verilen 1,1 milyar dolarlık hibeleri iptal edebilir."
30
- ],
31
- industrialsAndMaterials: [
32
- "Boeing, bir grevi sona erdirmek için IAM Sendikası ile geçici bir anlaşmaya vardı; detaylar açıklanmadı."
33
- ]
34
- };
35
-
36
- const mockNewsResponse = {
37
- items: [
38
- {
39
- url: "https://www.reuters.com/business/energy/commonwealth-lng-wants-more-time-build-planned-export-facility-louisiana-2025-10-07/",
40
- content: {
41
- title: "Commonwealth LNG wants more time to build planned export facility in Louisiana",
42
- content: [
43
- "Commonwealth LNG has requested a four-year extension from federal regulators to construct & begin exporting liquefied natural gas..."
44
- ],
45
- summary: [
46
- "Commonwealth LNG has requested a four-year extension from federal regulators..."
47
- ],
48
- description:
49
- "Commonwealth LNG has asked federal regulators for a four-year extension...",
50
- investorInsight:
51
- "What it means for investors: The extension request could postpone..."
52
- },
53
- sectors: { name: "Energy", meanType: 9, newsCount: 1 },
54
- tickers: [{ id: "6203d1ba1e674875275558f7", name: "EQT Corp", symbol: "EQT" }],
55
- imageUrl: "",
56
- createdAt: "2025-10-07T17:10:01.560644Z",
57
- publisher: { name: "Reuters", logoUrl: null },
58
- timestamp: "2025-10-07T16:50:16Z",
59
- categories: { name: "Sector News", newsCount: 1, categoryType: "StockSpesific" },
60
- industries: { name: "Oil/Gas (Production and Exploration)", meanType: 78 },
61
- publisherUrl: "Reuters",
62
- qualityScore: 0,
63
- relatedTickers: [{ id: "6203d1ba1e674875275558f7", name: "EQT Corp", symbol: "EQT" }]
64
- }
65
- ],
66
- recordCount: 352
67
- };
14
+ tech: [
15
+ "Alphabet ve Amazon'un desteğiyle Anthropic, 2026 başlarında Hindistan'ın Bengaluru kentinde bir ofis açacak."
16
+ ],
17
+ other: [
18
+ "ABD Yüksek Mahkemesi, Epic Games'in davası kapsamında Google'ın Play uygulamalarındaki değişikliği engellemeyecek."
19
+ ],
20
+ finance: [
21
+ "Fifth Third Bank, Comerica'yı 10,9 milyar dolara satın alacak ve böylece ABD'nin 9. en büyük bankası olacak."
22
+ ],
23
+ consumer: [
24
+ "Tesla, rekabet ortamında pazar payını geri almak için daha ucuz Model Y ve Model 3'ü piyasaya sürdü; duyuru hisseleri etkiledi."
25
+ ],
26
+ healthcare: [
27
+ "İlaç üreticileri, Amgen ve Novo Nordisk'in de dahil olduğu şekilde, Trump'ın ilaç fiyatlarını düşürme planıyla uyumlu olarak tele-sağlık satışlarını artırıyor."
28
+ ],
29
+ energyAndUtilities: [
30
+ "ABD Enerji Bakanlığı, Stellantis ve GM'ye verilen 1,1 milyar dolarlık hibeleri iptal edebilir."
31
+ ],
32
+ industrialsAndMaterials: [
33
+ "Boeing, bir grevi sona erdirmek için IAM Sendikası ile geçici bir anlaşmaya vardı; detaylar açıklanmadı."
34
+ ]
35
+ };
36
+
37
+ const mockNewsResponse = {
38
+ items: [
39
+ {
40
+ url: "https://www.reuters.com/business/energy/commonwealth-lng-wants-more-time-build-planned-export-facility-louisiana-2025-10-07/",
41
+ content: {
42
+ title: "Commonwealth LNG wants more time to build planned export facility in Louisiana",
43
+ content: [
44
+ "Commonwealth LNG has requested a four-year extension from federal regulators to construct & begin exporting liquefied natural gas..."
45
+ ],
46
+ summary: [
47
+ "Commonwealth LNG has requested a four-year extension from federal regulators..."
48
+ ],
49
+ description:
50
+ "Commonwealth LNG has asked federal regulators for a four-year extension...",
51
+ investorInsight:
52
+ "What it means for investors: The extension request could postpone..."
53
+ },
54
+ sectors: { name: "Energy", meanType: 9, newsCount: 1 },
55
+ tickers: [{ id: "6203d1ba1e674875275558f7", name: "EQT Corp", symbol: "EQT" }],
56
+ imageUrl: "",
57
+ createdAt: "2025-10-07T17:10:01.560644Z",
58
+ publisher: { name: "Reuters", logoUrl: null },
59
+ timestamp: "2025-10-07T16:50:16Z",
60
+ categories: { name: "Sector News", newsCount: 1, categoryType: "StockSpesific" },
61
+ industries: { name: "Oil/Gas (Production and Exploration)", meanType: 78 },
62
+ publisherUrl: "Reuters",
63
+ qualityScore: 0,
64
+ relatedTickers: [{ id: "6203d1ba1e674875275558f7", name: "EQT Corp", symbol: "EQT" }]
65
+ }
66
+ ],
67
+ recordCount: 352
68
+ };
69
+
70
+ const mockNewsV2Response = {
71
+ items: mockNewsResponse.items.map(({ relatedTickers, ...rest }) => rest),
72
+ recordCount: mockNewsResponse.recordCount
73
+ };
68
74
 
69
75
  describe("NewsClient", () => {
70
76
  let client: NewsClient;
@@ -150,13 +156,13 @@ describe("NewsClient", () => {
150
156
  expect(typeof n.categories.newsCount).toBe("number");
151
157
  expect(
152
158
  typeof n.categories.categoryType === "string" ||
153
- n.categories.categoryType == null ||
154
- n.categories.categoryType === undefined
159
+ n.categories.categoryType == null ||
160
+ n.categories.categoryType === undefined
155
161
  ).toBe(true);
156
162
  expect(
157
163
  typeof n.categories.meanType === "number" ||
158
- n.categories.meanType == null ||
159
- n.categories.meanType === undefined
164
+ n.categories.meanType == null ||
165
+ n.categories.meanType === undefined
160
166
  ).toBe(true);
161
167
  }
162
168
 
@@ -165,13 +171,13 @@ describe("NewsClient", () => {
165
171
  expect(typeof n.sectors.newsCount).toBe("number");
166
172
  expect(
167
173
  typeof n.sectors.categoryType === "string" ||
168
- n.sectors.categoryType == null ||
169
- n.sectors.categoryType === undefined
174
+ n.sectors.categoryType == null ||
175
+ n.sectors.categoryType === undefined
170
176
  ).toBe(true);
171
177
  expect(
172
178
  typeof n.sectors.meanType === "number" ||
173
- n.sectors.meanType == null ||
174
- n.sectors.meanType === undefined
179
+ n.sectors.meanType == null ||
180
+ n.sectors.meanType === undefined
175
181
  ).toBe(true);
176
182
  }
177
183
 
@@ -189,6 +195,58 @@ describe("NewsClient", () => {
189
195
  }
190
196
  }
191
197
  });
198
+
199
+ test("getNewsV2 returns valid paginated data", async () => {
200
+ const resp = await client.getNewsV2(
201
+ Region.Us,
202
+ Locale.Tr,
203
+ NewsType.BRIEFS,
204
+ 0,
205
+ 10,
206
+ NewsOrderBy.TIMESTAMP,
207
+ SortDirection.Desc
208
+ );
209
+
210
+ expect(resp).toBeDefined();
211
+ expect(typeof resp.recordCount).toBe("number");
212
+ expect(resp.recordCount).toBeGreaterThanOrEqual(0);
213
+ expect(Array.isArray(resp.items)).toBe(true);
214
+
215
+ if (resp.items.length > 0) {
216
+ const n = resp.items[0];
217
+
218
+ expect(typeof n.url).toBe("string");
219
+ expect(typeof n.imageUrl).toBe("string");
220
+ expect(typeof n.timestamp).toBe("string");
221
+ expect(typeof n.publisherUrl).toBe("string");
222
+ expect(typeof n.qualityScore).toBe("number");
223
+ expect(typeof n.createdAt).toBe("string");
224
+
225
+ expect((n as any).relatedTickers).toBeUndefined();
226
+
227
+ expect(n.publisher).toBeDefined();
228
+ expect(typeof n.publisher.name).toBe("string");
229
+ }
230
+ });
231
+
232
+ test("streamNews yields item before timeout or throws gracefully if none arrive", async () => {
233
+ let newsItemsReceived = 0;
234
+ const { events, cancel } = client.streamNews(Region.Us, Locale.Tr);
235
+
236
+ const receivePromise = (async () => {
237
+ for await (const items of events) {
238
+ if (items && items.length > 0) {
239
+ newsItemsReceived += items.length;
240
+ break;
241
+ }
242
+ }
243
+ })();
244
+
245
+ const timeoutPromise = new Promise((resolve) => setTimeout(resolve, 8000));
246
+ await Promise.race([receivePromise, timeoutPromise]);
247
+ cancel();
248
+ expect(newsItemsReceived).toBeGreaterThanOrEqual(0);
249
+ });
192
250
  });
193
251
 
194
252
  describe("Mock Tests", () => {
@@ -343,5 +401,142 @@ describe("NewsClient", () => {
343
401
  expect(cli.request).toHaveBeenCalledTimes(1);
344
402
  });
345
403
  });
404
+
405
+ describe("getNewsV2", () => {
406
+ test("calls correct endpoint/params and matches raw response", async () => {
407
+ cli.request.mockResolvedValueOnce({ data: mockNewsV2Response });
408
+
409
+ const resp = await client.getNewsV2(
410
+ Region.Tr,
411
+ Locale.Tr,
412
+ NewsType.BRIEFS,
413
+ 1,
414
+ 10,
415
+ NewsOrderBy.TIMESTAMP,
416
+ SortDirection.Desc,
417
+ undefined
418
+ );
419
+
420
+ expect(cli.request).toHaveBeenCalledTimes(1);
421
+ const call = cli.request.mock.calls[0][0];
422
+
423
+ expect(call.method).toBe("GET");
424
+ expect(call.url).toBe("/api/v2/news");
425
+ expect(call.params).toEqual({
426
+ region: Region.Tr,
427
+ locale: Locale.Tr,
428
+ newsType: NewsType.BRIEFS,
429
+ page: 1,
430
+ size: 10,
431
+ orderBy: NewsOrderBy.TIMESTAMP,
432
+ orderByDirection: SortDirection.Desc
433
+ });
434
+
435
+ expect(resp.recordCount).toBe(352);
436
+ expect(resp.items).toHaveLength(1);
437
+
438
+ const n = resp.items[0];
439
+
440
+ expect((n as any).relatedTickers).toBeUndefined();
441
+ expect(n.url).toBe(mockNewsV2Response.items[0].url);
442
+ });
443
+
444
+ test("does not send optional params when undefined", async () => {
445
+ cli.request.mockResolvedValueOnce({ data: mockNewsV2Response });
446
+
447
+ await client.getNewsV2(Region.Tr, Locale.Tr);
448
+
449
+ const call = cli.request.mock.calls[0][0];
450
+ expect(call.params).toEqual({
451
+ region: Region.Tr,
452
+ locale: Locale.Tr
453
+ });
454
+ });
455
+
456
+ test("bubbles up request error", async () => {
457
+ cli.request.mockRejectedValueOnce(new Error("Failed to fetch news v2"));
458
+
459
+ await expect(
460
+ client.getNewsV2(
461
+ Region.Tr,
462
+ Locale.Tr,
463
+ NewsType.REUTERS,
464
+ 0,
465
+ 10,
466
+ NewsOrderBy.TIMESTAMP,
467
+ SortDirection.Desc
468
+ )
469
+ ).rejects.toThrow("Failed to fetch news v2");
470
+
471
+ expect(cli.request).toHaveBeenCalledTimes(1);
472
+ });
473
+ });
474
+
475
+ describe("streamNews", () => {
476
+ test("calls correct endpoint/params and correctly yields stream entities", async () => {
477
+ const eventsList: any[] = [];
478
+
479
+ // Mock get response to return a readable stream
480
+ const mockStreamData = [
481
+ "data: " + JSON.stringify([{ url: "http://example.com/stream-news-1", publiser: { name: "test-publisher" } }]) + "\n\n",
482
+ "data: " + JSON.stringify([{ url: "http://example.com/stream-news-2", publiser: { name: "test-publisher-2" } }]) + "\n\n",
483
+ ];
484
+
485
+ const mockAsyncIterator = {
486
+ async *[Symbol.asyncIterator]() {
487
+ for (const chunk of mockStreamData) {
488
+ yield new TextEncoder().encode(chunk);
489
+ }
490
+ }
491
+ };
492
+
493
+ const axiosGetSpy = jest.spyOn(axios, 'get').mockResolvedValueOnce({
494
+ data: mockAsyncIterator
495
+ });
496
+
497
+ const { events, cancel } = client.streamNews(Region.Us, Locale.Tr);
498
+
499
+ for await (const newsList of events) {
500
+ eventsList.push(newsList);
501
+ }
502
+
503
+ expect(axiosGetSpy).toHaveBeenCalledTimes(1);
504
+ const callArgs = axiosGetSpy.mock.calls[0];
505
+ expect(callArgs[0]).toBe(`${client["baseUrl"]}/api/v1/news/stream?locale=tr&region=us`);
506
+ expect(callArgs[1]?.responseType).toBe('stream');
507
+
508
+ expect(eventsList).toHaveLength(2);
509
+ expect(eventsList[0][0].url).toBe("http://example.com/stream-news-1");
510
+ expect(eventsList[1][0].url).toBe("http://example.com/stream-news-2");
511
+
512
+ cancel();
513
+ axiosGetSpy.mockRestore();
514
+ });
515
+
516
+ test("calls correct endpoint with optional parameters", async () => {
517
+ const mockAsyncIterator = {
518
+ async *[Symbol.asyncIterator]() {
519
+ yield new TextEncoder().encode("data: " + JSON.stringify([]) + "\n\n");
520
+ }
521
+ };
522
+
523
+ const axiosGetSpy = jest.spyOn(axios, 'get').mockResolvedValueOnce({
524
+ data: mockAsyncIterator
525
+ });
526
+
527
+ const { events, cancel } = client.streamNews(Region.Us, Locale.En, ["tech"], ["AAPL"], ["category"], ["software"]);
528
+
529
+ for await (const _ of events) {
530
+ break;
531
+ }
532
+
533
+ expect(axiosGetSpy).toHaveBeenCalledTimes(1);
534
+ const callArgs = axiosGetSpy.mock.calls[0];
535
+ expect(callArgs[0]).toBe(`${client["baseUrl"]}/api/v1/news/stream?locale=en&region=us&sectors=tech&tickers=AAPL&categories=category&industries=software`);
536
+
537
+ cancel();
538
+ axiosGetSpy.mockRestore();
539
+ });
540
+ });
346
541
  });
347
542
  });