From 31e5811142489c5ab63eb1d335e3869c3ed6fb1e Mon Sep 17 00:00:00 2001 From: "Sharad." Date: Wed, 16 Sep 2026 21:27:47 +0530 Subject: [PATCH] fix: reject impossible created range in build_filter() created_after > created_before silently built an impossible Range(gte, lte) that returned empty with no error, hiding caller bugs. Raise ValueError when the range is inverted. Closes #12 --- src/tenantq/search.py | 8 ++++++++ tests/test_search.py | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/tenantq/search.py b/src/tenantq/search.py index 5923be5..fead624 100644 --- a/src/tenantq/search.py +++ b/src/tenantq/search.py @@ -58,6 +58,14 @@ def build_filter( models.FieldCondition(key=CATEGORY_FIELD, match=models.MatchValue(value=category)) ) if created_after is not None or created_before is not None: + if ( + created_after is not None + and created_before is not None + and created_after > created_before + ): + raise ValueError( + f"created_after ({created_after}) must be ≤ created_before ({created_before})" + ) must.append( models.FieldCondition( key=CREATED_AT_FIELD, diff --git a/tests/test_search.py b/tests/test_search.py index 7e7ebc6..ffe10a9 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -79,3 +79,15 @@ def test_build_filter_accepts_tenant_with_internal_spaces(): from tenantq.search import build_filter f = build_filter("acme corp") assert f.must + + +def test_build_filter_rejects_impossible_range(): + from tenantq.search import build_filter + with pytest.raises(ValueError, match="must be"): + build_filter("acme", created_after=200, created_before=100) + + +def test_build_filter_allows_wide_open_range(): + from tenantq.search import build_filter + f = build_filter("acme", created_after=100, created_before=200) + assert f.must