-
Notifications
You must be signed in to change notification settings - Fork 106
feat: Add support for Dynamic Search Rules (v1.41) #1228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1b56432
74dd9eb
6f918cb
c5bd2be
c056a2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| import pytest | ||
| from meilisearch.errors import MeilisearchApiError | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def test_index(client_with_index): | ||
| index = client_with_index() | ||
| yield index | ||
| index.delete() | ||
|
|
||
|
|
||
| def test_list_dynamic_search_rules(test_index): | ||
| """Test listing dynamic search rules""" | ||
| response = test_index.list_dynamic_search_rules() | ||
| assert isinstance(response, dict) | ||
| assert "results" in response or "meta" in response | ||
| if "results" in response: | ||
| assert isinstance(response["results"], list) | ||
|
|
||
|
|
||
| def test_get_dynamic_search_rule(test_index): | ||
| """Test getting a single dynamic search rule""" | ||
| rule_uid = "test-rule-1" | ||
| rule_body = { | ||
| "conditions": [ | ||
| { | ||
| "scope": ["title"], | ||
| "operator": "contains", | ||
| "value": "new" | ||
| } | ||
| ], | ||
| "actions": [ | ||
| { | ||
| "action": "promote", | ||
| "documentIds": ["1"], | ||
| "matchCondition": "all", | ||
| "position": 1 | ||
| } | ||
| ] | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| create_response = test_index.upsert_dynamic_search_rule(rule_uid, rule_body) | ||
| test_index.wait_for_task(create_response.task_uid) | ||
|
|
||
| response = test_index.get_dynamic_search_rule(rule_uid) | ||
| assert isinstance(response, dict) | ||
| assert response.get("uid") == rule_uid | ||
|
|
||
|
|
||
| def test_upsert_dynamic_search_rule(test_index): | ||
| """Test creating or updating a dynamic search rule""" | ||
| rule_uid = "test-rule-2" | ||
| rule_body = { | ||
| "conditions": [ | ||
| { | ||
| "scope": ["title"], | ||
| "operator": "contains", | ||
| "value": "hello" | ||
| } | ||
| ], | ||
| "actions": [ | ||
| { | ||
| "action": "promote", | ||
| "documentIds": ["2"], | ||
| "matchCondition": "all", | ||
| "position": 1 | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| response = test_index.upsert_dynamic_search_rule(rule_uid, rule_body) | ||
| assert response.task_uid is not None | ||
|
|
||
| test_index.wait_for_task(response.task_uid) | ||
|
|
||
| retrieved = test_index.get_dynamic_search_rule(rule_uid) | ||
| assert retrieved.get("uid") == rule_uid | ||
|
Comment on lines
+50
to
+77
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Verify path construction consistency across dynamic search rule methods.
rg -n -C3 'def (upsert_dynamic_search_rule|get_dynamic_search_rule|delete_dynamic_search_rule)\(' meilisearch/index.py
rg -n -C2 'dynamic_search_rules.*uid' meilisearch/index.pyRepository: meilisearch/meilisearch-python Length of output: 1319 Add a multi-index isolation test to catch endpoint scoping regressions in The current tests use only a single index, which masks a critical bug: 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| def test_delete_dynamic_search_rule(test_index): | ||
| """Test deleting a dynamic search rule""" | ||
| rule_uid = "test-rule-3" | ||
| rule_body = { | ||
| "conditions": [ | ||
| { | ||
| "scope": ["title"], | ||
| "operator": "contains", | ||
| "value": "delete-me" | ||
| } | ||
| ], | ||
| "actions": [ | ||
| { | ||
| "action": "promote", | ||
| "documentIds": ["3"], | ||
| "matchCondition": "all", | ||
| "position": 1 | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| create_response = test_index.upsert_dynamic_search_rule(rule_uid, rule_body) | ||
| test_index.wait_for_task(create_response.task_uid) | ||
|
|
||
| delete_response = test_index.delete_dynamic_search_rule(rule_uid) | ||
| assert delete_response.task_uid is not None | ||
|
|
||
| test_index.wait_for_task(delete_response.task_uid) | ||
|
|
||
| with pytest.raises(MeilisearchApiError): | ||
| test_index.get_dynamic_search_rule(rule_uid) | ||
|
|
||
|
|
||
| def test_upsert_dynamic_search_rule_index_isolation(client_with_index): | ||
| """Test that upsert on one index does not affect another index""" | ||
| index_a = client_with_index() | ||
| index_b = client_with_index() | ||
|
|
||
| rule_uid = "isolation-rule" | ||
| body_a = { | ||
| "conditions": [ | ||
| {"scope": ["title"], "operator": "contains", "value": "foo"} | ||
| ], | ||
| "actions": [ | ||
| {"action": "promote", "documentIds": ["1"], "matchCondition": "all", "position": 1} | ||
| ], | ||
| } | ||
| body_b = { | ||
| "conditions": [ | ||
| {"scope": ["title"], "operator": "contains", "value": "bar"} | ||
| ], | ||
| "actions": [ | ||
| {"action": "promote", "documentIds": ["2"], "matchCondition": "all", "position": 2} | ||
| ], | ||
| } | ||
|
|
||
| try: | ||
| task_a = index_a.upsert_dynamic_search_rule(rule_uid, body_a) | ||
| index_a.wait_for_task(task_a.task_uid) | ||
|
|
||
| task_b = index_b.upsert_dynamic_search_rule(rule_uid, body_b) | ||
| index_b.wait_for_task(task_b.task_uid) | ||
|
|
||
| rule_a = index_a.get_dynamic_search_rule(rule_uid) | ||
| rule_b = index_b.get_dynamic_search_rule(rule_uid) | ||
|
|
||
| assert rule_a.get("uid") == rule_uid | ||
| assert rule_b.get("uid") == rule_uid | ||
| # Rules should be independent per index | ||
| assert rule_a != rule_b | ||
| finally: | ||
| index_a.delete() | ||
| index_b.delete() | ||
Uh oh!
There was an error while loading. Please reload this page.