[IMP] partner_phone_country_validation: add tests
This commit is contained in:
4
partner_phone_country_validation/tests/__init__.py
Normal file
4
partner_phone_country_validation/tests/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# Copyright 2024 Elabore (https://elabore.coop)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import test_partner_phone_country_validation
|
||||
@@ -0,0 +1,149 @@
|
||||
# Copyright 2024 Elabore (https://elabore.coop)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests import Form, TransactionCase
|
||||
|
||||
|
||||
class TestPartnerPhoneCountryValidation(TransactionCase):
|
||||
"""Tests for partner phone country validation module.
|
||||
|
||||
Note on testing @api.onchange methods:
|
||||
--------------------------------------
|
||||
In Odoo, @api.onchange methods are only triggered by the web UI, not by
|
||||
direct field assignment in Python code.
|
||||
|
||||
- `partner.phone = "xxx"` → triggers write() → validates constraints
|
||||
BEFORE any onchange can run → fails if constraint not met
|
||||
|
||||
- `Form(partner)` → simulates web UI behavior → triggers onchange methods
|
||||
when field values change → onchange can set country BEFORE save
|
||||
|
||||
We use Form() for tests that need onchange behavior (auto-detection of
|
||||
country from phone prefix), and direct create/write for constraint tests.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
||||
cls.country_fr = cls.env.ref("base.fr")
|
||||
cls.country_be = cls.env.ref("base.be")
|
||||
# Set company country to France for default formatting
|
||||
cls.env.company.country_id = cls.country_fr
|
||||
|
||||
def test_normalize_00_to_plus(self):
|
||||
"""Test conversion of 00xx format to +xx format."""
|
||||
partner = self.env["res.partner"].create(
|
||||
{"name": "Test Partner", "country_id": self.country_fr.id}
|
||||
)
|
||||
# 00 → + conversion
|
||||
self.assertEqual(
|
||||
partner._normalize_phone_number("0033612345678"), "+33612345678"
|
||||
)
|
||||
# + numbers unchanged
|
||||
self.assertEqual(
|
||||
partner._normalize_phone_number("+33612345678"), "+33612345678"
|
||||
)
|
||||
# National numbers unchanged
|
||||
self.assertEqual(partner._normalize_phone_number("0612345678"), "0612345678")
|
||||
# Edge cases
|
||||
self.assertIsNone(partner._normalize_phone_number(None))
|
||||
self.assertEqual(partner._normalize_phone_number(""), "")
|
||||
|
||||
def test_auto_country_detection(self):
|
||||
"""Test automatic country detection from phone prefix."""
|
||||
partner = self.env["res.partner"].create({"name": "Test Partner"})
|
||||
self.assertFalse(partner.country_id)
|
||||
|
||||
partner._set_country_from_phone_number("+33612345678")
|
||||
self.assertEqual(partner.country_id, self.country_fr)
|
||||
|
||||
def test_auto_country_detection_does_not_override(self):
|
||||
"""Test that auto-detection does not override existing country."""
|
||||
partner = self.env["res.partner"].create(
|
||||
{"name": "Test Partner", "country_id": self.country_be.id}
|
||||
)
|
||||
partner._set_country_from_phone_number("+33612345678")
|
||||
# Country should remain Belgium
|
||||
self.assertEqual(partner.country_id, self.country_be)
|
||||
|
||||
def test_onchange_phone_full_flow(self):
|
||||
"""Test complete onchange flow: 00→+ normalization, country detection, formatting.
|
||||
|
||||
Use Form to simulate UI behavior where onchange triggers before save.
|
||||
"""
|
||||
with Form(self.env["res.partner"]) as partner_form:
|
||||
partner_form.name = "Test Partner"
|
||||
partner_form.phone = "0033612345678"
|
||||
# Onchange should have normalized and detected country
|
||||
self.assertIn("+33", partner_form.phone)
|
||||
self.assertEqual(partner_form.country_id, self.country_fr)
|
||||
|
||||
def test_onchange_mobile_full_flow(self):
|
||||
"""Test complete onchange flow for mobile field."""
|
||||
with Form(self.env["res.partner"]) as partner_form:
|
||||
partner_form.name = "Test Partner"
|
||||
partner_form.mobile = "0032475123456"
|
||||
# Onchange should have normalized and detected country
|
||||
self.assertIn("+32", partner_form.mobile)
|
||||
self.assertEqual(partner_form.country_id, self.country_be)
|
||||
|
||||
def test_onchange_with_existing_country(self):
|
||||
"""Test formatting with existing country uses that country."""
|
||||
with Form(self.env["res.partner"]) as partner_form:
|
||||
partner_form.name = "Test Partner"
|
||||
partner_form.country_id = self.country_fr
|
||||
partner_form.phone = "06 12 34 56 78"
|
||||
# Should be formatted with French prefix
|
||||
self.assertIn("+33", partner_form.phone)
|
||||
|
||||
def test_constraint_country_required_with_phone(self):
|
||||
"""Test that country is required when phone/mobile is set."""
|
||||
with self.assertRaises(ValidationError):
|
||||
self.env["res.partner"].create(
|
||||
{"name": "Test Partner", "phone": "0612345678"}
|
||||
)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
self.env["res.partner"].create(
|
||||
{"name": "Test Partner", "mobile": "0612345678"}
|
||||
)
|
||||
|
||||
def test_constraint_passes_without_phone(self):
|
||||
"""Test that partner without phone doesn't require country."""
|
||||
partner = self.env["res.partner"].create({"name": "Test Partner"})
|
||||
self.assertTrue(partner.id)
|
||||
self.assertFalse(partner.country_id)
|
||||
|
||||
|
||||
class TestGetCountryFromPhoneNumber(TransactionCase):
|
||||
"""Test the utility function for country detection."""
|
||||
|
||||
def test_valid_international_number(self):
|
||||
"""Test detection from valid international number."""
|
||||
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
|
||||
get_country_from_phone_number,
|
||||
)
|
||||
|
||||
self.assertEqual(get_country_from_phone_number("+33612345678"), "FR")
|
||||
|
||||
def test_invalid_number_returns_false(self):
|
||||
"""Test that invalid numbers return False."""
|
||||
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
|
||||
get_country_from_phone_number,
|
||||
)
|
||||
|
||||
self.assertFalse(get_country_from_phone_number("invalid"))
|
||||
self.assertFalse(get_country_from_phone_number("0612345678"))
|
||||
|
||||
def test_national_number_without_prefix(self):
|
||||
"""Test handling of national number without international prefix."""
|
||||
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
|
||||
get_country_from_phone_number,
|
||||
)
|
||||
|
||||
# National numbers without + cannot be reliably detected
|
||||
result = get_country_from_phone_number("0612345678")
|
||||
# phonenumbers cannot determine country without prefix
|
||||
self.assertFalse(result)
|
||||
Reference in New Issue
Block a user