reaching 100% test coverage for the middleware unit tests
This commit is contained in:
@@ -16,6 +16,7 @@ import pytest
|
||||
from unittest.mock import Mock, MagicMock, patch
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from jose import jwt
|
||||
from fastapi import HTTPException
|
||||
|
||||
from middleware.auth import AuthManager
|
||||
from app.exceptions import (
|
||||
@@ -350,6 +351,26 @@ class TestJWTTokenVerification:
|
||||
with pytest.raises(InvalidTokenException):
|
||||
auth_manager.verify_token(token)
|
||||
|
||||
def test_verify_token_additional_expiration_check(self):
|
||||
"""Test the additional expiration check after jwt.decode."""
|
||||
auth_manager = AuthManager()
|
||||
|
||||
# Create a token with expiration in the past
|
||||
past_time = datetime.now(timezone.utc) - timedelta(minutes=1)
|
||||
payload = {
|
||||
"sub": "1",
|
||||
"username": "testuser",
|
||||
"exp": past_time.timestamp()
|
||||
}
|
||||
token = jwt.encode(payload, auth_manager.secret_key, algorithm=auth_manager.algorithm)
|
||||
|
||||
# Mock jwt.decode to bypass its expiration check and test line 205
|
||||
with patch('middleware.auth.jwt.decode') as mock_decode:
|
||||
mock_decode.return_value = payload
|
||||
|
||||
with pytest.raises(TokenExpiredException):
|
||||
auth_manager.verify_token(token)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.auth
|
||||
@@ -661,3 +682,62 @@ class TestEdgeCases:
|
||||
# Result depends on how the filter is implemented
|
||||
# This test documents the expected behavior
|
||||
assert result is None or result is mock_user
|
||||
|
||||
def test_verify_token_unexpected_exception(self):
|
||||
"""Test generic exception handler in verify_token."""
|
||||
auth_manager = AuthManager()
|
||||
|
||||
# Create a valid token with a mock user
|
||||
mock_user = Mock(spec=User)
|
||||
mock_user.id = 1
|
||||
mock_user.username = "test"
|
||||
mock_user.email = "test@example.com"
|
||||
mock_user.role = "user"
|
||||
|
||||
token_data = auth_manager.create_access_token(mock_user)
|
||||
token = token_data["access_token"]
|
||||
|
||||
# Mock jose.jwt.decode to raise an unexpected exception
|
||||
with patch('middleware.auth.jwt.decode', side_effect=RuntimeError("Unexpected error")):
|
||||
with pytest.raises(InvalidTokenException) as exc_info:
|
||||
auth_manager.verify_token(token)
|
||||
|
||||
# The message should be "Authentication failed" from the generic except handler
|
||||
assert "Authentication failed" in str(exc_info.value.message)
|
||||
|
||||
def test_require_role_decorator_wrapper_functionality(self):
|
||||
"""Test the require_role decorator wrapper execution."""
|
||||
auth_manager = AuthManager()
|
||||
|
||||
# Create a test function decorated with require_role
|
||||
@auth_manager.require_role("admin")
|
||||
def test_function(current_user, additional_arg=None):
|
||||
return {"user": current_user.username, "arg": additional_arg}
|
||||
|
||||
# Test successful case - user has required role
|
||||
admin_user = Mock(spec=User)
|
||||
admin_user.role = "admin"
|
||||
admin_user.username = "admin_user"
|
||||
|
||||
result = test_function(admin_user, additional_arg="test_value")
|
||||
|
||||
assert result["user"] == "admin_user"
|
||||
assert result["arg"] == "test_value"
|
||||
|
||||
def test_require_role_decorator_blocks_wrong_role(self):
|
||||
"""Test that require_role decorator blocks users with wrong role."""
|
||||
auth_manager = AuthManager()
|
||||
|
||||
@auth_manager.require_role("admin")
|
||||
def admin_only_function(current_user):
|
||||
return {"status": "success"}
|
||||
|
||||
# Test with user that has wrong role
|
||||
regular_user = Mock(spec=User)
|
||||
regular_user.role = "user"
|
||||
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
admin_only_function(regular_user)
|
||||
|
||||
assert exc_info.value.status_code == 403
|
||||
assert "Required role 'admin' not found" in exc_info.value.detail
|
||||
|
||||
@@ -435,6 +435,10 @@ class TestVendorContextManager:
|
||||
"/image.jpg",
|
||||
"/style.css",
|
||||
"/app.webmanifest",
|
||||
"/static/", # Path starting with /static/ but no extension
|
||||
"/media/uploads", # Path starting with /media/ but no extension
|
||||
"/subfolder/favicon.ico", # favicon.ico in subfolder
|
||||
"/favicon.ico.bak", # Contains favicon.ico but doesn't end with static extension (hits line 226)
|
||||
])
|
||||
def test_is_static_file_request(self, path):
|
||||
"""Test static file detection for various paths and extensions."""
|
||||
@@ -719,3 +723,23 @@ class TestEdgeCases:
|
||||
# Should detect 'shop' as subdomain since it's the first part
|
||||
assert context["detection_method"] == "subdomain"
|
||||
assert context["subdomain"] == "shop"
|
||||
|
||||
def test_get_vendor_logs_warning_when_not_found_subdomain(self):
|
||||
"""Test that warning is logged when vendor is not found by subdomain."""
|
||||
mock_db = Mock()
|
||||
# Mock the complete query chain properly - need to mock filter twice and then first
|
||||
mock_query = mock_db.query.return_value
|
||||
mock_filter1 = mock_query.filter.return_value
|
||||
mock_filter2 = mock_filter1.filter.return_value
|
||||
mock_filter2.first.return_value = None
|
||||
|
||||
context = {"subdomain": "nonexistent", "detection_method": "subdomain"}
|
||||
|
||||
with patch('middleware.vendor_context.logger') as mock_logger:
|
||||
vendor = VendorContextManager.get_vendor_from_context(mock_db, context)
|
||||
|
||||
assert vendor is None
|
||||
# Verify warning was logged
|
||||
mock_logger.warning.assert_called()
|
||||
warning_message = str(mock_logger.warning.call_args)
|
||||
assert "No active vendor found for subdomain" in warning_message and "nonexistent" in warning_message
|
||||
|
||||
Reference in New Issue
Block a user