236 lines
12 KiB
Python
236 lines
12 KiB
Python
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
from odoo.exceptions import UserError
|
||
|
from odoo.models import Command
|
||
|
from odoo.tests import tagged
|
||
|
|
||
|
from odoo.addons.payment import utils as payment_utils
|
||
|
from odoo.addons.payment.const import REPORT_REASONS_MAPPING
|
||
|
from odoo.addons.payment.tests.common import PaymentCommon
|
||
|
|
||
|
|
||
|
@tagged('-at_install', 'post_install')
|
||
|
class TestPaymentMethod(PaymentCommon):
|
||
|
|
||
|
def test_unlinking_payment_method_from_provider_state_archives_tokens(self):
|
||
|
""" Test that the active tokens of a payment method created through a provider are archived
|
||
|
when the method is unlinked from the provider. """
|
||
|
token = self._create_token()
|
||
|
self.payment_method.provider_ids = [Command.unlink(self.payment_method.provider_ids[:1].id)]
|
||
|
self.assertFalse(token.active)
|
||
|
|
||
|
def test_payment_method_requires_provider_to_be_activated(self):
|
||
|
""" Test that activating a payment method that is not linked to an enabled provider is
|
||
|
forbidden. """
|
||
|
self.provider.state = 'disabled'
|
||
|
with self.assertRaises(UserError):
|
||
|
self.payment_methods.active = True
|
||
|
|
||
|
def test_payment_method_compatible_when_provider_is_enabled(self):
|
||
|
""" Test that a payment method is available when it is supported by an enabled provider. """
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id
|
||
|
)
|
||
|
self.assertIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_not_compatible_when_provider_is_disabled(self):
|
||
|
""" Test that a payment method is not available when there is no enabled provider that
|
||
|
supports it. """
|
||
|
self.provider.state = 'disabled'
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id
|
||
|
)
|
||
|
self.assertNotIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_non_primary_payment_method_not_compatible(self):
|
||
|
""" Test that a "brand" (i.e., non-primary) payment method is never available. """
|
||
|
brand_payment_method = self.payment_method.copy()
|
||
|
brand_payment_method.primary_payment_method_id = self.payment_method_id # Make it a brand.
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id
|
||
|
)
|
||
|
self.assertNotIn(brand_payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_compatible_with_supported_countries(self):
|
||
|
""" Test that the payment method is compatible with its supported countries. """
|
||
|
belgium = self.env.ref('base.be')
|
||
|
self.payment_method.supported_country_ids = [Command.set([belgium.id])]
|
||
|
self.partner.country_id = belgium
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id
|
||
|
)
|
||
|
self.assertIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_not_compatible_with_unsupported_countries(self):
|
||
|
""" Test that the payment method is not compatible with a country that is not supported. """
|
||
|
belgium = self.env.ref('base.be')
|
||
|
self.payment_method.supported_country_ids = [Command.set([belgium.id])]
|
||
|
france = self.env.ref('base.fr')
|
||
|
self.partner.country_id = france
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id
|
||
|
)
|
||
|
self.assertNotIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_compatible_when_no_supported_countries_set(self):
|
||
|
""" Test that the payment method is always compatible when no supported countries are
|
||
|
set. """
|
||
|
self.payment_method.supported_country_ids = [Command.clear()]
|
||
|
belgium = self.env.ref('base.be')
|
||
|
self.partner.country_id = belgium
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id
|
||
|
)
|
||
|
self.assertIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_compatible_with_supported_currencies(self):
|
||
|
""" Test that the payment method is compatible with its supported currencies. """
|
||
|
self.payment_method.supported_currency_ids = [Command.set([self.currency_euro.id])]
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id, currency_id=self.currency_euro.id
|
||
|
)
|
||
|
self.assertIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_not_compatible_with_unsupported_currencies(self):
|
||
|
""" Test that the payment method is not compatible with a currency that is not
|
||
|
supported. """
|
||
|
self.payment_method.supported_currency_ids = [Command.set([self.currency_euro.id])]
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id, currency_id=self.currency_usd.id
|
||
|
)
|
||
|
self.assertNotIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_compatible_when_no_supported_currencies_set(self):
|
||
|
""" Test that the payment method is always compatible when no supported currencies are
|
||
|
set. """
|
||
|
self.payment_method.supported_currency_ids = [Command.clear()]
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id, currency_id=self.currency_euro.id
|
||
|
)
|
||
|
self.assertIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_compatible_when_tokenization_forced(self):
|
||
|
""" Test that the payment method is compatible when it supports tokenization while it is
|
||
|
forced by the calling module. """
|
||
|
self.payment_method.support_tokenization = True
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id, force_tokenization=True
|
||
|
)
|
||
|
self.assertIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_not_compatible_when_tokenization_forced(self):
|
||
|
""" Test that the payment method is not compatible when it does not support tokenization
|
||
|
while it is forced by the calling module. """
|
||
|
self.payment_method.support_tokenization = False
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id, force_tokenization=True
|
||
|
)
|
||
|
self.assertNotIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_compatible_with_express_checkout(self):
|
||
|
""" Test that the payment method is compatible when it supports express checkout while it is
|
||
|
an express checkout flow. """
|
||
|
self.payment_method.support_express_checkout = True
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id, is_express_checkout=True
|
||
|
)
|
||
|
self.assertIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_payment_method_not_compatible_with_express_checkout(self):
|
||
|
""" Test that the payment method is not compatible when it does not support express checkout
|
||
|
while it is an express checkout flow. """
|
||
|
self.payment_method.support_express_checkout = False
|
||
|
compatible_payment_methods = self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids, self.partner.id, is_express_checkout=True
|
||
|
)
|
||
|
self.assertNotIn(self.payment_method, compatible_payment_methods)
|
||
|
|
||
|
def test_availability_report_covers_all_reasons(self):
|
||
|
""" Test that every possible unavailability reason is correctly reported. """
|
||
|
# Disable all payment methods.
|
||
|
pms = self.env['payment.method'].search([('is_primary', '=', True)])
|
||
|
pms.active = False
|
||
|
|
||
|
# Prepare a base payment method.
|
||
|
self.payment_method.write({
|
||
|
'active': True,
|
||
|
'support_express_checkout': True,
|
||
|
'support_tokenization': True,
|
||
|
})
|
||
|
|
||
|
# Prepare the report with a provider to allow checking provider availability.
|
||
|
report = {}
|
||
|
payment_utils.add_to_report(report, self.provider)
|
||
|
|
||
|
# Prepare a payment method with an unavailable provider.
|
||
|
unavailable_provider = self.provider.copy()
|
||
|
payment_utils.add_to_report(report, unavailable_provider, available=False, reason="test")
|
||
|
no_provider_pm = self.payment_method.copy()
|
||
|
no_provider_pm.provider_ids = [Command.set([unavailable_provider.id])]
|
||
|
unavailable_provider.payment_method_ids = [Command.set([no_provider_pm.id])]
|
||
|
|
||
|
# Prepare a payment method with an incompatible country.
|
||
|
invalid_country_pm = self.payment_method.copy()
|
||
|
belgium = self.env.ref('base.be')
|
||
|
invalid_country_pm.supported_country_ids = [Command.set([belgium.id])]
|
||
|
france = self.env.ref('base.fr')
|
||
|
self.partner.country_id = france
|
||
|
|
||
|
# Prepare a payment method with an incompatible currency.
|
||
|
invalid_currency_pm = self.payment_method.copy()
|
||
|
invalid_currency_pm.supported_currency_ids = [Command.set([self.currency_euro.id])]
|
||
|
|
||
|
# Prepare a payment method without support for tokenization.
|
||
|
no_tokenization_pm = self.payment_method.copy()
|
||
|
no_tokenization_pm.support_tokenization = False
|
||
|
|
||
|
# Prepare a payment method without support for express checkout.
|
||
|
no_express_checkout_pm = self.payment_method.copy()
|
||
|
no_express_checkout_pm.support_express_checkout = False
|
||
|
|
||
|
# Get compatible payment methods to generate their availability report.
|
||
|
self.env['payment.method']._get_compatible_payment_methods(
|
||
|
self.provider.ids,
|
||
|
self.partner.id,
|
||
|
currency_id=self.currency_usd.id,
|
||
|
force_tokenization=True,
|
||
|
is_express_checkout=True,
|
||
|
report=report,
|
||
|
)
|
||
|
|
||
|
# Compare the generated payment methods report with the expected one.
|
||
|
expected_pms_report = {
|
||
|
self.payment_method: {
|
||
|
'available': True,
|
||
|
'reason': '',
|
||
|
'supported_providers': [(self.provider, True)],
|
||
|
},
|
||
|
no_provider_pm: {
|
||
|
'available': False,
|
||
|
'reason': REPORT_REASONS_MAPPING['provider_not_available'],
|
||
|
'supported_providers': [(unavailable_provider, False)],
|
||
|
},
|
||
|
invalid_country_pm: {
|
||
|
'available': False,
|
||
|
'reason': REPORT_REASONS_MAPPING['incompatible_country'],
|
||
|
'supported_providers': [(self.provider, True)],
|
||
|
},
|
||
|
invalid_currency_pm: {
|
||
|
'available': False,
|
||
|
'reason': REPORT_REASONS_MAPPING['incompatible_currency'],
|
||
|
'supported_providers': [(self.provider, True)],
|
||
|
},
|
||
|
no_tokenization_pm: {
|
||
|
'available': False,
|
||
|
'reason': REPORT_REASONS_MAPPING['tokenization_not_supported'],
|
||
|
'supported_providers': [(self.provider, True)],
|
||
|
},
|
||
|
no_express_checkout_pm: {
|
||
|
'available': False,
|
||
|
'reason': REPORT_REASONS_MAPPING['express_checkout_not_supported'],
|
||
|
'supported_providers': [(self.provider, True)],
|
||
|
},
|
||
|
}
|
||
|
self.maxDiff = None
|
||
|
self.assertDictEqual(report['payment_methods'], expected_pms_report)
|