[IMP] payment: test the call to send_payment_request

Adding a test to verify if `send_payment_request` is used once and
only once, and under the right conditions.
In the utils, we change the direct use of `opener` in
portal_transaction for a softer use of `url_open` which manage the
url and then call the `opener` for a same end result.

task-2659750

closes odoo/odoo#84582

X-original-commit: c9371a2ec8dfbd7e55b1b6595e2a76d76ee36e12
Related: odoo/enterprise#24338
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
Signed-off-by: Morgane Demesmaeker <edm@odoo.com>
This commit is contained in:
Demesmaeker
2022-02-15 10:26:12 +00:00
parent dfc82a655b
commit 95a1b387cb
4 changed files with 93 additions and 30 deletions
+21
View File
@@ -99,6 +99,27 @@ class PaymentCommon(PaymentTestUtils):
cls.currency = cls.currency_euro
cls.partner = cls.default_partner
cls.reference = "Test Transaction"
cls.account = cls.company.account_journal_payment_credit_account_id
cls.invoice = cls.env['account.move'].create({
'move_type': 'entry',
'date': '2019-01-01',
'line_ids': [
(0, 0, {
'account_id': cls.account.id,
'currency_id': cls.currency_euro.id,
'debit': 100.0,
'credit': 0.0,
'amount_currency': 200.0,
}),
(0, 0, {
'account_id': cls.account.id,
'currency_id': cls.currency_euro.id,
'debit': 0.0,
'credit': 100.0,
'amount_currency': -200.0,
}),
],
})
#=== Utils ===#
+1 -2
View File
@@ -198,8 +198,7 @@ class PaymentHttpCommon(PaymentTestUtils, HttpCase):
def portal_transaction(self, **route_kwargs):
"""/payment/transaction feedback
:returns: processing values for given route_kwargs
:rtype: dict
:return: The response to the json request
"""
uri = '/payment/transaction'
url = self._build_url(uri)
+46 -28
View File
@@ -1,6 +1,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from freezegun import freeze_time
from unittest.mock import patch
from odoo.tests import tagged
from odoo.tools import mute_logger
@@ -223,7 +224,7 @@ class TestFlows(PaymentCommon, PaymentHttpCommon):
response = self.portal_pay(**route_values)
self.assertTrue(response.url.startswith(self._build_url('/web/login?redirect=')))
# Pay without a partner specified (but loggged) --> pay with the partner of current user.
# Pay without a partner specified (but logged) --> pay with the partner of current user.
self.authenticate(self.portal_user.login, self.portal_user.login)
tx_context = self.get_tx_checkout_context(**route_values)
self.assertEqual(tx_context['partner_id'], self.portal_partner.id)
@@ -237,7 +238,7 @@ class TestFlows(PaymentCommon, PaymentHttpCommon):
response = self.portal_pay(**route_values)
self.assertTrue(response.url.startswith(self._build_url('/web/login?redirect=')))
# Pay without a partner specified (but loggged) --> pay with the partner of current user.
# Pay without a partner specified (but logged) --> pay with the partner of current user.
self.authenticate(self.portal_user.login, self.portal_user.login)
tx_context = self.get_tx_checkout_context(**route_values)
self.assertEqual(tx_context['partner_id'], self.portal_partner.id)
@@ -265,34 +266,12 @@ class TestFlows(PaymentCommon, PaymentHttpCommon):
def test_invoice_payment_flow(self):
"""Test the payment of an invoice through the payment/pay route"""
# Create a dummy invoice
account = self.env['account.account'].search([('company_id', '=', self.env.company.id)], limit=1)
invoice = self.env['account.move'].create({
'move_type': 'entry',
'date': '2019-01-01',
'line_ids': [
(0, 0, {
'account_id': account.id,
'currency_id': self.currency_euro.id,
'debit': 100.0,
'credit': 0.0,
'amount_currency': 200.0,
}),
(0, 0, {
'account_id': account.id,
'currency_id': self.currency_euro.id,
'debit': 0.0,
'credit': 100.0,
'amount_currency': -200.0,
}),
],
})
# Pay for this invoice (no impact even if amounts do not match)
route_values = self._prepare_pay_values()
route_values['invoice_id'] = invoice.id
route_values['invoice_id'] = self.invoice.id
tx_context = self.get_tx_checkout_context(**route_values)
self.assertEqual(tx_context['invoice_id'], invoice.id)
self.assertEqual(tx_context['invoice_id'], self.invoice.id)
# payment/transaction
route_values = {
@@ -318,8 +297,8 @@ class TestFlows(PaymentCommon, PaymentHttpCommon):
# Note: strangely, the check
# self.assertEqual(tx_sudo.invoice_ids, invoice)
# doesn't work, and cache invalidation doesn't work either.
invoice.invalidate_cache(['transaction_ids'])
self.assertEqual(invoice.transaction_ids, tx_sudo)
self.invoice.invalidate_cache(['transaction_ids'])
self.assertEqual(self.invoice.transaction_ids, tx_sudo)
def test_transaction_wrong_flow(self):
transaction_values = self._prepare_pay_values()
@@ -380,3 +359,42 @@ class TestFlows(PaymentCommon, PaymentHttpCommon):
self.assertEqual(manage_context['partner_id'], self.partner.id)
self.assertEqual(manage_context['acquirer_ids'], [acquirer_b.id])
self.assertEqual(manage_context['token_ids'], [])
def test_number_of_payment_request_from_portal(self):
self.authenticate(self.portal_user.login, self.portal_user.login)
self.partner = self.portal_partner
self.user = self.portal_user
self._test_number_of_payment_request_from_portal('direct', 0)
self._test_number_of_payment_request_from_portal('redirect', 0)
self._test_number_of_payment_request_from_portal('token', 1)
@mute_logger('odoo.addons.payment.models.payment_transaction')
def _test_number_of_payment_request_from_portal(self, flow, calls):
""" Test the number of payment requests made from the portal for a given online payment flow
:param str flow: The online payment flow to test ('direct', 'redirect', or 'token')
:param int calls: The expected number of call to `_send_payment_request`
"""
payment_option_id = self.create_token().id if flow == 'token' else self.acquirer.id
data = {
'amount': self.amount,
'currency_id': self.currency.id,
'partner_id': self.partner.id,
'access_token': self._generate_test_access_token(
self.partner.id, self.amount, self.currency.id
),
'payment_option_id': payment_option_id,
'reference_prefix': 'test',
'tokenization_requested': True,
'landing_route': 'Test',
'is_validation': False,
'invoice_id': self.invoice.id,
'flow': flow,
}
with patch(
'odoo.addons.payment.models.payment_transaction.PaymentTransaction'
'._send_payment_request'
) as patched:
self.get_processing_values(**data)
self.assertEqual(patched.call_count, calls)
+25
View File
@@ -1,6 +1,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import tagged
from unittest.mock import patch
from odoo.addons.payment.tests.common import PaymentCommon
@@ -115,3 +116,27 @@ class TestPayments(PaymentCommon):
1,
msg="The refunds count should only consider transactions with operation 'refund'."
)
def test_action_post_call_send_payment_request_only_once(self):
payment_token = self.create_token()
payment_without_token = self.env['account.payment'].create({
'payment_type': 'inbound',
'partner_type': 'customer',
'amount': 2000.0,
'date': '2019-01-01',
'currency_id': self.currency.id,
'partner_id': self.partner.id,
'journal_id': self.acquirer.journal_id.id,
'payment_method_line_id': self.inbound_payment_method_line.id,
})
payment_with_token = payment_without_token.copy()
payment_with_token.payment_token_id = payment_token.id
with patch(
'odoo.addons.payment.models.payment_transaction.PaymentTransaction'
'._send_payment_request'
) as patched:
payment_without_token.action_post()
patched.assert_not_called()
payment_with_token.action_post()
patched.assert_called_once()