@@ -564,3 +564,72 @@ def test_search_filter_by_feature(client: TestClient, values: dict):
564564 assert requested_features .intersection (features ), (
565565 f"Feed { result .id } with features { features } does not match " f"requested features { requested_features } "
566566 )
567+
568+
569+ @pytest .mark .parametrize (
570+ "values" ,
571+ [
572+ {"license_tags" : "family:ODC" , "expected_count" : 1 },
573+ {"license_tags" : "license:open-data-commons" , "expected_count" : 1 },
574+ # AND semantics: feed must contain ALL requested tags
575+ {"license_tags" : "family:ODC,license:open-data-commons" , "expected_count" : 1 },
576+ {"license_tags" : "nonexistent:tag" , "expected_count" : 0 },
577+ {"license_tags" : "license:open-data-commons,nonexistent:tag" , "expected_count" : 0 },
578+ {"license_tags" : "" , "expected_count" : 16 },
579+ ],
580+ ids = [
581+ "Filter by single tag family:ODC" ,
582+ "Filter by single tag license:open-data-commons" ,
583+ "Filter by multiple tags (AND semantics)" ,
584+ "No feed matches nonexistent tag" ,
585+ "Mixed existing and nonexistent tag (AND semantics)" ,
586+ "No filter returns all feeds" ,
587+ ],
588+ )
589+ def test_search_filter_by_license_tags (client : TestClient , values : dict ):
590+ """Retrieve feeds that have licenses associated with specific license tag IDs.
591+
592+ The ``license_tags`` parameter accepts a comma-separated list of tag IDs.
593+ The filter uses AND semantics: the feed's ``license_tags`` array must
594+ contain **all** of the requested tags for the feed to be returned.
595+ """
596+
597+ params = None
598+ if values ["license_tags" ]:
599+ params = [("license_tags" , values ["license_tags" ])]
600+
601+ headers = {"Authentication" : "special-key" }
602+ response = client .request ("GET" , "/v1/search" , headers = headers , params = params )
603+
604+ assert response .status_code == 200
605+
606+ response_body = SearchFeeds200Response .model_validate (response .json ())
607+ expected_count = values ["expected_count" ]
608+ assert (
609+ response_body .total == expected_count
610+ ), f"There should be { expected_count } feeds for license_tags={ values ['license_tags' ]} "
611+
612+
613+ def test_search_result_contains_license_tags (client : TestClient ):
614+ """
615+ Verify that the search results include license_tags for feeds with license tags.
616+ """
617+ params = [
618+ ("feed_id" , "mdb-70" ),
619+ ]
620+ headers = {
621+ "Authentication" : "special-key" ,
622+ }
623+ response = client .request (
624+ "GET" ,
625+ "/v1/search" ,
626+ headers = headers ,
627+ params = params ,
628+ )
629+ assert response .status_code == 200
630+ response_body = SearchFeeds200Response .parse_obj (response .json ())
631+ assert response_body .total == 1
632+ result = response_body .results [0 ]
633+ assert result .source_info .license_tags is not None
634+ assert "family:ODC" in result .source_info .license_tags [0 ]
635+ assert "license:open-data-commons" in result .source_info .license_tags [1 ]
0 commit comments