Odoo18-Base/addons/payment_paypal/tests/test_paypal.py
2025-03-10 11:12:23 +07:00

158 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',
'no_shipping': '1',
'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)