@@ -352,13 +352,20 @@ async fn index_sorting() -> anyhow::Result<()> {
352
352
assert_eq ! ( json. crates[ 2 ] . name, "bar_sort" ) ;
353
353
assert_eq ! ( json. crates[ 3 ] . name, "foo_sort" ) ;
354
354
}
355
- let ( resp, calls) = page_with_seek ( & anon, "sort=downloads" ) . await ;
355
+ let ( resp, calls) = page_with_seek_forward ( & anon, "sort=downloads" ) . await ;
356
356
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "other_sort" ) ;
357
357
assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "baz_sort" ) ;
358
358
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "bar_sort" ) ;
359
359
assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "foo_sort" ) ;
360
360
assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
361
361
assert_eq ! ( calls, 5 ) ;
362
+ let ( resp, calls) = page_with_seek_backward ( & anon, "sort=downloads" ) . await ;
363
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "foo_sort" ) ;
364
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "bar_sort" ) ;
365
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "baz_sort" ) ;
366
+ assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "other_sort" ) ;
367
+ assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
368
+ assert_eq ! ( calls, 5 ) ;
362
369
363
370
// Sort by recent-downloads
364
371
for json in search_both ( & anon, "sort=recent-downloads" ) . await {
@@ -368,13 +375,20 @@ async fn index_sorting() -> anyhow::Result<()> {
368
375
assert_eq ! ( json. crates[ 2 ] . name, "bar_sort" ) ;
369
376
assert_eq ! ( json. crates[ 3 ] . name, "other_sort" ) ;
370
377
}
371
- let ( resp, calls) = page_with_seek ( & anon, "sort=recent-downloads" ) . await ;
378
+ let ( resp, calls) = page_with_seek_forward ( & anon, "sort=recent-downloads" ) . await ;
372
379
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "baz_sort" ) ;
373
380
assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "foo_sort" ) ;
374
381
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "bar_sort" ) ;
375
382
assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "other_sort" ) ;
376
383
assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
377
384
assert_eq ! ( calls, 5 ) ;
385
+ let ( resp, calls) = page_with_seek_backward ( & anon, "sort=recent-downloads" ) . await ;
386
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "other_sort" ) ;
387
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "bar_sort" ) ;
388
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "foo_sort" ) ;
389
+ assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "baz_sort" ) ;
390
+ assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
391
+ assert_eq ! ( calls, 5 ) ;
378
392
379
393
// Sort by recent-updates
380
394
for json in search_both ( & anon, "sort=recent-updates" ) . await {
@@ -384,13 +398,20 @@ async fn index_sorting() -> anyhow::Result<()> {
384
398
assert_eq ! ( json. crates[ 2 ] . name, "bar_sort" ) ;
385
399
assert_eq ! ( json. crates[ 3 ] . name, "foo_sort" ) ;
386
400
}
387
- let ( resp, calls) = page_with_seek ( & anon, "sort=recent-updates" ) . await ;
401
+ let ( resp, calls) = page_with_seek_forward ( & anon, "sort=recent-updates" ) . await ;
388
402
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "other_sort" ) ;
389
403
assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "baz_sort" ) ;
390
404
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "bar_sort" ) ;
391
405
assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "foo_sort" ) ;
392
406
assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
393
407
assert_eq ! ( calls, 5 ) ;
408
+ let ( resp, calls) = page_with_seek_backward ( & anon, "sort=recent-updates" ) . await ;
409
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "foo_sort" ) ;
410
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "bar_sort" ) ;
411
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "baz_sort" ) ;
412
+ assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "other_sort" ) ;
413
+ assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
414
+ assert_eq ! ( calls, 5 ) ;
394
415
395
416
// Sort by new
396
417
for json in search_both ( & anon, "sort=new" ) . await {
@@ -400,28 +421,41 @@ async fn index_sorting() -> anyhow::Result<()> {
400
421
assert_eq ! ( json. crates[ 2 ] . name, "baz_sort" ) ;
401
422
assert_eq ! ( json. crates[ 3 ] . name, "foo_sort" ) ;
402
423
}
403
- let ( resp, calls) = page_with_seek ( & anon, "sort=new" ) . await ;
424
+ let ( resp, calls) = page_with_seek_forward ( & anon, "sort=new" ) . await ;
404
425
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "bar_sort" ) ;
405
426
assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "other_sort" ) ;
406
427
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "baz_sort" ) ;
407
428
assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "foo_sort" ) ;
408
429
assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
409
430
assert_eq ! ( calls, 5 ) ;
431
+ let ( resp, calls) = page_with_seek_backward ( & anon, "sort=new" ) . await ;
432
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "foo_sort" ) ;
433
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "baz_sort" ) ;
434
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "other_sort" ) ;
435
+ assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "bar_sort" ) ;
436
+ assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
437
+ assert_eq ! ( calls, 5 ) ;
410
438
411
439
// Sort by alpha with query
412
440
// ordering (exact match desc, name asc)
413
441
let query = "sort=alpha&q=bar_sort" ;
414
- let ( resp, calls) = page_with_seek ( & anon, query) . await ;
442
+ let ( resp, calls) = page_with_seek_forward ( & anon, query) . await ;
415
443
for json in search_both ( & anon, query) . await {
416
444
assert_eq ! ( json. meta. total, 3 ) ;
417
445
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "bar_sort" ) ;
418
446
assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "baz_sort" ) ;
419
447
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "foo_sort" ) ;
420
448
}
421
449
assert_eq ! ( calls, 4 ) ;
450
+ let ( resp, calls) = page_with_seek_backward ( & anon, query) . await ;
451
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "foo_sort" ) ;
452
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "baz_sort" ) ;
453
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "bar_sort" ) ;
454
+ assert_eq ! ( resp[ 2 ] . meta. total, 3 ) ;
455
+ assert_eq ! ( calls, 4 ) ;
422
456
423
457
let query = "sort=alpha&q=sort" ;
424
- let ( resp, calls) = page_with_seek ( & anon, query) . await ;
458
+ let ( resp, calls) = page_with_seek_forward ( & anon, query) . await ;
425
459
for json in search_both ( & anon, query) . await {
426
460
assert_eq ! ( json. meta. total, 4 ) ;
427
461
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "bar_sort" ) ;
@@ -430,11 +464,18 @@ async fn index_sorting() -> anyhow::Result<()> {
430
464
assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "other_sort" ) ;
431
465
}
432
466
assert_eq ! ( calls, 5 ) ;
467
+ let ( resp, calls) = page_with_seek_backward ( & anon, query) . await ;
468
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "other_sort" ) ;
469
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "foo_sort" ) ;
470
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "baz_sort" ) ;
471
+ assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "bar_sort" ) ;
472
+ assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
473
+ assert_eq ! ( calls, 5 ) ;
433
474
434
475
// Sort by relevance
435
476
// ordering (exact match desc, rank desc, name asc)
436
477
let query = "q=foo_sort" ;
437
- let ( resp, calls) = page_with_seek ( & anon, query) . await ;
478
+ let ( resp, calls) = page_with_seek_forward ( & anon, query) . await ;
438
479
for json in search_both ( & anon, query) . await {
439
480
assert_eq ! ( json. meta. total, 3 ) ;
440
481
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "foo_sort" ) ;
@@ -443,13 +484,19 @@ async fn index_sorting() -> anyhow::Result<()> {
443
484
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "baz_sort" ) ;
444
485
}
445
486
assert_eq ! ( calls, 4 ) ;
487
+ let ( resp, calls) = page_with_seek_backward ( & anon, query) . await ;
488
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "baz_sort" ) ;
489
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "bar_sort" ) ;
490
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "foo_sort" ) ;
491
+ assert_eq ! ( resp[ 2 ] . meta. total, 3 ) ;
492
+ assert_eq ! ( calls, 4 ) ;
446
493
let ranks = querystring_rank ( & mut conn, "foo_sort" ) . await ;
447
494
assert_eq ! ( ranks. get( "bar_sort" ) , ranks. get( "baz_sort" ) ) ;
448
495
449
496
// Add query containing a space to ensure tsquery works
450
497
// "foo_sort" and "foo sort" would generate same tsquery
451
498
let query = "q=foo%20sort" ;
452
- let ( resp, calls) = page_with_seek ( & anon, query) . await ;
499
+ let ( resp, calls) = page_with_seek_forward ( & anon, query) . await ;
453
500
for json in search_both ( & anon, query) . await {
454
501
assert_eq ! ( json. meta. total, 3 ) ;
455
502
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "foo_sort" ) ;
@@ -458,11 +505,17 @@ async fn index_sorting() -> anyhow::Result<()> {
458
505
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "baz_sort" ) ;
459
506
}
460
507
assert_eq ! ( calls, 4 ) ;
508
+ let ( resp, calls) = page_with_seek_backward ( & anon, query) . await ;
509
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "baz_sort" ) ;
510
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "bar_sort" ) ;
511
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "foo_sort" ) ;
512
+ assert_eq ! ( resp[ 2 ] . meta. total, 3 ) ;
513
+ assert_eq ! ( calls, 4 ) ;
461
514
let ranks = querystring_rank ( & mut conn, "foo%20sort" ) . await ;
462
515
assert_eq ! ( ranks. get( "bar_sort" ) , ranks. get( "baz_sort" ) ) ;
463
516
464
517
let query = "q=sort" ;
465
- let ( resp, calls) = page_with_seek ( & anon, query) . await ;
518
+ let ( resp, calls) = page_with_seek_forward ( & anon, query) . await ;
466
519
for json in search_both ( & anon, query) . await {
467
520
assert_eq ! ( json. meta. total, 4 ) ;
468
521
// by rank desc (items with more "sort" should have a hider rank value)
@@ -472,6 +525,13 @@ async fn index_sorting() -> anyhow::Result<()> {
472
525
assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "other_sort" ) ;
473
526
}
474
527
assert_eq ! ( calls, 5 ) ;
528
+ let ( resp, calls) = page_with_seek_backward ( & anon, query) . await ;
529
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "other_sort" ) ;
530
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "foo_sort" ) ;
531
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "bar_sort" ) ;
532
+ assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "baz_sort" ) ;
533
+ assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
534
+ assert_eq ! ( calls, 5 ) ;
475
535
let ranks = querystring_rank ( & mut conn, "sort" ) . await ;
476
536
assert_eq ! (
477
537
ranks. keys( ) . collect:: <Vec <_>>( ) ,
@@ -480,20 +540,28 @@ async fn index_sorting() -> anyhow::Result<()> {
480
540
481
541
// Test for bug with showing null results first when sorting
482
542
// by descending downloads
483
- for json in search_both ( & anon, "sort=recent-downloads" ) . await {
543
+ let query = "sort=recent-downloads" ;
544
+ for json in search_both ( & anon, query) . await {
484
545
assert_eq ! ( json. meta. total, 4 ) ;
485
546
assert_eq ! ( json. crates[ 0 ] . name, "baz_sort" ) ;
486
547
assert_eq ! ( json. crates[ 1 ] . name, "foo_sort" ) ;
487
548
assert_eq ! ( json. crates[ 2 ] . name, "bar_sort" ) ;
488
549
assert_eq ! ( json. crates[ 3 ] . name, "other_sort" ) ;
489
550
}
490
- let ( resp, calls) = page_with_seek ( & anon, "sort=recent-downloads" ) . await ;
551
+ let ( resp, calls) = page_with_seek_forward ( & anon, query ) . await ;
491
552
assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "baz_sort" ) ;
492
553
assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "foo_sort" ) ;
493
554
assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "bar_sort" ) ;
494
555
assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "other_sort" ) ;
495
556
assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
496
557
assert_eq ! ( calls, 5 ) ;
558
+ let ( resp, calls) = page_with_seek_backward ( & anon, query) . await ;
559
+ assert_eq ! ( resp[ 0 ] . crates[ 0 ] . name, "other_sort" ) ;
560
+ assert_eq ! ( resp[ 1 ] . crates[ 0 ] . name, "bar_sort" ) ;
561
+ assert_eq ! ( resp[ 2 ] . crates[ 0 ] . name, "foo_sort" ) ;
562
+ assert_eq ! ( resp[ 3 ] . crates[ 0 ] . name, "baz_sort" ) ;
563
+ assert_eq ! ( resp[ 3 ] . meta. total, 4 ) ;
564
+ assert_eq ! ( calls, 5 ) ;
497
565
498
566
Ok ( ( ) )
499
567
}
@@ -1052,45 +1120,35 @@ async fn seek_based_pagination() -> anyhow::Result<()> {
1052
1120
. expect_build ( & mut conn)
1053
1121
. await ;
1054
1122
1055
- let mut url = Some ( "?per_page=1" . to_string ( ) ) ;
1056
- let mut results = Vec :: new ( ) ;
1057
- let mut calls = 0 ;
1058
- while let Some ( current_url) = url. take ( ) {
1059
- let resp = anon. search ( current_url. trim_start_matches ( '?' ) ) . await ;
1060
- calls += 1 ;
1061
-
1062
- results. append (
1063
- & mut resp
1064
- . crates
1065
- . iter ( )
1066
- . map ( |res| res. name . clone ( ) )
1067
- . collect :: < Vec < _ > > ( ) ,
1068
- ) ;
1069
-
1070
- if let Some ( new_url) = resp. meta . next_page {
1071
- assert_that ! ( resp. crates, len( eq( 1 ) ) ) ;
1072
- url = Some ( new_url) ;
1073
- assert_eq ! ( resp. meta. total, 3 ) ;
1074
- assert ! ( default_versions_iter( & resp. crates) . all( Option :: is_some) ) ;
1075
- } else {
1076
- assert_that ! ( resp. crates, empty( ) ) ;
1077
- assert_eq ! ( resp. meta. total, 0 ) ;
1078
- }
1079
-
1080
- if calls == 1 {
1081
- assert_eq ! ( resp. meta. prev_page, None ) ;
1082
- }
1123
+ fn names ( resp : & [ crate :: tests:: CrateList ] ) -> std:: vec:: Vec < & str > {
1124
+ resp. iter ( )
1125
+ . flat_map ( |r| r. crates . iter ( ) . map ( |c| c. name . as_str ( ) ) )
1126
+ . collect :: < Vec < _ > > ( )
1083
1127
}
1084
1128
1129
+ let ( resp, calls) = page_with_seek_forward ( & anon, "" ) . await ;
1085
1130
assert_eq ! ( calls, 4 ) ;
1086
1131
assert_eq ! (
1087
1132
vec![
1088
1133
"pagination_links_1" ,
1089
1134
"pagination_links_2" ,
1090
- "pagination_links_3"
1135
+ "pagination_links_3" ,
1136
+ ] ,
1137
+ names( & resp)
1138
+ ) ;
1139
+ assert_eq ! ( resp[ 0 ] . meta. prev_page, None ) ;
1140
+
1141
+ let ( resp, calls) = page_with_seek_backward ( & anon, "" ) . await ;
1142
+ assert_eq ! ( calls, 4 ) ;
1143
+ assert_eq ! (
1144
+ vec![
1145
+ "pagination_links_3" ,
1146
+ "pagination_links_2" ,
1147
+ "pagination_links_1" ,
1091
1148
] ,
1092
- results
1149
+ names ( & resp )
1093
1150
) ;
1151
+ assert_eq ! ( resp[ 0 ] . meta. next_page, None ) ;
1094
1152
1095
1153
Ok ( ( ) )
1096
1154
}
@@ -1250,11 +1308,29 @@ async fn search_both_by_user_id<U: RequestHelper>(
1250
1308
search_both ( anon, & url) . await
1251
1309
}
1252
1310
1253
- async fn page_with_seek < U : RequestHelper > (
1311
+ async fn page_with_seek_forward < U : RequestHelper > (
1312
+ anon : & U ,
1313
+ query : & str ,
1314
+ ) -> ( Vec < crate :: tests:: CrateList > , i32 ) {
1315
+ _page_with_seek ( anon, query, true ) . await
1316
+ }
1317
+
1318
+ async fn page_with_seek_backward < U : RequestHelper > (
1254
1319
anon : & U ,
1255
1320
query : & str ,
1256
1321
) -> ( Vec < crate :: tests:: CrateList > , i32 ) {
1257
- let mut url = Some ( format ! ( "?per_page=1&{query}" ) ) ;
1322
+ _page_with_seek ( anon, query, false ) . await
1323
+ }
1324
+
1325
+ async fn _page_with_seek < U : RequestHelper > (
1326
+ anon : & U ,
1327
+ query : & str ,
1328
+ forward : bool ,
1329
+ ) -> ( Vec < crate :: tests:: CrateList > , i32 ) {
1330
+ let mut url = Some ( format ! (
1331
+ "?per_page=1&{query}{}" ,
1332
+ ( !forward) . then_some( "&seek=-" ) . unwrap_or_default( )
1333
+ ) ) ;
1258
1334
let mut results = Vec :: new ( ) ;
1259
1335
let mut calls = 0 ;
1260
1336
while let Some ( current_url) = url. take ( ) {
@@ -1264,7 +1340,13 @@ async fn page_with_seek<U: RequestHelper>(
1264
1340
panic ! ( "potential infinite loop detected!" )
1265
1341
}
1266
1342
1267
- if let Some ( ref new_url) = resp. meta . next_page {
1343
+ let next_url = if forward {
1344
+ resp. meta . next_page . as_ref ( )
1345
+ } else {
1346
+ resp. meta . prev_page . as_ref ( )
1347
+ } ;
1348
+
1349
+ if let Some ( new_url) = next_url {
1268
1350
assert ! ( new_url. contains( "seek=" ) ) ;
1269
1351
assert_that ! ( resp. crates, len( eq( 1 ) ) ) ;
1270
1352
url = Some ( new_url. to_owned ( ) ) ;
0 commit comments