""" Tests pour les routes de gestion des groupes Ansible. Couvre: - Liste des groupes - Détails d'un groupe - Création de groupe - Mise à jour de groupe - Suppression de groupe """ import pytest from unittest.mock import patch, MagicMock from httpx import AsyncClient pytestmark = pytest.mark.unit class TestGetGroups: """Tests pour GET /api/groups.""" async def test_list_groups(self, client: AsyncClient): """Liste tous les groupes.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.get_groups.return_value = ["env_prod", "env_dev", "role_web"] mock_ansible.get_env_groups.return_value = ["env_prod", "env_dev"] mock_ansible.get_role_groups.return_value = ["role_web"] mock_ansible.get_group_hosts.return_value = ["host1", "host2"] response = await client.get("/api/groups") assert response.status_code == 200 data = response.json() assert "groups" in data assert "env_count" in data assert "role_count" in data assert data["env_count"] == 2 assert data["role_count"] == 1 async def test_list_groups_empty(self, client: AsyncClient): """Liste vide quand pas de groupes.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.get_groups.return_value = [] mock_ansible.get_env_groups.return_value = [] mock_ansible.get_role_groups.return_value = [] response = await client.get("/api/groups") assert response.status_code == 200 data = response.json() assert data["groups"] == [] class TestGetGroup: """Tests pour GET /api/groups/{group_name}.""" async def test_get_group_success(self, client: AsyncClient): """Récupère les détails d'un groupe.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = True mock_ansible.get_env_groups.return_value = ["env_prod"] mock_ansible.get_role_groups.return_value = [] mock_ansible.get_group_hosts.return_value = ["server1", "server2"] response = await client.get("/api/groups/env_prod") assert response.status_code == 200 data = response.json() assert data["name"] == "env_prod" assert data["type"] == "env" assert data["hosts_count"] == 2 async def test_get_group_not_found(self, client: AsyncClient): """Erreur si groupe non trouvé.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = False response = await client.get("/api/groups/nonexistent") assert response.status_code == 404 class TestCreateGroup: """Tests pour POST /api/groups.""" async def test_create_group_success(self, client: AsyncClient): """Création de groupe réussie.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = False mock_ansible.add_group = MagicMock() response = await client.post( "/api/groups", json={"name": "env_staging", "type": "env"} ) assert response.status_code == 200 data = response.json() assert "créé" in data["message"] mock_ansible.add_group.assert_called_once_with("env_staging", "env") async def test_create_group_invalid_prefix(self, client: AsyncClient): """Erreur si préfixe invalide.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = False response = await client.post( "/api/groups", json={"name": "staging", "type": "env"} # Missing env_ prefix ) assert response.status_code == 400 assert "doit commencer par" in response.json()["detail"] async def test_create_group_already_exists(self, client: AsyncClient): """Erreur si groupe existe déjà.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = True response = await client.post( "/api/groups", json={"name": "env_prod", "type": "env"} ) assert response.status_code == 400 assert "existe déjà" in response.json()["detail"] class TestUpdateGroup: """Tests pour PUT /api/groups/{group_name}.""" async def test_update_group_not_found(self, client: AsyncClient): """Erreur si groupe non trouvé.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = False response = await client.put( "/api/groups/nonexistent", json={"new_name": "env_new"} ) assert response.status_code == 404 class TestDeleteGroup: """Tests pour DELETE /api/groups/{group_name}.""" async def test_delete_group_not_found(self, client: AsyncClient): """Erreur si groupe non trouvé.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = False response = await client.delete("/api/groups/nonexistent") assert response.status_code == 404 async def test_delete_group_success(self, client: AsyncClient): """Suppression de groupe réussie.""" with patch("app.routes.groups.ansible_service") as mock_ansible: mock_ansible.group_exists.return_value = True mock_ansible.delete_group = MagicMock() response = await client.delete("/api/groups/env_old") assert response.status_code == 200 mock_ansible.delete_group.assert_called_once()