"""Tests for target lists CRUD.""" import pytest from httpx import AsyncClient from sqlalchemy.ext.asyncio import AsyncSession from app.models.team import Team from app.models.user import User from sqlalchemy import select @pytest.fixture async def auth_headers(client: AsyncClient, test_db: AsyncSession, test_user: dict): """Override auth_headers to ensure the test user has a team_id assigned.""" # Fetch the user from DB and assign a team result = await test_db.execute(select(User).where(User.email == test_user["email"])) user = result.scalar_one() # Create a team and assign the user to it team = Team(name="Test Team") test_db.add(team) await test_db.flush() user.team_id = team.id await test_db.commit() # Re-login to get a fresh token login_data = { "email": test_user["email"], "password": test_user["password"], } resp = await client.post("/api/v1/auth/login/json", json=login_data) assert resp.status_code == 200 token_data = resp.json() return {"Authorization": f"Bearer {token_data['access_token']}"} @pytest.mark.asyncio async def test_create_target_list(client: AsyncClient, auth_headers: dict): resp = await client.post( "/api/v1/target-lists/", json={ "name": "RDS Farm A", "description": "Production RDS servers", "targets": [ {"label": "RDS-01", "notes": "192.168.1.10"}, {"label": "RDS-02", "notes": "192.168.1.11"}, ], }, headers=auth_headers, ) assert resp.status_code == 201, resp.text data = resp.json() assert data["name"] == "RDS Farm A" assert len(data["targets"]) == 2 @pytest.mark.asyncio async def test_list_target_lists(client: AsyncClient, auth_headers: dict): resp = await client.get("/api/v1/target-lists/", headers=auth_headers) assert resp.status_code == 200 assert isinstance(resp.json(), list) @pytest.mark.asyncio async def test_get_target_list(client: AsyncClient, auth_headers: dict): create = await client.post( "/api/v1/target-lists/", json={"name": "Get Test", "targets": [{"label": "SRV-01"}]}, headers=auth_headers, ) list_id = create.json()["id"] resp = await client.get(f"/api/v1/target-lists/{list_id}", headers=auth_headers) assert resp.status_code == 200 assert resp.json()["name"] == "Get Test" @pytest.mark.asyncio async def test_update_target_list(client: AsyncClient, auth_headers: dict): create = await client.post( "/api/v1/target-lists/", json={"name": "Old Name", "targets": [{"label": "SRV-01"}]}, headers=auth_headers, ) list_id = create.json()["id"] resp = await client.put( f"/api/v1/target-lists/{list_id}", json={"name": "New Name", "targets": [{"label": "SRV-01"}, {"label": "SRV-02"}]}, headers=auth_headers, ) assert resp.status_code == 200 assert resp.json()["name"] == "New Name" assert len(resp.json()["targets"]) == 2 @pytest.mark.asyncio async def test_delete_target_list(client: AsyncClient, auth_headers: dict): create = await client.post( "/api/v1/target-lists/", json={"name": "To Delete", "targets": [{"label": "X"}]}, headers=auth_headers, ) list_id = create.json()["id"] resp = await client.delete(f"/api/v1/target-lists/{list_id}", headers=auth_headers) assert resp.status_code == 204 get = await client.get(f"/api/v1/target-lists/{list_id}", headers=auth_headers) assert get.status_code == 404 @pytest.mark.asyncio async def test_cannot_access_other_teams_list(client: AsyncClient, auth_headers: dict, test_db): """User from team B cannot access team A's list.""" import uuid from app.models.team import Team from app.models.user import User from app.core.security import get_password_hash # Create team A list using existing auth_headers create = await client.post( "/api/v1/target-lists/", json={"name": "Team A List", "targets": [{"label": "SRV-A"}]}, headers=auth_headers, ) assert create.status_code == 201 list_id = create.json()["id"] # Create a separate team B with its own user team_b = Team(name=f"Team B {uuid.uuid4()}") test_db.add(team_b) await test_db.flush() user_b = User( email=f"userb_{uuid.uuid4()}@test.com", password_hash=get_password_hash("password123"), name="User B", is_active=True, team_id=team_b.id, role="engineer", ) test_db.add(user_b) await test_db.flush() # Get auth token for user B login = await client.post( "/api/v1/auth/login/json", json={"email": user_b.email, "password": "password123"}, ) assert login.status_code == 200 token_b = login.json()["access_token"] headers_b = {"Authorization": f"Bearer {token_b}"} # Team B cannot access Team A's list resp = await client.get(f"/api/v1/target-lists/{list_id}", headers=headers_b) assert resp.status_code == 404