import pytest from fastapi import HTTPException from fastapi.testclient import TestClient from datetime import datetime import time from unittest.mock import MagicMock, patch from api_objects import OccupantTokenObject, EmployeeTokenObject, UserType from ApiServices.api_handlers.auth_actions.token import AccessObjectActions from api_services.redis.functions import RedisActions from api_library.date_time_actions.date_functions import system_arrow from api_configs import Auth class MockRequest: def __init__(self, headers=None): self.headers = headers or {} def test_save_object_to_redis_success(): """Test successful token save""" # Create test data access_token = "test_token_123" model_object = OccupantTokenObject( domain="test.com", user_type=UserType.occupant.value, user_uu_id="test-uuid", credentials={}, user_id=1, person_id=1, person_uu_id="person-uuid", request={}, available_occupants={}, ) # Test save result = AccessObjectActions.save_object_to_redis( access_token=access_token, model_object=model_object, expiry_minutes=1 ) assert result is True # Verify saved data saved_data = RedisActions.get_object_via_access_key( MockRequest(headers={Auth.ACCESS_TOKEN_TAG: access_token}) ) assert saved_data.user_uu_id == model_object.user_uu_id assert saved_data.domain == model_object.domain def test_save_object_to_redis_expiry(): """Test token expiration""" # Create test data access_token = "test_token_456" model_object = OccupantTokenObject( domain="test.com", user_type=UserType.occupant.value, user_uu_id="test-uuid-2", credentials={}, user_id=2, person_id=2, person_uu_id="person-uuid-2", request={}, available_occupants={}, ) # Save with 2 second expiry AccessObjectActions.save_object_to_redis( access_token=access_token, model_object=model_object, expiry_minutes=2 / 60, # 2 seconds ) # Verify token exists token1 = RedisActions.get_object_via_access_key( MockRequest(headers={Auth.ACCESS_TOKEN_TAG: access_token}) ) assert token1 is not None # Wait for expiration time.sleep(3) # Verify token is expired with pytest.raises(Exception) as exc_info: RedisActions.get_object_via_access_key( MockRequest(headers={Auth.ACCESS_TOKEN_TAG: access_token}) ) assert any( msg in str(exc_info.value) for msg in ["Token expired", "Invalid credentials"] ) def test_get_object_via_user_uu_id(): """Test retrieving all tokens for a user""" user_id = "test-uuid-3" # Create multiple tokens for same user tokens = [] for i in range(3): access_token = f"test_token_{i}" model_object = OccupantTokenObject( domain=f"test{i}.com", user_type=UserType.occupant.value, user_uu_id=user_id, credentials={}, user_id=3, person_id=3, person_uu_id="person-uuid-3", request={}, available_occupants={}, ) AccessObjectActions.save_object_to_redis(access_token, model_object) tokens.append(access_token) # Get all tokens user_tokens = AccessObjectActions.get_object_via_user_uu_id(user_id) assert len(user_tokens) == 3 # Verify each token for token in tokens: found = False for key, data in user_tokens.items(): if token in key: found = True break assert found, f"Token {token} not found in user tokens" def test_invalid_token_handling(): """Test handling of invalid tokens""" # Test missing headers with pytest.raises(HTTPException) as exc_info: AccessObjectActions.get_token_object(MockRequest()) assert "Unauthorized user" in str(exc_info.value.detail["message"]) # Test missing token with pytest.raises(HTTPException) as exc_info: AccessObjectActions.get_token_object(MockRequest(headers={})) assert "Unauthorized user" in str(exc_info.value.detail["message"]) # Test invalid token with pytest.raises(HTTPException) as exc_info: AccessObjectActions.get_token_object( MockRequest(headers={Auth.ACCESS_TOKEN_TAG: "invalid_token"}) ) assert "Invalid credentials" in str(exc_info.value.detail["message"]) def test_timezone_handling(): """Test timezone awareness in token handling""" access_token = "test_token_tz" model_object = OccupantTokenObject( domain="test.com", user_type=UserType.occupant.value, user_uu_id="test-uuid-tz", credentials={}, user_id=4, person_id=4, person_uu_id="person-uuid-4", request={}, available_occupants={}, ) # Save token AccessObjectActions.save_object_to_redis(access_token, model_object) # Get token and verify timezone data token_data = RedisActions.get_object_via_access_key( MockRequest(headers={Auth.ACCESS_TOKEN_TAG: access_token}) ) # Verify expiry time is in future assert system_arrow.from_timestamp(token_data.expires_at) > system_arrow.now() if __name__ == "__main__": pytest.main([__file__, "-v"])