-
Notifications
You must be signed in to change notification settings - Fork 79
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
Delete slot mapping fix #1602
Delete slot mapping fix #1602
Conversation
WalkthroughThe changes involve a modification to the Changes
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (3)
tests/integration_test/services_test.py (3)
21441-21464
: Enhance test coverage and maintainabilityWhile the test covers the basic flow, consider these improvements:
- Rename test to be more descriptive (e.g.,
test_add_slot_mapping_success
)- Add validation of the actual mapping structure in the response
- Add cleanup in a teardown to ensure test isolation
- Consider parameterizing the test for different slot types and mapping configurations
-def test_add_slot_mapping_1(): +def test_add_slot_mapping_success(): response = client.post( f"/api/bot/{pytest.bot}/slots", json={"name": "name_slot", "type": "text"}, headers={"Authorization": pytest.token_type + " " + pytest.access_token}, ) actual = response.json() assert actual["message"] == "Slot added successfully!" assert actual["success"] assert actual["error_code"] == 0 + response = client.post( f"/api/bot/{pytest.bot}/slots/mapping", json={ "slot": "name_slot", "mapping": {"type": "from_text", "value": "user", "entity": "name_slot"}, }, headers={"Authorization": pytest.token_type + " " + pytest.access_token}, ) actual = response.json() assert actual["message"] == "Slot mapping added" assert actual["success"] assert actual["error_code"] == 0 + # Validate mapping structure + response = client.get( + f"/api/bot/{pytest.bot}/slots/mapping", + headers={"Authorization": pytest.token_type + " " + pytest.access_token}, + ) + actual = response.json() + assert any( + mapping["slot"] == "name_slot" and + mapping["mapping"][0]["type"] == "from_text" and + mapping["mapping"][0]["value"] == "user" and + mapping["mapping"][0]["entity"] == "name_slot" + for mapping in actual["data"] + )
21499-21508
: Improve error case testingThe test could be improved for better clarity and reliability:
- Use a clearly invalid mapping ID (e.g., "non_existent_id") instead of reusing bot ID
- Add verification that the mapping truly doesn't exist before attempting deletion
- Consider testing other error scenarios (e.g., invalid format, empty ID)
def test_delete_slot_mapping_does_not_exist(): + # Verify mapping doesn't exist + response = client.get( + f"/api/bot/{pytest.bot}/slots/mapping", + headers={"Authorization": pytest.token_type + " " + pytest.access_token}, + ) + actual = response.json() + assert actual["success"] + assert not any( + any(m["_id"] == "non_existent_id" for m in mapping["mapping"]) + for mapping in actual["data"] + ) + response = client.delete( - f"/api/bot/{pytest.bot}/slots/mapping_id/{pytest.bot}", + f"/api/bot/{pytest.bot}/slots/mapping_id/non_existent_id", headers={"Authorization": pytest.token_type + " " + pytest.access_token}, ) actual = response.json()
21441-21508
: Consider improving test architectureThe test implementation could benefit from:
- Creating shared fixtures for common setup/teardown operations
- Extracting API calls into helper methods to reduce duplication
- Using a base test class with common utilities
- Adding test data factories for consistent test data creation
This would improve maintainability and reduce code duplication across tests.
Example helper method structure:
class SlotMappingTestBase: def create_slot(self, name: str, slot_type: str) -> dict: response = client.post( f"/api/bot/{pytest.bot}/slots", json={"name": name, "type": slot_type}, headers=self.get_headers(), ) return response.json() def add_slot_mapping(self, slot: str, mapping: dict) -> dict: response = client.post( f"/api/bot/{pytest.bot}/slots/mapping", json={"slot": slot, "mapping": mapping}, headers=self.get_headers(), ) return response.json()
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
kairon/api/app/routers/bot/bot.py
(1 hunks)tests/integration_test/services_test.py
(1 hunks)
🔇 Additional comments (1)
kairon/api/app/routers/bot/bot.py (1)
1387-1387
: 🛠️ Refactor suggestion
Verify the impact of removing user parameter from slot mapping deletion.
The change from delete_slot_mapping
to delete_singular_slot_mapping
and removal of user parameter has the following implications:
- The new function name better reflects its single-record deletion behavior
- The removal of user parameter might affect audit logging capabilities
Let's verify the consistency of this change across the codebase:
Consider adding a comment explaining why user tracking was removed from this operation, or if audit logging is handled within the mongo processor implementation.
✅ Verification successful
Based on the analysis of the shell script results, I can now provide a final response:
Removal of user parameter is consistent with audit logging implementation
The change from delete_slot_mapping
to delete_singular_slot_mapping
is safe because:
- The new function is properly integrated with the audit logging system through the
SlotMapping
model which inherits fromAuditlog
and is decorated with@auditlogger.log
- The user information is automatically captured through the FastAPI security dependency
current_user
in the route handler - The audit logging is handled at the model level through MongoDB signals, not requiring explicit user parameter in method calls
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for other usages of slot mapping deletion functions
# and verify audit logging implementation
# Check for other usages of the old and new functions
echo "Checking function usages:"
rg "delete_slot_mapping|delete_singular_slot_mapping" -A 5
# Check if audit logging is handled within the mongo processor
echo "Checking audit logging implementation:"
ast-grep --pattern 'def delete_singular_slot_mapping($$$)'
Length of output: 8496
Script:
#!/bin/bash
# Let's check the implementation of delete_singular_slot_mapping to understand how it handles audit logging
echo "Checking delete_singular_slot_mapping implementation:"
rg -A 10 "def delete_singular_slot_mapping" kairon/shared/data/processor.py
# Also check if there's any audit logging mechanism in the codebase
echo "Checking audit logging mechanism:"
rg "audit|log.*activity" -A 3
Length of output: 72637
def test_delete_slot_mapping_1(): | ||
response = client.get( | ||
f"/api/bot/{pytest.bot}/slots/mapping", | ||
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | ||
) | ||
actual = response.json() | ||
assert actual["success"] | ||
for slot_mapping in actual["data"]: | ||
if slot_mapping['slot'] == "name_slot": | ||
mapping_id = slot_mapping['mapping'][0]['_id'] | ||
break | ||
assert len(actual["data"]) == 12 | ||
|
||
response = client.delete( | ||
f"/api/bot/{pytest.bot}/slots/mapping_id/{mapping_id}", | ||
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | ||
) | ||
actual = response.json() | ||
assert actual["success"] | ||
assert actual["message"] == "Slot mapping deleted" | ||
assert actual["error_code"] == 0 | ||
assert not actual["data"] | ||
|
||
response = client.get( | ||
f"/api/bot/{pytest.bot}/slots/mapping", | ||
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | ||
) | ||
actual = response.json() | ||
assert actual["success"] | ||
assert actual["error_code"] == 0 | ||
assert len(actual["data"]) == 11 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix brittle test implementation
The test has several issues that could lead to flaky behavior:
- Hardcoded assertions for total mappings (12 -> 11) make the test brittle
- Missing error handling if mapping_id is not found
- Implicit dependency on test data state
-def test_delete_slot_mapping_1():
+def test_delete_slot_mapping_success():
response = client.get(
f"/api/bot/{pytest.bot}/slots/mapping",
headers={"Authorization": pytest.token_type + " " + pytest.access_token},
)
actual = response.json()
assert actual["success"]
+ initial_mapping_count = len(actual["data"])
+ mapping_id = None
for slot_mapping in actual["data"]:
if slot_mapping['slot'] == "name_slot":
mapping_id = slot_mapping['mapping'][0]['_id']
break
- assert len(actual["data"]) == 12
+ assert mapping_id is not None, "Required test mapping 'name_slot' not found"
response = client.delete(
f"/api/bot/{pytest.bot}/slots/mapping_id/{mapping_id}",
headers={"Authorization": pytest.token_type + " " + pytest.access_token},
)
actual = response.json()
assert actual["success"]
assert actual["message"] == "Slot mapping deleted"
assert actual["error_code"] == 0
assert not actual["data"]
response = client.get(
f"/api/bot/{pytest.bot}/slots/mapping",
headers={"Authorization": pytest.token_type + " " + pytest.access_token},
)
actual = response.json()
assert actual["success"]
assert actual["error_code"] == 0
- assert len(actual["data"]) == 11
+ assert len(actual["data"]) == initial_mapping_count - 1
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def test_delete_slot_mapping_1(): | |
response = client.get( | |
f"/api/bot/{pytest.bot}/slots/mapping", | |
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | |
) | |
actual = response.json() | |
assert actual["success"] | |
for slot_mapping in actual["data"]: | |
if slot_mapping['slot'] == "name_slot": | |
mapping_id = slot_mapping['mapping'][0]['_id'] | |
break | |
assert len(actual["data"]) == 12 | |
response = client.delete( | |
f"/api/bot/{pytest.bot}/slots/mapping_id/{mapping_id}", | |
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | |
) | |
actual = response.json() | |
assert actual["success"] | |
assert actual["message"] == "Slot mapping deleted" | |
assert actual["error_code"] == 0 | |
assert not actual["data"] | |
response = client.get( | |
f"/api/bot/{pytest.bot}/slots/mapping", | |
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | |
) | |
actual = response.json() | |
assert actual["success"] | |
assert actual["error_code"] == 0 | |
assert len(actual["data"]) == 11 | |
def test_delete_slot_mapping_success(): | |
response = client.get( | |
f"/api/bot/{pytest.bot}/slots/mapping", | |
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | |
) | |
actual = response.json() | |
assert actual["success"] | |
initial_mapping_count = len(actual["data"]) | |
mapping_id = None | |
for slot_mapping in actual["data"]: | |
if slot_mapping['slot'] == "name_slot": | |
mapping_id = slot_mapping['mapping'][0]['_id'] | |
break | |
assert mapping_id is not None, "Required test mapping 'name_slot' not found" | |
response = client.delete( | |
f"/api/bot/{pytest.bot}/slots/mapping_id/{mapping_id}", | |
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | |
) | |
actual = response.json() | |
assert actual["success"] | |
assert actual["message"] == "Slot mapping deleted" | |
assert actual["error_code"] == 0 | |
assert not actual["data"] | |
response = client.get( | |
f"/api/bot/{pytest.bot}/slots/mapping", | |
headers={"Authorization": pytest.token_type + " " + pytest.access_token}, | |
) | |
actual = response.json() | |
assert actual["success"] | |
assert actual["error_code"] == 0 | |
assert len(actual["data"]) == initial_mapping_count - 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
approved
Fix Delete Slot Mapping api and added related test cases
Summary by CodeRabbit
New Features
Bug Fixes
Tests