@@ -664,7 +664,15 @@ def validate_api(
664
664
665
665
if "item-search#sort" in ccs_to_validate :
666
666
logger .info ("STAC API - Item Search - Sort extension conformance class found." )
667
- logger .info ("STAC API - Item Search - Sort extension is not yet supported." )
667
+ validate_sort (
668
+ context = Context .ITEM_SEARCH_SORT ,
669
+ landing_page_body = landing_page_body ,
670
+ collection = collection ,
671
+ errors = errors ,
672
+ warnings = warnings ,
673
+ r_session = r_session ,
674
+ query_config = query_config ,
675
+ )
668
676
669
677
if "item-search#query" in ccs_to_validate :
670
678
logger .info ("STAC API - Item Search - Query extension conformance class found." )
@@ -3532,3 +3540,124 @@ def validate_transaction(
3532
3540
context = context ,
3533
3541
r_session = r_session ,
3534
3542
)
3543
+
3544
+
3545
+ def validate_sort (
3546
+ landing_page_body : Dict [str , Any ],
3547
+ collection : str ,
3548
+ errors : Errors ,
3549
+ warnings : Warnings ,
3550
+ r_session : Session ,
3551
+ context : Context ,
3552
+ query_config : QueryConfig ,
3553
+ ) -> None :
3554
+ limit = 100
3555
+
3556
+ search_method_to_url : dict [Method , str ] = {
3557
+ Method [x .get ("method" , "GET" )]: x .get ("href" )
3558
+ for x in links_by_rel (landing_page_body .get ("links" ), "search" )
3559
+ }
3560
+
3561
+ # ascending
3562
+ if Method .GET in search_method_to_url :
3563
+ for sortby in ["properties.datetime" , "+properties.datetime" ]:
3564
+ _ , body , _ = retrieve (
3565
+ Method .GET ,
3566
+ search_method_to_url [Method .GET ],
3567
+ params = {
3568
+ "sortby" : sortby ,
3569
+ "limit" : limit ,
3570
+ "collections" : collection ,
3571
+ },
3572
+ errors = errors ,
3573
+ context = context ,
3574
+ r_session = r_session ,
3575
+ )
3576
+
3577
+ if not len (body ["features" ]):
3578
+ errors += (
3579
+ f"[{ context } ] : GET search with Sort '{ sortby } ' had no results"
3580
+ )
3581
+
3582
+ datetimes = [f ["properties" ]["datetime" ] for f in body ["features" ]]
3583
+ sorted_datetimes = copy .deepcopy (datetimes )
3584
+ sorted_datetimes .sort ()
3585
+
3586
+ if datetimes != sorted_datetimes :
3587
+ errors += f"[{ context } ] : GET search with Sort '{ sortby } ' was not sorted in ascending order { datetimes } { sorted_datetimes } "
3588
+
3589
+ if Method .POST in search_method_to_url :
3590
+ sortby_json = [{"field" : "properties.datetime" , "direction" : "asc" }]
3591
+ retrieve (
3592
+ Method .POST ,
3593
+ search_method_to_url [Method .POST ],
3594
+ body = {
3595
+ "sortby" : sortby_json ,
3596
+ "limit" : limit ,
3597
+ "collections" : collection ,
3598
+ },
3599
+ errors = errors ,
3600
+ context = context ,
3601
+ r_session = r_session ,
3602
+ )
3603
+
3604
+ if not len (body ["features" ]):
3605
+ errors += f"[{ context } ] : POST search with Sort '{ json .dumps (sortby_json )} ' had no results"
3606
+
3607
+ datetimes = [f ["properties" ]["datetime" ] for f in body ["features" ]]
3608
+ sorted_datetimes = copy .deepcopy (datetimes )
3609
+ sorted_datetimes .sort ()
3610
+
3611
+ if datetimes != sorted_datetimes :
3612
+ errors += f"[{ context } ] : POST search with Sort '{ json .dumps (sortby_json )} ' was not sorted in ascending order"
3613
+
3614
+ # descending
3615
+ if Method .GET in search_method_to_url :
3616
+ sortby = "-properties.datetime"
3617
+ _ , body , _ = retrieve (
3618
+ Method .GET ,
3619
+ search_method_to_url [Method .GET ],
3620
+ params = {
3621
+ "sortby" : sortby ,
3622
+ "limit" : limit ,
3623
+ "collections" : collection ,
3624
+ },
3625
+ errors = errors ,
3626
+ context = context ,
3627
+ r_session = r_session ,
3628
+ )
3629
+
3630
+ if not len (body ["features" ]):
3631
+ errors += f"[{ context } ] : GET search with Sort '{ sortby } ' had no results"
3632
+
3633
+ datetimes = [f ["properties" ]["datetime" ] for f in body ["features" ]]
3634
+ sorted_datetimes = copy .deepcopy (datetimes )
3635
+ sorted_datetimes .sort (reverse = True )
3636
+
3637
+ if datetimes != sorted_datetimes :
3638
+ errors += f"[{ context } ] : GET search with Sort '{ sortby } ' was not sorted in descending order { datetimes } { sorted_datetimes } "
3639
+
3640
+ if Method .POST in search_method_to_url :
3641
+ sortby_json = [{"field" : "properties.datetime" , "direction" : "desc" }]
3642
+ retrieve (
3643
+ Method .POST ,
3644
+ search_method_to_url [Method .POST ],
3645
+ body = {
3646
+ "sortby" : sortby_json ,
3647
+ "limit" : limit ,
3648
+ "collections" : collection ,
3649
+ },
3650
+ errors = errors ,
3651
+ context = context ,
3652
+ r_session = r_session ,
3653
+ )
3654
+
3655
+ if not len (body ["features" ]):
3656
+ errors += f"[{ context } ] : POST search with Sort '{ json .dumps (sortby_json )} ' had no results"
3657
+
3658
+ datetimes = [f ["properties" ]["datetime" ] for f in body ["features" ]]
3659
+ sorted_datetimes = copy .deepcopy (datetimes )
3660
+ sorted_datetimes .sort (reverse = True )
3661
+
3662
+ if datetimes != sorted_datetimes :
3663
+ errors += f"[{ context } ] : POST search with Sort '{ json .dumps (sortby_json )} ' was not sorted in descending order"
0 commit comments