laplace-api 4.8.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -71,7 +71,6 @@ const mockAllTypesSearchResponse = {
71
71
  {
72
72
  id: "col123",
73
73
  title: "Artificial Intelligence",
74
- description: "AI focused companies",
75
74
  region: [Region.Us],
76
75
  assetClass: "equity",
77
76
  imageUrl: "https://example.com/collection.jpg",
@@ -97,12 +96,7 @@ describe("Search", () => {
97
96
 
98
97
  describe("Integration Tests", () => {
99
98
  test("SearchStock", async () => {
100
- const resp = await client.search(
101
- "TUPRS",
102
- [SearchType.Stock],
103
- Region.Tr,
104
- Locale.Tr
105
- );
99
+ const resp = await client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr);
106
100
  expect(resp.stocks).not.toBeEmpty();
107
101
 
108
102
  const firstResult = resp.stocks[0];
@@ -115,12 +109,7 @@ describe("Search", () => {
115
109
  });
116
110
 
117
111
  test("SearchIndustry", async () => {
118
- const resp = await client.search(
119
- "Hava",
120
- [SearchType.Industry],
121
- Region.Tr,
122
- Locale.Tr
123
- );
112
+ const resp = await client.search("Hava", [SearchType.Industry], Locale.Tr, Region.Tr);
124
113
  expect(resp.industries).not.toBeEmpty();
125
114
 
126
115
  const firstResult = resp.industries[0];
@@ -128,9 +117,7 @@ describe("Search", () => {
128
117
  expect(typeof firstResult.title).toBe("string");
129
118
  expect(Array.isArray(firstResult.region)).toBe(true);
130
119
  expect(firstResult.region.length).toBeGreaterThan(0);
131
- firstResult.region.forEach((region) => {
132
- expect(typeof region).toBe("string");
133
- });
120
+ firstResult.region.forEach((r: string) => expect(typeof r).toBe("string"));
134
121
 
135
122
  expect(typeof firstResult.assetClass).toBe("string");
136
123
  expect(typeof firstResult.imageUrl).toBe("string");
@@ -140,19 +127,11 @@ describe("Search", () => {
140
127
  test("SearchAllTypes", async () => {
141
128
  const resp = await client.search(
142
129
  "Ab",
143
- [
144
- SearchType.Stock,
145
- SearchType.Industry,
146
- SearchType.Sector,
147
- SearchType.Collection,
148
- ],
149
- Region.Us,
150
- Locale.Tr
130
+ [SearchType.Stock, SearchType.Industry, SearchType.Sector, SearchType.Collection],
131
+ Locale.Tr,
132
+ Region.Us
151
133
  );
152
134
 
153
- expect(typeof resp).toBe("object");
154
- expect(resp).not.toBeNull();
155
-
156
135
  const hasResults =
157
136
  (resp.stocks && resp.stocks.length > 0) ||
158
137
  (resp.industries && resp.industries.length > 0) ||
@@ -160,168 +139,163 @@ describe("Search", () => {
160
139
  (resp.collections && resp.collections.length > 0);
161
140
 
162
141
  expect(hasResults).toBe(true);
163
-
164
- if (resp.stocks) expect(Array.isArray(resp.stocks)).toBe(true);
165
- if (resp.industries) expect(Array.isArray(resp.industries)).toBe(true);
166
- if (resp.sectors) expect(Array.isArray(resp.sectors)).toBe(true);
167
- if (resp.collections) expect(Array.isArray(resp.collections)).toBe(true);
168
142
  });
169
143
  });
170
144
 
171
- describe("Mock Tests", () => {
145
+ describe("Mock Tests (Data Injection)", () => {
146
+ let client: SearchClient;
147
+ let cli: { request: jest.Mock };
148
+
172
149
  beforeEach(() => {
173
- jest.clearAllMocks();
150
+ cli = { request: jest.fn() };
151
+
152
+ const config = (global as any).testSuite.config as LaplaceConfiguration;
153
+ const logger: Logger = {
154
+ info: jest.fn(),
155
+ error: jest.fn(),
156
+ warn: jest.fn(),
157
+ debug: jest.fn(),
158
+ } as unknown as Logger;
159
+
160
+ client = new SearchClient(config, logger, cli as any);
174
161
  });
175
162
 
176
- describe("SearchStock", () => {
177
- test("should return stock search results with mock data", async () => {
178
- jest.spyOn(client, 'search').mockResolvedValue(mockStockSearchResponse);
179
-
180
- const resp = await client.search(
181
- "TUPRS",
182
- [SearchType.Stock],
183
- Region.Tr,
184
- Locale.Tr
185
- );
186
-
187
- expect(resp.stocks).toHaveLength(1);
188
-
189
- const firstResult = resp.stocks[0];
190
- expect(firstResult.id).toBe("61dd0d6f0ec2114146342fd0");
191
- expect(firstResult.name).toBe("Tüpraş");
192
- expect(firstResult.title).toBe("Türkiye Petrol Rafinerileri A.Ş.");
193
- expect(firstResult.region).toBe(Region.Tr);
194
- expect(firstResult.assetType).toBe("stock");
195
- expect(firstResult.type).toBe("equity");
196
-
197
- expect(resp.industries).toHaveLength(0);
198
- expect(resp.sectors).toHaveLength(0);
199
- expect(resp.collections).toHaveLength(0);
200
-
201
- expect(client.search).toHaveBeenCalledWith(
202
- "TUPRS",
203
- [SearchType.Stock],
204
- Region.Tr,
205
- Locale.Tr
206
- );
207
- });
163
+ function expectSearchCall(expected: {
164
+ filter: string;
165
+ types: SearchType[];
166
+ locale: Locale;
167
+ region?: Region;
168
+ page?: number;
169
+ size?: number;
170
+ }) {
171
+ expect(cli.request).toHaveBeenCalledTimes(1);
172
+ const call = cli.request.mock.calls[0][0];
173
+
174
+ expect(call.method).toBe("GET");
175
+ expect(call.url).toBe("/api/v1/search");
176
+
177
+ const expectedParams: any = {
178
+ filter: expected.filter,
179
+ types: expected.types.join(","),
180
+ locale: expected.locale,
181
+ };
182
+
183
+ if (expected.region != null) expectedParams.region = expected.region;
184
+ if (expected.page != null) expectedParams.page = expected.page;
185
+ if (expected.size != null) expectedParams.size = expected.size;
186
+
187
+ expect(call.params).toEqual(expectedParams);
188
+ }
189
+
190
+ test("SearchStock: calls correct endpoint/params and matches raw response", async () => {
191
+ cli.request.mockResolvedValueOnce({ data: mockStockSearchResponse });
208
192
 
209
- test("should handle API errors for stock search", async () => {
210
- jest.spyOn(client, 'search').mockRejectedValue(new Error("Failed to search stocks"));
193
+ const resp = await client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr);
211
194
 
212
- await expect(client.search(
213
- "TUPRS",
214
- [SearchType.Stock],
215
- Region.Tr,
216
- Locale.Tr
217
- )).rejects.toThrow("Failed to search stocks");
195
+ expectSearchCall({
196
+ filter: "TUPRS",
197
+ types: [SearchType.Stock],
198
+ locale: Locale.Tr,
199
+ region: Region.Tr,
218
200
  });
201
+
202
+ expect(resp.stocks).toHaveLength(1);
203
+ const first = resp.stocks[0];
204
+ expect(first.id).toBe(mockStockSearchResponse.stocks[0].id);
205
+ expect(first.name).toBe(mockStockSearchResponse.stocks[0].name);
206
+ expect(first.title).toBe(mockStockSearchResponse.stocks[0].title);
207
+ expect(first.region).toBe(mockStockSearchResponse.stocks[0].region);
208
+ expect(first.assetType).toBe(mockStockSearchResponse.stocks[0].assetType);
209
+ expect(first.type).toBe(mockStockSearchResponse.stocks[0].type);
210
+
211
+ expect(resp.industries).toHaveLength(0);
212
+ expect(resp.sectors).toHaveLength(0);
213
+ expect(resp.collections).toHaveLength(0);
219
214
  });
220
215
 
221
- describe("SearchIndustry", () => {
222
- test("should return industry search results with mock data", async () => {
223
- jest.spyOn(client, 'search').mockResolvedValue(mockIndustrySearchResponse);
224
-
225
- const resp = await client.search(
226
- "Hava",
227
- [SearchType.Industry],
228
- Region.Tr,
229
- Locale.Tr
230
- );
231
-
232
- expect(resp.industries).toHaveLength(1);
233
-
234
- const firstResult = resp.industries[0];
235
- expect(firstResult.id).toBe("ind123");
236
- expect(firstResult.title).toBe("Hava Yolları Taşımacılığı");
237
- expect(firstResult.region).toEqual([Region.Tr]);
238
- expect(firstResult.assetClass).toBe("equity");
239
- expect(firstResult.imageUrl).toBe("https://example.com/image.jpg");
240
- expect(firstResult.avatarUrl).toBe("https://example.com/avatar.jpg");
241
-
242
- expect(resp.stocks).toHaveLength(0);
243
- expect(resp.sectors).toHaveLength(0);
244
- expect(resp.collections).toHaveLength(0);
245
-
246
- expect(client.search).toHaveBeenCalledWith(
247
- "Hava",
248
- [SearchType.Industry],
249
- Region.Tr,
250
- Locale.Tr
251
- );
216
+ test("SearchIndustry: calls correct endpoint/params and matches raw response", async () => {
217
+ cli.request.mockResolvedValueOnce({ data: mockIndustrySearchResponse });
218
+
219
+ const resp = await client.search("Hava", [SearchType.Industry], Locale.Tr, Region.Tr);
220
+
221
+ expectSearchCall({
222
+ filter: "Hava",
223
+ types: [SearchType.Industry],
224
+ locale: Locale.Tr,
225
+ region: Region.Tr,
252
226
  });
253
227
 
254
- test("should handle API errors for industry search", async () => {
255
- jest.spyOn(client, 'search').mockRejectedValue(new Error("Failed to search industries"));
228
+ expect(resp.industries).toHaveLength(1);
229
+ const first = resp.industries[0];
230
+ expect(first.id).toBe(mockIndustrySearchResponse.industries[0].id);
231
+ expect(first.title).toBe(mockIndustrySearchResponse.industries[0].title);
232
+ expect(first.region).toEqual(mockIndustrySearchResponse.industries[0].region);
233
+ expect(first.assetClass).toBe(mockIndustrySearchResponse.industries[0].assetClass);
234
+ expect(first.imageUrl).toBe(mockIndustrySearchResponse.industries[0].imageUrl);
235
+ expect(first.avatarUrl).toBe(mockIndustrySearchResponse.industries[0].avatarUrl);
236
+
237
+ expect(resp.stocks).toHaveLength(0);
238
+ expect(resp.sectors).toHaveLength(0);
239
+ expect(resp.collections).toHaveLength(0);
240
+ });
256
241
 
257
- await expect(client.search(
258
- "Hava",
259
- [SearchType.Industry],
260
- Region.Tr,
261
- Locale.Tr
262
- )).rejects.toThrow("Failed to search industries");
242
+ test("SearchAllTypes: calls correct endpoint/params and matches raw response", async () => {
243
+ cli.request.mockResolvedValueOnce({ data: mockAllTypesSearchResponse });
244
+
245
+ const resp = await client.search(
246
+ "Ab",
247
+ [SearchType.Stock, SearchType.Industry, SearchType.Sector, SearchType.Collection],
248
+ Locale.Tr,
249
+ Region.Us
250
+ );
251
+
252
+ expectSearchCall({
253
+ filter: "Ab",
254
+ types: [SearchType.Stock, SearchType.Industry, SearchType.Sector, SearchType.Collection],
255
+ locale: Locale.Tr,
256
+ region: Region.Us,
263
257
  });
258
+
259
+ expect(resp.stocks).toHaveLength(1);
260
+ expect(resp.industries).toHaveLength(1);
261
+ expect(resp.sectors).toHaveLength(1);
262
+ expect(resp.collections).toHaveLength(1);
264
263
  });
265
264
 
266
- describe("SearchAllTypes", () => {
267
- test("should return all types search results with mock data", async () => {
268
- jest.spyOn(client, 'search').mockResolvedValue(mockAllTypesSearchResponse);
269
-
270
- const resp = await client.search(
271
- "Ab",
272
- [
273
- SearchType.Stock,
274
- SearchType.Industry,
275
- SearchType.Sector,
276
- SearchType.Collection,
277
- ],
278
- Region.Us,
279
- Locale.Tr
280
- );
281
-
282
- expect(resp.stocks).toHaveLength(1);
283
- expect(resp.stocks[0].name).toBe("Abbott");
284
- expect(resp.stocks[0].region).toBe(Region.Us);
285
-
286
- expect(resp.industries).toHaveLength(1);
287
- expect(resp.industries[0].title).toBe("Abrasive Manufacturing");
288
- expect(resp.industries[0].region).toEqual([Region.Us]);
289
-
290
- expect(resp.sectors).toHaveLength(1);
291
- expect(resp.sectors[0].title).toBe("Aerospace & Defense");
292
- expect(resp.sectors[0].region).toEqual([Region.Us]);
293
-
294
- expect(resp.collections).toHaveLength(1);
295
- expect(resp.collections[0].title).toBe("Artificial Intelligence");
296
- expect(resp.collections[0].region).toEqual([Region.Us]);
297
-
298
- expect(client.search).toHaveBeenCalledWith(
299
- "Ab",
300
- [
301
- SearchType.Stock,
302
- SearchType.Industry,
303
- SearchType.Sector,
304
- SearchType.Collection,
305
- ],
306
- Region.Us,
307
- Locale.Tr
308
- );
265
+ test("does not send optional params when undefined", async () => {
266
+ cli.request.mockResolvedValueOnce({ data: mockStockSearchResponse });
267
+
268
+ await client.search("TUPRS", [SearchType.Stock], Locale.Tr);
269
+
270
+ expectSearchCall({
271
+ filter: "TUPRS",
272
+ types: [SearchType.Stock],
273
+ locale: Locale.Tr,
309
274
  });
275
+ });
276
+
277
+ test("bubbles up request error", async () => {
278
+ cli.request.mockRejectedValueOnce(new Error("Failed to search"));
279
+
280
+ await expect(client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr)).rejects.toThrow(
281
+ "Failed to search"
282
+ );
283
+
284
+ expect(cli.request).toHaveBeenCalledTimes(1);
285
+ });
286
+
287
+ test("page=0 / size=0 should still be sent (guards against falsy spread bug)", async () => {
288
+ cli.request.mockResolvedValueOnce({ data: mockStockSearchResponse });
289
+
290
+ await client.search("TUPRS", [SearchType.Stock], Locale.Tr, Region.Tr, 0, 10);
310
291
 
311
- test("should handle API errors for all types search", async () => {
312
- jest.spyOn(client, 'search').mockRejectedValue(new Error("Failed to search all types"));
313
-
314
- await expect(client.search(
315
- "Ab",
316
- [
317
- SearchType.Stock,
318
- SearchType.Industry,
319
- SearchType.Sector,
320
- SearchType.Collection,
321
- ],
322
- Region.Us,
323
- Locale.Tr
324
- )).rejects.toThrow("Failed to search all types");
292
+ expectSearchCall({
293
+ filter: "TUPRS",
294
+ types: [SearchType.Stock],
295
+ locale: Locale.Tr,
296
+ region: Region.Tr,
297
+ page: 0,
298
+ size: 10,
325
299
  });
326
300
  });
327
301
  });