import uuid from datetime import datetime from unittest.mock import AsyncMock, patch import pytest from app.api.deps import get_current_user @pytest.fixture def mock_query(): """Return a mock query object.""" q = AsyncMock() q.id = uuid.UUID("22345678-1234-1234-1234-123456789abc") q.user_id = uuid.UUID("12345678-1234-1234-1234-123456789abc") q.keyword = "test keyword" q.target_brand = "TestBrand" q.brand_aliases = [] q.platforms = ["wenxin", "kimi"] q.frequency = "weekly" q.status = "active" q.last_queried_at = None q.next_query_at = datetime.now() q.created_at = datetime.now() q.updated_at = datetime.now() return q @pytest.mark.asyncio async def test_create_query_success( async_client, override_get_current_user, auth_headers, mock_query ): with patch("app.api.queries.create_query", return_value=mock_query): response = await async_client.post( "/api/v1/queries/", headers=auth_headers, json={ "keyword": "test keyword", "target_brand": "TestBrand", "platforms": ["wenxin", "kimi"], "frequency": "weekly", }, ) assert response.status_code == 201 data = response.json() assert data["keyword"] == "test keyword" assert data["target_brand"] == "TestBrand" @pytest.mark.asyncio async def test_create_query_exceeds_limit( async_client, override_get_current_user, auth_headers ): with patch( "app.api.queries.create_query", side_effect=PermissionError("Query limit exceeded"), ): response = await async_client.post( "/api/v1/queries/", headers=auth_headers, json={ "keyword": "test keyword", "target_brand": "TestBrand", "platforms": ["wenxin"], "frequency": "daily", }, ) assert response.status_code == 403 data = response.json() assert "Query limit exceeded" in data["detail"] @pytest.mark.asyncio async def test_list_queries( async_client, override_get_current_user, auth_headers, mock_query ): with patch("app.api.queries.get_queries", return_value=([mock_query], 1)): response = await async_client.get("/api/v1/queries/", headers=auth_headers) assert response.status_code == 200 data = response.json() assert data["total"] == 1 assert len(data["items"]) == 1 assert data["items"][0]["keyword"] == "test keyword" @pytest.mark.asyncio async def test_update_query( async_client, override_get_current_user, auth_headers, mock_query ): updated_query = AsyncMock() updated_query.id = mock_query.id updated_query.keyword = "updated keyword" updated_query.target_brand = "TestBrand" updated_query.brand_aliases = [] updated_query.platforms = ["wenxin"] updated_query.frequency = "daily" updated_query.status = "active" updated_query.last_queried_at = None updated_query.next_query_at = datetime.now() updated_query.created_at = datetime.now() updated_query.updated_at = datetime.now() with patch("app.api.queries.update_query", return_value=updated_query): response = await async_client.put( f"/api/v1/queries/{mock_query.id}", headers=auth_headers, json={"keyword": "updated keyword", "frequency": "daily"}, ) assert response.status_code == 200 data = response.json() assert data["keyword"] == "updated keyword" assert data["frequency"] == "daily" @pytest.mark.asyncio async def test_delete_query( async_client, override_get_current_user, auth_headers, mock_query ): with patch("app.api.queries.delete_query", return_value=True): response = await async_client.delete( f"/api/v1/queries/{mock_query.id}", headers=auth_headers, ) assert response.status_code == 204 @pytest.mark.asyncio async def test_query_not_found( async_client, override_get_current_user, auth_headers ): non_existent_id = uuid.UUID("33333333-3333-3333-3333-333333333333") with patch("app.api.queries.get_query", return_value=None): response = await async_client.get( f"/api/v1/queries/{non_existent_id}", headers=auth_headers, ) assert response.status_code == 404 data = response.json() assert "Query not found" in data["detail"] @pytest.mark.asyncio async def test_query_belongs_to_other_user( async_client, override_get_current_user, auth_headers ): other_user_query_id = uuid.UUID("44444444-4444-4444-4444-444444444444") # Simulate that the query does not belong to the current user by returning None with patch("app.api.queries.get_query", return_value=None): response = await async_client.get( f"/api/v1/queries/{other_user_query_id}", headers=auth_headers, ) assert response.status_code == 404