"""Tests pour les outils de gestion des timesheets."""
from __future__ import annotations
import pytest
from unittest.mock import patch, MagicMock
from datetime import date
# Mock les variables d'environnement avant l'import
with patch.dict("os.environ", {
"ODOO_URL": "https://test.odoo.com",
"ODOO_DB": "test_db",
"ODOO_USERNAME": "test_user",
"ODOO_API_KEY": "test_key",
}):
with patch("server.OdooClient"):
from server import (
list_projects,
list_tasks,
list_timesheets,
create_timesheet,
update_timesheet,
delete_timesheet,
)
class TestListProjects:
"""Tests pour list_projects."""
def test_list_projects_success(self, mock_odoo_client, sample_projects):
"""Test listage des projets avec succès."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.search_read.return_value = sample_projects
result = list_projects()
assert "# Projets disponibles" in result
assert "Projet Alpha" in result
assert "Projet Beta" in result
assert "Client A" in result
assert "Client B" in result
# Projet sans client
assert "N/A" in result
def test_list_projects_empty(self, mock_odoo_client):
"""Test listage sans projets."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.search_read.return_value = []
result = list_projects()
assert "Aucun projet trouvé" in result
def test_list_projects_with_pagination(self, mock_odoo_client, sample_projects):
"""Test listage avec pagination."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.search_read.return_value = sample_projects
result = list_projects(limit=10, offset=5)
assert "Page à partir de l'entrée 6" in result
class TestListTasks:
"""Tests pour list_tasks."""
def test_list_tasks_success(self, mock_odoo_client, sample_tasks):
"""Test listage des tâches avec succès."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.search_read.return_value = sample_tasks
result = list_tasks()
assert "# Tâches disponibles" in result
assert "Tâche 1" in result
assert "Tâche 2" in result
assert "À faire" in result
assert "En cours" in result
def test_list_tasks_with_project_filter(self, mock_odoo_client, sample_tasks):
"""Test listage avec filtre par projet."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.search_read.return_value = sample_tasks
mock_odoo_client.exists.return_value = True
result = list_tasks(project_id=1)
assert "Tâche 1" in result
mock_odoo_client.exists.assert_called_once_with("project.project", 1)
def test_list_tasks_project_not_found(self, mock_odoo_client):
"""Test avec projet inexistant."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = False
result = list_tasks(project_id=999)
assert "Erreur" in result
assert "non trouvé" in result
class TestListTimesheets:
"""Tests pour list_timesheets."""
def test_list_timesheets_success(self, mock_odoo_client, sample_timesheets):
"""Test listage des timesheets avec succès."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.search_read.return_value = sample_timesheets
result = list_timesheets()
assert "# Entrées de timesheet" in result
assert "Développement feature X" in result
assert "4.0h" in result or "4h" in result
assert "Total affiché: 6.0h" in result
def test_list_timesheets_with_date_filter(self, mock_odoo_client, sample_timesheets):
"""Test listage avec filtre de date."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.search_read.return_value = sample_timesheets
result = list_timesheets(date_from="2024-01-01", date_to="2024-01-31")
assert "# Entrées de timesheet" in result
def test_list_timesheets_invalid_date(self, mock_odoo_client):
"""Test avec date invalide."""
with patch("server.odoo", mock_odoo_client):
result = list_timesheets(date_from="invalid-date")
assert "Erreur" in result
assert "Format de date invalide" in result
class TestCreateTimesheet:
"""Tests pour create_timesheet."""
def test_create_timesheet_success(self, mock_odoo_client):
"""Test création de timesheet avec succès."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = True
mock_odoo_client.create.return_value = 42
result = create_timesheet(
project_id=1,
hours=4.0,
description="Test développement",
)
assert "créé avec succès" in result
assert "42" in result
def test_create_timesheet_with_task(self, mock_odoo_client):
"""Test création avec tâche."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = True
mock_odoo_client.create.return_value = 43
result = create_timesheet(
project_id=1,
hours=2.0,
description="Test",
task_id=5,
)
assert "créé avec succès" in result
def test_create_timesheet_invalid_hours(self, mock_odoo_client):
"""Test avec heures invalides."""
with patch("server.odoo", mock_odoo_client):
result = create_timesheet(
project_id=1,
hours=-1.0,
description="Test",
)
assert "Erreur" in result
assert "positif" in result
def test_create_timesheet_empty_description(self, mock_odoo_client):
"""Test avec description vide."""
with patch("server.odoo", mock_odoo_client):
result = create_timesheet(
project_id=1,
hours=2.0,
description=" ",
)
assert "Erreur" in result
assert "vide" in result
def test_create_timesheet_project_not_found(self, mock_odoo_client):
"""Test avec projet inexistant."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = False
result = create_timesheet(
project_id=999,
hours=2.0,
description="Test",
)
assert "Erreur" in result
assert "non trouvé" in result
class TestUpdateTimesheet:
"""Tests pour update_timesheet."""
def test_update_timesheet_success(self, mock_odoo_client):
"""Test modification avec succès."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = True
result = update_timesheet(
timesheet_id=1,
hours=5.0,
description="Nouvelle description",
)
assert "modifié avec succès" in result
def test_update_timesheet_not_found(self, mock_odoo_client):
"""Test avec timesheet inexistant."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = False
result = update_timesheet(timesheet_id=999, hours=2.0)
assert "Erreur" in result
assert "non trouvé" in result
def test_update_timesheet_no_changes(self, mock_odoo_client):
"""Test sans modifications."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = True
result = update_timesheet(timesheet_id=1)
assert "Aucune modification" in result
class TestDeleteTimesheet:
"""Tests pour delete_timesheet."""
def test_delete_timesheet_success(self, mock_odoo_client):
"""Test suppression avec succès."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = True
result = delete_timesheet(timesheet_id=1)
assert "supprimé avec succès" in result
mock_odoo_client.unlink.assert_called_once()
def test_delete_timesheet_not_found(self, mock_odoo_client):
"""Test avec timesheet inexistant."""
with patch("server.odoo", mock_odoo_client):
mock_odoo_client.exists.return_value = False
result = delete_timesheet(timesheet_id=999)
assert "Erreur" in result
assert "non trouvé" in result