@@ -677,53 +677,88 @@ async def test_queryables_enum_platform(
677
677
678
678
679
679
@pytest .mark .asyncio
680
- async def test_search_filter_ext_or_with_must_condition (app_client , ctx ):
680
+ async def test_search_filter_ext_or_with_must_condition (app_client , load_test_data ):
681
681
"""
682
682
Test that OR conditions require at least one match when combined with MUST.
683
- This test will fail if minimum_should_match=1 is not set in the ES query.
683
+ This test will fail if minimum_should_match=1 is not set in the ES/OS query.
684
684
"""
685
- # Case 1: At least one OR condition matches (should return the item)
685
+ # Arrange: Create a unique collection for this test
686
+ collection_data = load_test_data ("test_collection.json" )
687
+ collection_id = collection_data ["id" ] = f"or-test-collection-{ uuid .uuid4 ()} "
688
+ r = await app_client .post ("/collections" , json = collection_data )
689
+ r .raise_for_status ()
690
+
691
+ # Add three items:
692
+ # 1. Matches both must and should
693
+ # 2. Matches must but not should
694
+ # 3. Matches neither
695
+ items = [
696
+ {
697
+ "eo:cloud_cover" : 0 ,
698
+ "proj:epsg" : 32756 ,
699
+ }, # Should be returned when should matches
700
+ {
701
+ "eo:cloud_cover" : 5 ,
702
+ "proj:epsg" : 88888 ,
703
+ }, # Should NOT be returned if min_should_match=1
704
+ {"eo:cloud_cover" : - 5 , "proj:epsg" : 99999 }, # Should not be returned at all
705
+ ]
706
+ for idx , props in enumerate (items ):
707
+ item_data = load_test_data ("test_item.json" )
708
+ item_data ["id" ] = f"or-test-item-{ idx } "
709
+ item_data ["collection" ] = collection_id
710
+ item_data ["properties" ]["eo:cloud_cover" ] = props ["eo:cloud_cover" ]
711
+ item_data ["properties" ]["proj:epsg" ] = props ["proj:epsg" ]
712
+ r = await app_client .post (f"/collections/{ collection_id } /items" , json = item_data )
713
+ r .raise_for_status ()
714
+
715
+ # Case 1: At least one OR condition matches (should return only the first item)
686
716
params = {
687
717
"filter" : {
688
718
"op" : "and" ,
689
719
"args" : [
690
- {
691
- "op" : ">=" ,
692
- "args" : [{"property" : "eo:cloud_cover" }, 0 ],
693
- }, # True for test item (cloud_cover=0)
720
+ {"op" : ">=" , "args" : [{"property" : "eo:cloud_cover" }, 0 ]},
694
721
{
695
722
"op" : "or" ,
696
723
"args" : [
697
724
{
698
725
"op" : "<" ,
699
726
"args" : [{"property" : "eo:cloud_cover" }, 1 ],
700
- }, # True for test item (cloud_cover=0)
727
+ }, # Only first item matches
701
728
{
702
729
"op" : "=" ,
703
- "args" : [{"property" : "properties. proj:epsg" }, 99999 ],
704
- }, # False
730
+ "args" : [{"property" : "proj:epsg" }, 32756 ],
731
+ }, # Only first item matches
705
732
],
706
733
},
707
734
],
708
735
}
709
736
}
710
737
resp = await app_client .post ("/search" , json = params )
711
738
assert resp .status_code == 200
712
- resp_json = resp .json ()
739
+ features = resp .json ()[ "features" ]
713
740
assert any (
714
- f ["properties" ].get ("eo:cloud_cover" ) == 0 for f in resp_json ["features" ]
715
- ), "Should return the test item when at least one OR condition matches"
741
+ f ["properties" ].get ("eo:cloud_cover" ) == 0 for f in features
742
+ ), "Should return the item where at least one OR condition matches"
743
+ assert all (
744
+ f ["properties" ].get ("eo:cloud_cover" ) == 0 for f in features
745
+ ), "Should only return the item matching the should clause"
716
746
717
- # Case 2: No OR conditions match (should NOT return the item if minimum_should_match=1 is set)
747
+ # Case 2: No OR conditions match (should NOT return the second item if minimum_should_match=1 is set)
718
748
params ["filter" ]["args" ][1 ]["args" ][0 ]["args" ][
719
749
1
720
- ] = - 1 # Now: cloud_cover < -1 (False )
750
+ ] = - 10 # cloud_cover < -10 (false for all )
721
751
params ["filter" ]["args" ][1 ]["args" ][1 ]["args" ][
722
752
1
723
- ] = 99998 # Now: proj:epsg == 99998 (False )
753
+ ] = 12345 # proj:epsg == 12345 (false for all )
724
754
resp = await app_client .post ("/search" , json = params )
725
755
assert resp .status_code == 200
726
- resp_json = resp .json ()
727
- assert all (
728
- f ["properties" ].get ("eo:cloud_cover" ) != 0 for f in resp_json ["features" ]
729
- ), "Should NOT return the test item when no OR conditions match (requires minimum_should_match=1)"
756
+ features = resp .json ()["features" ]
757
+ assert len (features ) == 0 , (
758
+ "Should NOT return items that match only the must clause when no OR conditions match "
759
+ "(requires minimum_should_match=1)"
760
+ )
761
+
762
+ # Clean up
763
+ r = await app_client .delete (f"/collections/{ collection_id } " )
764
+ r .raise_for_status ()
0 commit comments