"""Tests for audit log API.""" from datetime import datetime, timedelta import pytest from fastapi.testclient import TestClient from sqlalchemy.orm import Session from app.models.user import User from app.services.audit_service import log_action def test_get_audit_logs(client: TestClient, admin_token: str, db_session: Session, test_admin: User) -> None: """Test getting audit logs.""" # Create some audit logs log_action(db_session, "booking_approved", test_admin.id, "booking", 1) log_action(db_session, "space_created", test_admin.id, "space", 2) response = client.get( "/api/admin/audit-log", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 200 data = response.json() assert len(data) >= 2 assert data[0]["user_name"] == test_admin.full_name assert data[0]["user_email"] == test_admin.email def test_filter_audit_logs_by_action( client: TestClient, admin_token: str, db_session: Session, test_admin: User ) -> None: """Test filtering by action.""" log_action(db_session, "booking_approved", test_admin.id, "booking", 1) log_action(db_session, "space_created", test_admin.id, "space", 2) response = client.get( "/api/admin/audit-log?action=booking_approved", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 200 data = response.json() assert all(log["action"] == "booking_approved" for log in data) def test_filter_audit_logs_by_date( client: TestClient, admin_token: str, db_session: Session, test_admin: User ) -> None: """Test filtering by date range.""" log_action(db_session, "booking_approved", test_admin.id, "booking", 1) # Test with date filters yesterday = (datetime.utcnow() - timedelta(days=1)).isoformat() tomorrow = (datetime.utcnow() + timedelta(days=1)).isoformat() response = client.get( f"/api/admin/audit-log?start_date={yesterday}&end_date={tomorrow}", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 200 data = response.json() assert len(data) >= 1 def test_audit_logs_require_admin(client: TestClient, user_token: str) -> None: """Test that regular users cannot access audit logs.""" response = client.get( "/api/admin/audit-log", headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == 403 def test_pagination_audit_logs( client: TestClient, admin_token: str, db_session: Session, test_admin: User ) -> None: """Test pagination.""" # Create multiple logs for i in range(10): log_action(db_session, f"action_{i}", test_admin.id, "booking", i) # Get page 1 response = client.get( "/api/admin/audit-log?page=1&limit=5", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 200 assert len(response.json()) == 5 # Get page 2 response = client.get( "/api/admin/audit-log?page=2&limit=5", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 200 assert len(response.json()) == 5 def test_audit_logs_with_details( client: TestClient, admin_token: str, db_session: Session, test_admin: User ) -> None: """Test audit logs with additional details.""" log_action( db_session, "booking_rejected", test_admin.id, "booking", 1, details={"reason": "Room not available", "original_status": "pending"} ) response = client.get( "/api/admin/audit-log", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 200 data = response.json() assert len(data) >= 1 log_entry = next((log for log in data if log["action"] == "booking_rejected"), None) assert log_entry is not None assert log_entry["details"]["reason"] == "Room not available" assert log_entry["details"]["original_status"] == "pending" def test_audit_logs_ordered_by_date_desc( client: TestClient, admin_token: str, db_session: Session, test_admin: User ) -> None: """Test that audit logs are ordered by date descending (newest first).""" # Create logs with different actions to identify them log_action(db_session, "first_action", test_admin.id, "booking", 1) log_action(db_session, "second_action", test_admin.id, "booking", 2) log_action(db_session, "third_action", test_admin.id, "booking", 3) response = client.get( "/api/admin/audit-log", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 200 data = response.json() assert len(data) >= 3 # Most recent should be first assert data[0]["action"] == "third_action" assert data[1]["action"] == "second_action" assert data[2]["action"] == "first_action"