@@ -284,6 +284,131 @@ describe('SearchService', () => {
284284 expect ( remoteResult . map ( note => note . id ) ) . toEqual ( [ remoteNote . id ] ) ;
285285 } ) ;
286286
287+ describe ( 'date range' , ( ) => {
288+ test ( 'filters notes after rangeStartAt' , async ( ) => {
289+ const ctx = getCtx ( ) ;
290+ const me = await createUser ( ctx , { username : 'me' , usernameLower : 'me' , host : null } ) ;
291+ const author = await createUser ( ctx , { username : 'author' , usernameLower : 'author' , host : null } ) ;
292+
293+ const t1 = Date . now ( ) - 3000 ;
294+ const t2 = Date . now ( ) - 2000 ;
295+ const t3 = Date . now ( ) - 1000 ;
296+
297+ await createNote ( ctx , author , { text : 'hello old' } , t1 ) ;
298+ const note2 = await createNote ( ctx , author , { text : 'hello middle' } , t2 ) ;
299+ const note3 = await createNote ( ctx , author , { text : 'hello new' } , t3 ) ;
300+
301+ const result = await ctx . service . searchNote ( 'hello' , me , { rangeStartAt : t2 } , { limit : 10 } ) ;
302+ expect ( result . map ( note => note . id ) ) . toEqual ( [ note3 . id , note2 . id ] ) ;
303+ } ) ;
304+
305+ test ( 'filters notes before rangeEndAt' , async ( ) => {
306+ const ctx = getCtx ( ) ;
307+ const me = await createUser ( ctx , { username : 'me' , usernameLower : 'me' , host : null } ) ;
308+ const author = await createUser ( ctx , { username : 'author' , usernameLower : 'author' , host : null } ) ;
309+
310+ const t1 = Date . now ( ) - 3000 ;
311+ const t2 = Date . now ( ) - 2000 ;
312+ const t3 = Date . now ( ) - 1000 ;
313+
314+ const note1 = await createNote ( ctx , author , { text : 'hello old' } , t1 ) ;
315+ const note2 = await createNote ( ctx , author , { text : 'hello middle' } , t2 ) ;
316+ await createNote ( ctx , author , { text : 'hello new' } , t3 ) ;
317+
318+ const result = await ctx . service . searchNote ( 'hello' , me , { rangeEndAt : t2 } , { limit : 10 } ) ;
319+ expect ( result . map ( note => note . id ) ) . toEqual ( [ note2 . id , note1 . id ] ) ;
320+ } ) ;
321+
322+ test ( 'filters notes between rangeStartAt and rangeEndAt' , async ( ) => {
323+ const ctx = getCtx ( ) ;
324+ const me = await createUser ( ctx , { username : 'me' , usernameLower : 'me' , host : null } ) ;
325+ const author = await createUser ( ctx , { username : 'author' , usernameLower : 'author' , host : null } ) ;
326+
327+ const t1 = Date . now ( ) - 4000 ;
328+ const t2 = Date . now ( ) - 3000 ;
329+ const t3 = Date . now ( ) - 2000 ;
330+ const t4 = Date . now ( ) - 1000 ;
331+
332+ await createNote ( ctx , author , { text : 'hello old' } , t1 ) ;
333+ const note2 = await createNote ( ctx , author , { text : 'hello middle' } , t2 ) ;
334+ const note3 = await createNote ( ctx , author , { text : 'hello newer' } , t3 ) ;
335+ await createNote ( ctx , author , { text : 'hello new' } , t4 ) ;
336+
337+ const result = await ctx . service . searchNote ( 'hello' , me , { rangeStartAt : t2 , rangeEndAt : t3 } , { limit : 10 } ) ;
338+ expect ( result . map ( note => note . id ) ) . toEqual ( [ note3 . id , note2 . id ] ) ;
339+ } ) ;
340+
341+ test ( 'keeps pagination within date range when sinceId and untilId are outside range' , async ( ) => {
342+ const ctx = getCtx ( ) ;
343+ const me = await createUser ( ctx , { username : 'me' , usernameLower : 'me' , host : null } ) ;
344+ const author = await createUser ( ctx , { username : 'author' , usernameLower : 'author' , host : null } ) ;
345+
346+ const t1 = Date . now ( ) - 8000 ;
347+ const t2 = Date . now ( ) - 7000 ;
348+ const t3 = Date . now ( ) - 6000 ;
349+ const t4 = Date . now ( ) - 5000 ;
350+ const t5 = Date . now ( ) - 4000 ;
351+ const t6 = Date . now ( ) - 3000 ;
352+ const t7 = Date . now ( ) - 2000 ;
353+ const t8 = Date . now ( ) - 1000 ;
354+
355+ await createNote ( ctx , author , { text : 'hello outside oldest' } , t1 ) ;
356+ const sinceCursor = await createNote ( ctx , author , { text : 'hello since cursor before range' } , t2 ) ;
357+ const beforeRange = await createNote ( ctx , author , { text : 'hello before range but after since' } , t3 ) ;
358+ const note4 = await createNote ( ctx , author , { text : 'hello range old' } , t4 ) ;
359+ const note5 = await createNote ( ctx , author , { text : 'hello range middle' } , t5 ) ;
360+ const note6 = await createNote ( ctx , author , { text : 'hello range new' } , t6 ) ;
361+ const afterRange = await createNote ( ctx , author , { text : 'hello after range but before until' } , t7 ) ;
362+ const untilCursor = await createNote ( ctx , author , { text : 'hello until cursor after range' } , t8 ) ;
363+
364+ const result = await ctx . service . searchNote (
365+ 'hello' ,
366+ me ,
367+ { rangeStartAt : t4 , rangeEndAt : t6 } ,
368+ { limit : 10 , sinceId : sinceCursor . id , untilId : untilCursor . id } ,
369+ ) ;
370+ const resultIds = result . map ( note => note . id ) ;
371+ expect ( resultIds ) . toEqual ( [ note6 . id , note5 . id , note4 . id ] ) ;
372+ expect ( resultIds ) . not . toContain ( beforeRange . id ) ;
373+ expect ( resultIds ) . not . toContain ( afterRange . id ) ;
374+ } ) ;
375+
376+ test ( 'uses sinceId and untilId as pagination boundaries inside date range' , async ( ) => {
377+ const ctx = getCtx ( ) ;
378+ const me = await createUser ( ctx , { username : 'me' , usernameLower : 'me' , host : null } ) ;
379+ const author = await createUser ( ctx , { username : 'author' , usernameLower : 'author' , host : null } ) ;
380+
381+ const t1 = Date . now ( ) - 8000 ;
382+ const t2 = Date . now ( ) - 7000 ;
383+ const t3 = Date . now ( ) - 6000 ;
384+ const t4 = Date . now ( ) - 5000 ;
385+ const t5 = Date . now ( ) - 4000 ;
386+ const t6 = Date . now ( ) - 3000 ;
387+ const t7 = Date . now ( ) - 2000 ;
388+ const t8 = Date . now ( ) - 1000 ;
389+
390+ await createNote ( ctx , author , { text : 'hello before range' } , t1 ) ;
391+ const rangeOldest = await createNote ( ctx , author , { text : 'hello range oldest' } , t2 ) ;
392+ const sinceCursor = await createNote ( ctx , author , { text : 'hello since cursor in range' } , t3 ) ;
393+ const note4 = await createNote ( ctx , author , { text : 'hello page old' } , t4 ) ;
394+ const note5 = await createNote ( ctx , author , { text : 'hello page new' } , t5 ) ;
395+ const untilCursor = await createNote ( ctx , author , { text : 'hello until cursor in range' } , t6 ) ;
396+ const rangeNewest = await createNote ( ctx , author , { text : 'hello range newest' } , t7 ) ;
397+ await createNote ( ctx , author , { text : 'hello after range' } , t8 ) ;
398+
399+ const result = await ctx . service . searchNote (
400+ 'hello' ,
401+ me ,
402+ { rangeStartAt : t2 , rangeEndAt : t7 } ,
403+ { limit : 10 , sinceId : sinceCursor . id , untilId : untilCursor . id } ,
404+ ) ;
405+ const resultIds = result . map ( note => note . id ) ;
406+ expect ( resultIds ) . toEqual ( [ note5 . id , note4 . id ] ) ;
407+ expect ( resultIds ) . not . toContain ( rangeOldest . id ) ;
408+ expect ( resultIds ) . not . toContain ( rangeNewest . id ) ;
409+ } ) ;
410+ } ) ;
411+
287412 describe ( 'muting and blocking' , ( ) => {
288413 test ( 'filters out muted users' , async ( ) => {
289414 const ctx = getCtx ( ) ;
0 commit comments