Before this commit the neutralize system introduced in v16 was using ORM
methods in order to change appropriate records. Although flexible, this approach
could lead to call some methods with side effects while neutralizing
(eg: overloads of write).
This patch converts the neutralize system to a safer "inert" SQL based approach
by migrating the generic method _neutralize to SQL files exposed in the
data folder.
Task id: 2961687
closes odoo/odoo#102792
X-original-commit: e5dbded9bb363351feff7ca8a56c7f8a6860f492
Related: odoo/enterprise#32580
Signed-off-by: Fabien Meghazi <fme@odoo.com>
157 lines
6.8 KiB
Python
157 lines
6.8 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from unittest.mock import patch
|
|
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.tests import tagged
|
|
from odoo.tools import mute_logger
|
|
|
|
from odoo.addons.payment.tests.http_common import PaymentHttpCommon
|
|
from odoo.addons.payment_paypal.controllers.main import PaypalController
|
|
from odoo.addons.payment_paypal.tests.common import PaypalCommon
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class PaypalTest(PaypalCommon, PaymentHttpCommon):
|
|
|
|
def _get_expected_values(self):
|
|
return_url = self._build_url(PaypalController._return_url)
|
|
values = {
|
|
'address1': 'Huge Street 2/543',
|
|
'amount': str(self.amount),
|
|
'business': self.paypal.paypal_email_account,
|
|
'cancel_return': return_url,
|
|
'city': 'Sin City',
|
|
'cmd': '_xclick',
|
|
'country': 'BE',
|
|
'currency_code': self.currency.name,
|
|
'email': 'norbert.buyer@example.com',
|
|
'first_name': 'Norbert',
|
|
'item_name': f'{self.paypal.company_id.name}: {self.reference}',
|
|
'item_number': self.reference,
|
|
'last_name': 'Buyer',
|
|
'lc': 'en_US',
|
|
'notify_url': self._build_url(PaypalController._webhook_url),
|
|
'return': return_url,
|
|
'rm': '2',
|
|
'zip': '1000',
|
|
}
|
|
|
|
if self.paypal.fees_active:
|
|
fees = self.currency.round(self.paypal._compute_fees(self.amount, self.currency, self.partner.country_id))
|
|
if fees:
|
|
# handling input is only specified if truthy
|
|
values['handling'] = str(fees)
|
|
|
|
return values
|
|
|
|
def test_redirect_form_values(self):
|
|
tx = self._create_transaction(flow='redirect')
|
|
with mute_logger('odoo.addons.payment.models.payment_transaction'):
|
|
processing_values = tx._get_processing_values()
|
|
|
|
form_info = self._extract_values_from_html_form(processing_values['redirect_form_html'])
|
|
self.assertEqual(
|
|
form_info['action'],
|
|
'https://www.sandbox.paypal.com/cgi-bin/webscr')
|
|
|
|
expected_values = self._get_expected_values()
|
|
self.assertDictEqual(
|
|
expected_values, form_info['inputs'],
|
|
"Paypal: invalid inputs specified in the redirect form.")
|
|
|
|
def test_redirect_form_with_fees(self):
|
|
self.paypal.write({
|
|
'fees_active': True,
|
|
'fees_dom_fixed': 1.0,
|
|
'fees_dom_var': 0.35,
|
|
'fees_int_fixed': 1.5,
|
|
'fees_int_var': 0.50,
|
|
})
|
|
expected_values = self._get_expected_values()
|
|
|
|
tx = self._create_transaction(flow='redirect')
|
|
with mute_logger('odoo.addons.payment.models.payment_transaction'):
|
|
processing_values = tx._get_processing_values()
|
|
form_info = self._extract_values_from_html_form(processing_values['redirect_form_html'])
|
|
|
|
self.assertEqual(form_info['action'], 'https://www.sandbox.paypal.com/cgi-bin/webscr')
|
|
self.assertDictEqual(
|
|
expected_values, form_info['inputs'],
|
|
"Paypal: invalid inputs specified in the redirect form.")
|
|
|
|
def test_feedback_processing(self):
|
|
# Unknown transaction
|
|
with self.assertRaises(ValidationError):
|
|
self.env['payment.transaction']._handle_notification_data('paypal', self.notification_data)
|
|
|
|
# Confirmed transaction
|
|
tx = self._create_transaction('redirect')
|
|
self.env['payment.transaction']._handle_notification_data('paypal', self.notification_data)
|
|
self.assertEqual(tx.state, 'done')
|
|
self.assertEqual(tx.provider_reference, self.notification_data['txn_id'])
|
|
|
|
# Pending transaction
|
|
self.reference = 'Test Transaction 2'
|
|
tx = self._create_transaction('redirect')
|
|
payload = dict(
|
|
self.notification_data,
|
|
item_number=self.reference,
|
|
payment_status='Pending',
|
|
pending_reason='multi_currency',
|
|
)
|
|
self.env['payment.transaction']._handle_notification_data('paypal', payload)
|
|
self.assertEqual(tx.state, 'pending')
|
|
self.assertEqual(tx.state_message, payload['pending_reason'])
|
|
|
|
def test_fees_computation(self):
|
|
# If the merchant needs to keep 100€, the transaction will be equal to 103.30€.
|
|
# In this way, Paypal will take 103.30 * 2.9% + 0.30 = 3.30€
|
|
# And the merchant will take 103.30 - 3.30 = 100€
|
|
self.paypal.write({
|
|
'fees_active': True,
|
|
'fees_int_fixed': 0.30,
|
|
'fees_int_var': 2.90,
|
|
})
|
|
total_fee = self.paypal._compute_fees(100, False, False)
|
|
self.assertEqual(round(total_fee, 2), 3.3, 'Wrong computation of the Paypal fees')
|
|
|
|
def test_parsing_pdt_validation_response_returns_notification_data(self):
|
|
""" Test that the notification data are parsed from the content of a validation response."""
|
|
response_content = 'SUCCESS\nkey1=val1\nkey2=val+2\n'
|
|
notification_data = PaypalController._parse_pdt_validation_response(response_content)
|
|
self.assertDictEqual(notification_data, {'key1': 'val1', 'key2': 'val 2'})
|
|
|
|
def test_fail_to_parse_pdt_validation_response_if_not_successful(self):
|
|
""" Test that no notification data are returned from parsing unsuccessful PDT validation."""
|
|
response_content = 'FAIL\ndoes-not-matter'
|
|
notification_data = PaypalController._parse_pdt_validation_response(response_content)
|
|
self.assertIsNone(notification_data)
|
|
|
|
@mute_logger('odoo.addons.payment_paypal.controllers.main')
|
|
def test_webhook_notification_confirms_transaction(self):
|
|
""" Test the processing of a webhook notification. """
|
|
tx = self._create_transaction('redirect')
|
|
url = self._build_url(PaypalController._webhook_url)
|
|
with patch(
|
|
'odoo.addons.payment_paypal.controllers.main.PaypalController'
|
|
'._verify_webhook_notification_origin'
|
|
):
|
|
self._make_http_post_request(url, data=self.notification_data)
|
|
self.assertEqual(tx.state, 'done')
|
|
|
|
@mute_logger('odoo.addons.payment_paypal.controllers.main')
|
|
def test_webhook_notification_triggers_origin_check(self):
|
|
""" Test that receiving a webhook notification triggers an origin check. """
|
|
self._create_transaction('redirect')
|
|
url = self._build_url(PaypalController._webhook_url)
|
|
with patch(
|
|
'odoo.addons.payment_paypal.controllers.main.PaypalController'
|
|
'._verify_webhook_notification_origin'
|
|
) as origin_check_mock, patch(
|
|
'odoo.addons.payment.models.payment_transaction.PaymentTransaction'
|
|
'._handle_notification_data'
|
|
):
|
|
self._make_http_post_request(url, data=self.notification_data)
|
|
self.assertEqual(origin_check_mock.call_count, 1)
|