158 lines
6.8 KiB
Python
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)
|