"""Tests pour le client Odoo."""
from __future__ import annotations
import pytest
from unittest.mock import patch, MagicMock
import xmlrpc.client
# 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",
}):
from server import (
OdooClient,
OdooError,
OdooConnectionError,
OdooAuthenticationError,
_get_many2one_name,
_format_pagination,
)
class TestOdooClient:
"""Tests pour la classe OdooClient."""
def test_init(self):
"""Test initialisation du client."""
with patch("server.ODOO_URL", "https://test.odoo.com"), \
patch("server.ODOO_DB", "test_db"), \
patch("server.ODOO_USERNAME", "test_user"), \
patch("server.ODOO_API_KEY", "test_key"):
client = OdooClient()
assert client.url == "https://test.odoo.com"
assert client.db == "test_db"
assert client.username == "test_user"
assert client._uid is None
def test_uid_authentication_success(self):
"""Test authentification réussie."""
with patch("server.ODOO_URL", "https://test.odoo.com"), \
patch("server.ODOO_DB", "test_db"), \
patch("server.ODOO_USERNAME", "test_user"), \
patch("server.ODOO_API_KEY", "test_key"):
client = OdooClient()
mock_common = MagicMock()
mock_common.authenticate.return_value = 42
with patch.object(client, "_common", mock_common):
uid = client.uid
assert uid == 42
mock_common.authenticate.assert_called_once()
def test_uid_authentication_failure(self):
"""Test échec d'authentification."""
with patch("server.ODOO_URL", "https://test.odoo.com"), \
patch("server.ODOO_DB", "test_db"), \
patch("server.ODOO_USERNAME", "test_user"), \
patch("server.ODOO_API_KEY", "test_key"):
client = OdooClient()
mock_common = MagicMock()
mock_common.authenticate.return_value = False
with patch.object(client, "_common", mock_common):
with pytest.raises(OdooAuthenticationError):
_ = client.uid
def test_exists_true(self):
"""Test exists retourne True."""
with patch("server.ODOO_URL", "https://test.odoo.com"), \
patch("server.ODOO_DB", "test_db"), \
patch("server.ODOO_USERNAME", "test_user"), \
patch("server.ODOO_API_KEY", "test_key"):
client = OdooClient()
# Mock via le models proxy car __slots__ empêche le patch direct
mock_models = MagicMock()
mock_models.execute_kw.return_value = 1
client._models = mock_models
client._uid = 1
assert client.exists("res.partner", 1) is True
def test_exists_false(self):
"""Test exists retourne False."""
with patch("server.ODOO_URL", "https://test.odoo.com"), \
patch("server.ODOO_DB", "test_db"), \
patch("server.ODOO_USERNAME", "test_user"), \
patch("server.ODOO_API_KEY", "test_key"):
client = OdooClient()
mock_models = MagicMock()
mock_models.execute_kw.return_value = 0
client._models = mock_models
client._uid = 1
assert client.exists("res.partner", 999) is False
class TestHelpers:
"""Tests pour les fonctions helper."""
def test_get_many2one_name_with_value(self):
"""Test extraction du nom d'un Many2one."""
assert _get_many2one_name([1, "Test Name"]) == "Test Name"
assert _get_many2one_name([42, "Autre"]) == "Autre"
def test_get_many2one_name_false(self):
"""Test avec valeur False."""
assert _get_many2one_name(False) == "N/A"
assert _get_many2one_name(False, "Default") == "Default"
def test_get_many2one_name_none(self):
"""Test avec valeur None."""
assert _get_many2one_name(None) == "N/A"
def test_get_many2one_name_empty_list(self):
"""Test avec liste vide."""
assert _get_many2one_name([]) == "N/A"
def test_format_pagination_no_more(self):
"""Test pagination sans plus de résultats."""
result = _format_pagination(5, 10, 0, "éléments")
assert "5 éléments" in result
assert "offset=" not in result
def test_format_pagination_with_more(self):
"""Test pagination avec plus de résultats."""
result = _format_pagination(10, 10, 0, "éléments")
assert "10 éléments" in result
assert "offset=10" in result
def test_format_pagination_with_offset(self):
"""Test pagination avec offset."""
result = _format_pagination(10, 10, 20, "items")
assert "offset=30" in result
class TestExceptions:
"""Tests pour les exceptions personnalisées."""
def test_odoo_error(self):
"""Test OdooError."""
error = OdooError("Test error")
assert str(error) == "Test error"
assert isinstance(error, Exception)
def test_odoo_connection_error(self):
"""Test OdooConnectionError."""
error = OdooConnectionError("Connection failed")
assert str(error) == "Connection failed"
assert isinstance(error, OdooError)
def test_odoo_authentication_error(self):
"""Test OdooAuthenticationError."""
error = OdooAuthenticationError("Auth failed")
assert str(error) == "Auth failed"
assert isinstance(error, OdooError)