1
- import { describe , it , expect , beforeEach , afterEach } from "vitest" ;
1
+ import { describe , it , expect , beforeEach , afterEach , vi } from "vitest" ;
2
2
import { Client as TypesenseClient } from "../../src/Typesense" ;
3
3
import { ObjectNotFound } from "../../src/Typesense/Errors" ;
4
+ import logger from "loglevel" ;
4
5
5
6
type MultiSearchResult = {
6
7
title : string ;
@@ -9,6 +10,14 @@ type MultiSearchResult = {
9
10
} ;
10
11
11
12
describe ( "MultiSearch" , function ( ) {
13
+ const mockConsole = {
14
+ error : vi . fn ( ) ,
15
+ warn : vi . fn ( ) ,
16
+ info : vi . fn ( ) ,
17
+ log : vi . fn ( ) ,
18
+ debug : vi . fn ( ) ,
19
+ } ;
20
+
12
21
const typesense = new TypesenseClient ( {
13
22
nodes : [
14
23
{
@@ -45,6 +54,18 @@ describe("MultiSearch", function () {
45
54
] ;
46
55
47
56
beforeEach ( async function ( ) {
57
+ // Setup console mocking
58
+ vi . spyOn ( console , "error" ) . mockImplementation ( mockConsole . error ) ;
59
+ vi . spyOn ( console , "warn" ) . mockImplementation ( mockConsole . warn ) ;
60
+ vi . spyOn ( console , "info" ) . mockImplementation ( mockConsole . info ) ;
61
+ vi . spyOn ( console , "log" ) . mockImplementation ( mockConsole . log ) ;
62
+ vi . spyOn ( console , "debug" ) . mockImplementation ( mockConsole . debug ) ;
63
+
64
+ typesense . multiSearch . logger . setLevel ( logger . levels . INFO ) ;
65
+
66
+ // Clear any previous mock calls
67
+ vi . clearAllMocks ( ) ;
68
+
48
69
try {
49
70
await typesense . collections ( testCollectionName ) . delete ( ) ;
50
71
} catch ( error ) {
@@ -218,5 +239,59 @@ describe("MultiSearch", function () {
218
239
expect ( result . results [ 0 ] . hits ?. length ) . toBe ( 0 ) ;
219
240
expect ( result . results [ 1 ] . hits ?. length ) . toBe ( 0 ) ;
220
241
} ) ;
242
+
243
+ it ( "warns when individual search pagination is used with union: true" , async function ( ) {
244
+ const searches = {
245
+ union : true as const ,
246
+ searches : [
247
+ { q : "first" , query_by : "title" , page : 1 } ,
248
+ { q : "second" , query_by : "title" , per_page : 10 } ,
249
+ ] ,
250
+ } ;
251
+ const commonParams = {
252
+ collection : testCollectionName ,
253
+ } ;
254
+
255
+ await typesense . multiSearch . perform ( searches , commonParams ) ;
256
+
257
+ expect ( mockConsole . warn ) . toHaveBeenCalledWith (
258
+ "Individual `searches` pagination parameters are ignored when `union: true` is set. Use a top-level pagination parameter instead. See https://typesense.org/docs/29.0/api/federated-multi-search.html#union-search"
259
+ ) ;
260
+ } ) ;
261
+
262
+ it ( "does not warn when union: true is used without individual search pagination" , async function ( ) {
263
+ const searches = {
264
+ union : true as const ,
265
+ searches : [
266
+ { q : "first" , query_by : "title" } ,
267
+ { q : "second" , query_by : "title" } ,
268
+ ] ,
269
+ } ;
270
+ const commonParams = {
271
+ collection : testCollectionName ,
272
+ page : 1 , // top-level pagination is fine
273
+ } ;
274
+
275
+ await typesense . multiSearch . perform ( searches , commonParams ) ;
276
+
277
+ expect ( mockConsole . warn ) . not . toHaveBeenCalled ( ) ;
278
+ } ) ;
279
+
280
+ it ( "does not warn when union is false with individual search pagination" , async function ( ) {
281
+ const searches = {
282
+ union : false as const ,
283
+ searches : [
284
+ { q : "first" , query_by : "title" , page : 1 } ,
285
+ { q : "second" , query_by : "title" , per_page : 10 } ,
286
+ ] ,
287
+ } ;
288
+ const commonParams = {
289
+ collection : testCollectionName ,
290
+ } ;
291
+
292
+ await typesense . multiSearch . perform ( searches , commonParams ) ;
293
+
294
+ expect ( mockConsole . warn ) . not . toHaveBeenCalled ( ) ;
295
+ } ) ;
221
296
} ) ;
222
297
} ) ;
0 commit comments