Exception handling enhancement
This commit is contained in:
@@ -23,10 +23,9 @@ class TestAdminAPI:
|
||||
response = client.get("/api/v1/admin/users", headers=auth_headers)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert (
|
||||
"Access denied" in response.json()["detail"]
|
||||
or "admin" in response.json()["detail"].lower()
|
||||
)
|
||||
data = response.json()
|
||||
assert data["error_code"] == "ADMIN_REQUIRED"
|
||||
assert "Admin privileges required" in data["message"]
|
||||
|
||||
def test_toggle_user_status_admin(self, client, admin_headers, test_user):
|
||||
"""Test admin toggling user status"""
|
||||
@@ -45,18 +44,35 @@ class TestAdminAPI:
|
||||
response = client.put("/api/v1/admin/users/99999/status", headers=admin_headers)
|
||||
|
||||
assert response.status_code == 404
|
||||
assert "User not found" in response.json()["detail"]
|
||||
data = response.json()
|
||||
assert data["error_code"] == "USER_NOT_FOUND"
|
||||
assert "User with ID '99999' not found" in data["message"]
|
||||
|
||||
def test_toggle_user_status_cannot_deactivate_self(
|
||||
def test_toggle_user_status_cannot_modify_self(
|
||||
self, client, admin_headers, test_admin
|
||||
):
|
||||
"""Test that admin cannot deactivate their own account"""
|
||||
"""Test that admin cannot modify their own account"""
|
||||
response = client.put(
|
||||
f"/api/v1/admin/users/{test_admin.id}/status", headers=admin_headers
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert "Cannot deactivate your own account" in response.json()["detail"]
|
||||
assert response.status_code == 400 # Business logic error
|
||||
data = response.json()
|
||||
assert data["error_code"] == "CANNOT_MODIFY_SELF"
|
||||
assert "Cannot perform 'deactivate account' on your own account" in data["message"]
|
||||
|
||||
def test_toggle_user_status_cannot_modify_admin(
|
||||
self, client, admin_headers, test_admin, another_admin
|
||||
):
|
||||
"""Test that admin cannot modify another admin"""
|
||||
response = client.put(
|
||||
f"/api/v1/admin/users/{another_admin.id}/status", headers=admin_headers
|
||||
)
|
||||
|
||||
assert response.status_code == 400 # Business logic error
|
||||
data = response.json()
|
||||
assert data["error_code"] == "USER_STATUS_CHANGE_FAILED"
|
||||
assert "Cannot modify another admin user" in data["message"]
|
||||
|
||||
def test_get_all_shops_admin(self, client, admin_headers, test_shop):
|
||||
"""Test admin getting all shops"""
|
||||
@@ -78,10 +94,8 @@ class TestAdminAPI:
|
||||
response = client.get("/api/v1/admin/shops", headers=auth_headers)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert (
|
||||
"Access denied" in response.json()["detail"]
|
||||
or "admin" in response.json()["detail"].lower()
|
||||
)
|
||||
data = response.json()
|
||||
assert data["error_code"] == "ADMIN_REQUIRED"
|
||||
|
||||
def test_verify_shop_admin(self, client, admin_headers, test_shop):
|
||||
"""Test admin verifying/unverifying shop"""
|
||||
@@ -99,7 +113,9 @@ class TestAdminAPI:
|
||||
response = client.put("/api/v1/admin/shops/99999/verify", headers=admin_headers)
|
||||
|
||||
assert response.status_code == 404
|
||||
assert "Shop not found" in response.json()["detail"]
|
||||
data = response.json()
|
||||
assert data["error_code"] == "SHOP_NOT_FOUND"
|
||||
assert "Shop with ID '99999' not found" in data["message"]
|
||||
|
||||
def test_toggle_shop_status_admin(self, client, admin_headers, test_shop):
|
||||
"""Test admin toggling shop status"""
|
||||
@@ -117,7 +133,8 @@ class TestAdminAPI:
|
||||
response = client.put("/api/v1/admin/shops/99999/status", headers=admin_headers)
|
||||
|
||||
assert response.status_code == 404
|
||||
assert "Shop not found" in response.json()["detail"]
|
||||
data = response.json()
|
||||
assert data["error_code"] == "SHOP_NOT_FOUND"
|
||||
|
||||
def test_get_marketplace_import_jobs_admin(
|
||||
self, client, admin_headers, test_marketplace_job
|
||||
@@ -159,10 +176,32 @@ class TestAdminAPI:
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert (
|
||||
"Access denied" in response.json()["detail"]
|
||||
or "admin" in response.json()["detail"].lower()
|
||||
)
|
||||
data = response.json()
|
||||
assert data["error_code"] == "ADMIN_REQUIRED"
|
||||
|
||||
def test_get_user_statistics(self, client, admin_headers):
|
||||
"""Test admin getting user statistics"""
|
||||
response = client.get("/api/v1/admin/stats/users", headers=admin_headers)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "total_users" in data
|
||||
assert "active_users" in data
|
||||
assert "inactive_users" in data
|
||||
assert "activation_rate" in data
|
||||
assert isinstance(data["total_users"], int)
|
||||
|
||||
def test_get_shop_statistics(self, client, admin_headers):
|
||||
"""Test admin getting shop statistics"""
|
||||
response = client.get("/api/v1/admin/stats/shops", headers=admin_headers)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "total_shops" in data
|
||||
assert "active_shops" in data
|
||||
assert "verified_shops" in data
|
||||
assert "verification_rate" in data
|
||||
assert isinstance(data["total_shops"], int)
|
||||
|
||||
def test_admin_pagination_users(self, client, admin_headers, test_user, test_admin):
|
||||
"""Test user pagination works correctly"""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_authentication_endpoints.py
|
||||
# tests/integration/api/v1/test_authentication_endpoints.py
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
@@ -34,8 +34,11 @@ class TestAuthenticationAPI:
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert "Email already registered" in response.json()["detail"]
|
||||
assert response.status_code == 409 # Changed from 400 to 409
|
||||
data = response.json()
|
||||
assert data["error_code"] == "USER_ALREADY_EXISTS"
|
||||
assert "Email already exists" in data["message"]
|
||||
assert data["field"] == "email"
|
||||
|
||||
def test_register_user_duplicate_username(self, client, test_user):
|
||||
"""Test registration with duplicate username"""
|
||||
@@ -48,8 +51,11 @@ class TestAuthenticationAPI:
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert "Username already taken" in response.json()["detail"]
|
||||
assert response.status_code == 409 # Changed from 400 to 409
|
||||
data = response.json()
|
||||
assert data["error_code"] == "USER_ALREADY_EXISTS"
|
||||
assert "Username already taken" in data["message"]
|
||||
assert data["field"] == "username"
|
||||
|
||||
def test_login_success(self, client, test_user):
|
||||
"""Test successful login"""
|
||||
@@ -73,9 +79,11 @@ class TestAuthenticationAPI:
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
assert "Incorrect username or password" in response.json()["detail"]
|
||||
data = response.json()
|
||||
assert data["error_code"] == "INVALID_CREDENTIALS"
|
||||
assert "Invalid username or password" in data["message"]
|
||||
|
||||
def test_login_nonexistent_user(self, client, db): # Added db fixture
|
||||
def test_login_nonexistent_user(self, client, db):
|
||||
"""Test login with nonexistent user"""
|
||||
response = client.post(
|
||||
"/api/v1/auth/login",
|
||||
@@ -83,6 +91,28 @@ class TestAuthenticationAPI:
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
data = response.json()
|
||||
assert data["error_code"] == "INVALID_CREDENTIALS"
|
||||
|
||||
def test_login_inactive_user(self, client, db, test_user):
|
||||
"""Test login with inactive user account"""
|
||||
# Manually deactivate the user for this test
|
||||
test_user.is_active = False
|
||||
db.commit()
|
||||
|
||||
response = client.post(
|
||||
"/api/v1/auth/login",
|
||||
json={"username": test_user.username, "password": "testpass123"},
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
data = response.json()
|
||||
assert data["error_code"] == "USER_NOT_ACTIVE"
|
||||
assert "User account is not active" in data["message"]
|
||||
|
||||
# Reactivate for other tests
|
||||
test_user.is_active = True
|
||||
db.commit()
|
||||
|
||||
def test_get_current_user_info(self, client, auth_headers, test_user):
|
||||
"""Test getting current user info"""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_export.py
|
||||
# tests/integration/api/v1/test_export.py
|
||||
import csv
|
||||
from io import StringIO
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_filtering.py
|
||||
# tests/integration/api/v1/test_filtering.py
|
||||
import pytest
|
||||
|
||||
from models.database.product import Product
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_marketplace_endpoints.py
|
||||
# tests/integration/api/v1/test_marketplace_endpoints.py
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_product_endpoints.py
|
||||
# tests/integration/api/v1/test_product_endpoints.py
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -82,16 +82,27 @@ class TestProductsAPI:
|
||||
"/api/v1/product", headers=auth_headers, json=product_data
|
||||
)
|
||||
|
||||
# Debug output
|
||||
print(f"Status Code: {response.status_code}")
|
||||
print(f"Response Content: {response.content}")
|
||||
try:
|
||||
print(f"Response JSON: {response.json()}")
|
||||
except:
|
||||
print("Could not parse response as JSON")
|
||||
assert response.status_code == 409 # Changed from 400 to 409
|
||||
data = response.json()
|
||||
assert data["error_code"] == "PRODUCT_ALREADY_EXISTS"
|
||||
assert test_product.product_id in data["message"]
|
||||
|
||||
def test_create_product_invalid_data(self, client, auth_headers):
|
||||
"""Test creating product with invalid data"""
|
||||
product_data = {
|
||||
"product_id": "", # Empty product ID
|
||||
"title": "New Product",
|
||||
"price": "invalid_price",
|
||||
"gtin": "invalid_gtin",
|
||||
}
|
||||
|
||||
response = client.post(
|
||||
"/api/v1/product", headers=auth_headers, json=product_data
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert "already exists" in response.json()["detail"]
|
||||
data = response.json()
|
||||
assert data["error_code"] in ["INVALID_PRODUCT_DATA", "PRODUCT_VALIDATION_FAILED"]
|
||||
|
||||
def test_get_product_by_id(self, client, auth_headers, test_product):
|
||||
"""Test getting specific product"""
|
||||
@@ -109,6 +120,9 @@ class TestProductsAPI:
|
||||
response = client.get("/api/v1/product/NONEXISTENT", headers=auth_headers)
|
||||
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
assert data["error_code"] == "PRODUCT_NOT_FOUND"
|
||||
assert "NONEXISTENT" in data["message"]
|
||||
|
||||
def test_update_product(self, client, auth_headers, test_product):
|
||||
"""Test updating product"""
|
||||
@@ -125,6 +139,34 @@ class TestProductsAPI:
|
||||
assert data["title"] == "Updated Product Title"
|
||||
assert data["price"] == "25.99"
|
||||
|
||||
def test_update_nonexistent_product(self, client, auth_headers):
|
||||
"""Test updating nonexistent product"""
|
||||
update_data = {"title": "Updated Product Title"}
|
||||
|
||||
response = client.put(
|
||||
"/api/v1/product/NONEXISTENT",
|
||||
headers=auth_headers,
|
||||
json=update_data,
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
assert data["error_code"] == "PRODUCT_NOT_FOUND"
|
||||
|
||||
def test_update_product_invalid_data(self, client, auth_headers, test_product):
|
||||
"""Test updating product with invalid data"""
|
||||
update_data = {"title": "", "price": "invalid_price"}
|
||||
|
||||
response = client.put(
|
||||
f"/api/v1/product/{test_product.product_id}",
|
||||
headers=auth_headers,
|
||||
json=update_data,
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
data = response.json()
|
||||
assert data["error_code"] in ["INVALID_PRODUCT_DATA", "PRODUCT_VALIDATION_FAILED"]
|
||||
|
||||
def test_delete_product(self, client, auth_headers, test_product):
|
||||
"""Test deleting product"""
|
||||
response = client.delete(
|
||||
@@ -134,6 +176,14 @@ class TestProductsAPI:
|
||||
assert response.status_code == 200
|
||||
assert "deleted successfully" in response.json()["message"]
|
||||
|
||||
def test_delete_nonexistent_product(self, client, auth_headers):
|
||||
"""Test deleting nonexistent product"""
|
||||
response = client.delete("/api/v1/product/NONEXISTENT", headers=auth_headers)
|
||||
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
assert data["error_code"] == "PRODUCT_NOT_FOUND"
|
||||
|
||||
def test_get_product_without_auth(self, client):
|
||||
"""Test that product endpoints require authentication"""
|
||||
response = client.get("/api/v1/product")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_shop_endpoints.py
|
||||
# tests/integration/api/v1/test_shop_endpoints.py
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_stats_endpoints.py
|
||||
# tests/integration/api/v1/test_stats_endpoints.py
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# tests/test_stock_endpoints.py
|
||||
# tests/integration/api/v1/test_stock_endpoints.py
|
||||
import pytest
|
||||
|
||||
from models.database.stock import Stock
|
||||
|
||||
Reference in New Issue
Block a user