@@ -664,7 +664,15 @@ def validate_api(
664664
665665 if "item-search#sort" in ccs_to_validate :
666666 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+ )
668676
669677 if "item-search#query" in ccs_to_validate :
670678 logger .info ("STAC API - Item Search - Query extension conformance class found." )
@@ -3532,3 +3540,124 @@ def validate_transaction(
35323540 context = context ,
35333541 r_session = r_session ,
35343542 )
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