From fc8b7c47c5c79c5ef34514d685d3171c21049ab1 Mon Sep 17 00:00:00 2001 From: Vedant Madane <6527493+VedantMadane@users.noreply.github.com> Date: Tue, 25 Aug 2026 01:01:15 +0530 Subject: [PATCH] fix: Reject empty/whitespace tenant_id in search filters - reject empty/whitespace tenant_id in build_filter - tests for empty tenant_id Fixes #4 Signed-off-by: Vedant Madane <6527493+VedantMadane@users.noreply.github.com> --- src/tenantq/search.py | 6 ++++++ tests/test_search.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/tenantq/search.py b/src/tenantq/search.py index 41cc5c4..e77e271 100644 --- a/src/tenantq/search.py +++ b/src/tenantq/search.py @@ -44,6 +44,12 @@ def build_filter( created_before: Optional[int] = None, ) -> models.Filter: """Build a tenant-scoped filter, optionally narrowed by metadata.""" + if tenant_id is None or not str(tenant_id).strip(): + raise ValueError( + "tenant_id is required: request was not scoped to a tenant " + "(empty or whitespace-only tenant_id)" + ) + tenant_id = str(tenant_id).strip() must: List[models.FieldCondition] = [ models.FieldCondition(key=TENANT_FIELD, match=models.MatchValue(value=tenant_id)) ] diff --git a/tests/test_search.py b/tests/test_search.py index 661e0bc..7843804 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -38,3 +38,18 @@ def test_created_at_range_filter(ingested, settings, embedder, dataset): by_id = {d.id: d for d in dataset.documents} for h in hits: assert lo <= by_id[h.id].created_at <= hi + + +import pytest +from tenantq.search import build_filter + + +@pytest.mark.parametrize("bad", ["", " ", "\t"]) +def test_build_filter_rejects_empty_tenant_id(bad): + with pytest.raises(ValueError, match="not scoped"): + build_filter(bad) + + +def test_build_filter_accepts_tenant_with_internal_spaces(): + f = build_filter("acme corp") + assert f.must