Fix multi-word query URL encoding for Tone3000 search

Replace spaces with PostgREST wildcards in ilike filter values so
multi-word queries like 'vox ac30' produce valid URLs.

Root cause: PostgREST filter parser doesn't handle spaces URL-encoded
as '+' in query parameter values, returning 400 Bad Request.

Fix: query.replace(' ', '*') converts spaces to PostgREST wildcards
before inserting into ilike.* pattern. 'vox ac30' becomes
ilike.*vox*ac30* -> ILIKE '%vox%ac30%'.

Changes:
- src/system/tonedownload.py: fix search_models() and search_irs()
- tests/test_tonedownload.py: update test_multi_word_query assertion
This commit is contained in:
2026-06-12 12:43:55 -04:00
parent e890a4aad3
commit 3e55ea8a9d
2 changed files with 279 additions and 142 deletions
+40
View File
@@ -176,6 +176,17 @@ class TestFormatSize:
def test_edge_mb(self):
assert format_size(1024 * 1024) == "1.0 MB"
def test_string_input(self):
"""format_size should handle string inputs (Supabase can return string)."""
assert format_size("500") == "0.5 KB"
assert format_size("2097152") == "2.0 MB"
assert format_size("1024") == "1.0 KB"
def test_invalid_string(self):
"""format_size should handle unparseable string inputs."""
assert format_size("not-a-number") == "Unknown"
assert format_size("") == "Unknown"
# ── Client initialization ──────────────────────────────────────────────
@@ -389,6 +400,35 @@ class TestSearchModels:
results = await client.search_models("nonexistent_xyz123", page=0)
assert isinstance(results, list)
@pytest.mark.asyncio
async def test_multi_word_query(self, client):
"""Multi-word queries should convert spaces to wildcards."""
captured_params = []
async def mock_get(path, params=None):
if path == "models" and params and "name" in params:
captured_params.append(params)
return [SAMPLE_MODEL_ROW]
if path == "users":
return [SAMPLE_USER_ROW]
if path == "tones":
return [SAMPLE_TONE_ROW]
return []
client._supabase_get = mock_get
results = await client.search_models("vox ac30", page=0)
assert len(results) == 1
assert results[0].name == "Marshall JCM800"
# Verify the Supabase param has spaces replaced with wildcards
assert len(captured_params) >= 1
name_param = captured_params[0].get("name", "")
assert "ilike.*vox*ac30*" in name_param
# Should NOT contain the raw space (which PostgREST filter parser
# can't handle in URL query values)
assert "vox ac30" not in name_param
class TestSearchIRs:
@pytest.mark.asyncio