diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/payment_stripe/tests/test_stripe.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/payment_stripe/tests/test_stripe.py')
| -rw-r--r-- | addons/payment_stripe/tests/test_stripe.py | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/addons/payment_stripe/tests/test_stripe.py b/addons/payment_stripe/tests/test_stripe.py new file mode 100644 index 00000000..2ac28193 --- /dev/null +++ b/addons/payment_stripe/tests/test_stripe.py @@ -0,0 +1,318 @@ +# -*- coding: utf-8 -*- +import odoo +from odoo import fields +from odoo.exceptions import ValidationError +from odoo.addons.payment.tests.common import PaymentAcquirerCommon +from unittest.mock import patch +from . import stripe_mocks +from ..models.payment import STRIPE_SIGNATURE_AGE_TOLERANCE +from odoo.tools import mute_logger + + +class StripeCommon(PaymentAcquirerCommon): + + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + cls.stripe = cls.env.ref('payment.payment_acquirer_stripe') + cls.stripe.write({ + 'stripe_secret_key': 'sk_test_KJtHgNwt2KS3xM7QJPr4O5E8', + 'stripe_publishable_key': 'pk_test_QSPnimmb4ZhtkEy3Uhdm4S6J', + 'stripe_webhook_secret': 'whsec_vG1fL6CMUouQ7cObF2VJprLVXT5jBLxB', + 'state': 'test', + }) + cls.token = cls.env['payment.token'].create({ + 'name': 'Test Card', + 'acquirer_id': cls.stripe.id, + 'acquirer_ref': 'cus_G27S7FqQ2w3fuH', + 'stripe_payment_method': 'pm_1FW3DdAlCFm536g8eQoSCejY', + 'partner_id': cls.buyer.id, + 'verified': True, + }) + cls.ideal_icon = cls.env.ref("payment.payment_icon_cc_ideal") + cls.bancontact_icon = cls.env.ref("payment.payment_icon_cc_bancontact") + cls.p24_icon = cls.env.ref("payment.payment_icon_cc_p24") + cls.eps_icon = cls.env.ref("payment.payment_icon_cc_eps") + cls.giropay_icon = cls.env.ref("payment.payment_icon_cc_giropay") + cls.all_icons = [cls.ideal_icon, cls.bancontact_icon, cls.p24_icon, cls.eps_icon, cls.giropay_icon] + cls.stripe.write({'payment_icon_ids': [(5, 0, 0)]}) + + +@odoo.tests.tagged('post_install', '-at_install', '-standard', 'external') +class StripeTest(StripeCommon): + + def run(self, result=None): + with mute_logger('odoo.addons.payment.models.payment_acquirer', 'odoo.addons.payment_stripe.models.payment'): + StripeCommon.run(self, result) + + def test_10_stripe_s2s(self): + self.assertEqual(self.stripe.state, 'test', 'test without test environment') + # Create transaction + tx = self.env['payment.transaction'].create({ + 'reference': 'stripe_test_10_%s' % fields.datetime.now().strftime('%Y%m%d_%H%M%S'), + 'currency_id': self.currency_euro.id, + 'acquirer_id': self.stripe.id, + 'partner_id': self.buyer_id, + 'payment_token_id': self.token.id, + 'type': 'server2server', + 'amount': 115.0 + }) + tx.with_context(off_session=True).stripe_s2s_do_transaction() + + # Check state + self.assertEqual(tx.state, 'done', 'Stripe: Transcation has been discarded.') + + def test_20_stripe_form_render(self): + self.assertEqual(self.stripe.state, 'test', 'test without test environment') + + # ---------------------------------------- + # Test: button direct rendering + # ---------------------------------------- + + # render the button + self.stripe.render('SO404', 320.0, self.currency_euro.id, values=self.buyer_values).decode('utf-8') + + def test_30_stripe_form_management(self): + self.assertEqual(self.stripe.state, 'test', 'test without test environment') + ref = 'stripe_test_30_%s' % fields.datetime.now().strftime('%Y%m%d_%H%M%S') + tx = self.env['payment.transaction'].create({ + 'amount': 4700.0, + 'acquirer_id': self.stripe.id, + 'currency_id': self.currency_euro.id, + 'reference': ref, + 'partner_name': 'Norbert Buyer', + 'partner_country_id': self.country_france.id, + 'payment_token_id': self.token.id, + }) + res = tx.with_context(off_session=True)._stripe_create_payment_intent() + tx.stripe_payment_intent = res.get('payment_intent') + + # typical data posted by Stripe after client has successfully paid + stripe_post_data = {'reference': ref} + # validate it + tx.form_feedback(stripe_post_data, 'stripe') + self.assertEqual(tx.state, 'done', 'Stripe: validation did not put tx into done state') + self.assertEqual(tx.acquirer_reference, stripe_post_data.get('id'), 'Stripe: validation did not update tx id') + + def test_add_available_payment_method_types_local_enabled(self): + self.stripe.payment_icon_ids = [(6, 0, [i.id for i in self.all_icons])] + tx_values = { + 'billing_partner_country': self.env.ref('base.be'), + 'currency': self.env.ref('base.EUR'), + 'type': 'form' + } + stripe_session_data = {} + + self.stripe._add_available_payment_method_types(stripe_session_data, tx_values) + + actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')} + self.assertEqual({'card', 'bancontact'}, actual) + + def test_add_available_payment_method_types_local_enabled_2(self): + self.stripe.payment_icon_ids = [(6, 0, [i.id for i in self.all_icons])] + tx_values = { + 'billing_partner_country': self.env.ref('base.pl'), + 'currency': self.env.ref('base.PLN'), + 'type': 'form' + } + stripe_session_data = {} + + self.stripe._add_available_payment_method_types(stripe_session_data, tx_values) + + actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')} + self.assertEqual({'card', 'p24'}, actual) + + def test_add_available_payment_method_types_pmt_does_not_exist(self): + self.bancontact_icon.unlink() + tx_values = { + 'billing_partner_country': self.env.ref('base.be'), + 'currency': self.env.ref('base.EUR'), + 'type': 'form' + } + stripe_session_data = {} + + self.stripe._add_available_payment_method_types(stripe_session_data, tx_values) + + actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')} + self.assertEqual({'card', 'bancontact'}, actual) + + def test_add_available_payment_method_types_local_disabled(self): + tx_values = { + 'billing_partner_country': self.env.ref('base.be'), + 'currency': self.env.ref('base.EUR'), + 'type': 'form' + } + stripe_session_data = {} + + self.stripe._add_available_payment_method_types(stripe_session_data, tx_values) + + actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')} + self.assertEqual({'card'}, actual) + + def test_add_available_payment_method_types_local_all_but_bancontact(self): + self.stripe.payment_icon_ids = [(4, icon.id) for icon in self.all_icons if icon.name.lower() != 'bancontact'] + tx_values = { + 'billing_partner_country': self.env.ref('base.be'), + 'currency': self.env.ref('base.EUR'), + 'type': 'form' + } + stripe_session_data = {} + + self.stripe._add_available_payment_method_types(stripe_session_data, tx_values) + + actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')} + self.assertEqual({'card'}, actual) + + def test_add_available_payment_method_types_recurrent(self): + tx_values = { + 'billing_partner_country': self.env.ref('base.be'), + 'currency': self.env.ref('base.EUR'), + 'type': 'form_save' + } + stripe_session_data = {} + + self.stripe._add_available_payment_method_types(stripe_session_data, tx_values) + + actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')} + self.assertEqual({'card'}, actual) + + def test_discarded_webhook(self): + self.assertFalse(self.env['payment.acquirer']._handle_stripe_webhook(dict(type='payment.intent.succeeded'))) + + def test_handle_checkout_webhook_no_secret(self): + self.stripe.stripe_webhook_secret = None + + with self.assertRaises(ValidationError): + self.env['payment.acquirer']._handle_stripe_webhook(dict(type='checkout.session.completed')) + + @patch('odoo.addons.payment_stripe.models.payment.request') + @patch('odoo.addons.payment_stripe.models.payment.datetime') + def test_handle_checkout_webhook(self, dt, request): + # pass signature verification + dt.utcnow.return_value.timestamp.return_value = 1591264652 + request.httprequest.headers = {'Stripe-Signature': stripe_mocks.checkout_session_signature} + request.httprequest.data = stripe_mocks.checkout_session_body + # test setup + tx = self.env['payment.transaction'].create({ + 'reference': 'tx_ref_test_handle_checkout_webhook', + 'currency_id': self.currency_euro.id, + 'acquirer_id': self.stripe.id, + 'partner_id': self.buyer_id, + 'payment_token_id': self.token.id, + 'type': 'server2server', + 'amount': 30 + }) + res = tx.with_context(off_session=True)._stripe_create_payment_intent() + tx.stripe_payment_intent = res.get('payment_intent') + stripe_object = stripe_mocks.checkout_session_object + + actual = self.stripe._handle_checkout_webhook(stripe_object) + + self.assertTrue(actual) + + @patch('odoo.addons.payment_stripe.models.payment.request') + @patch('odoo.addons.payment_stripe.models.payment.datetime') + def test_handle_checkout_webhook_wrong_amount(self, dt, request): + # pass signature verification + dt.utcnow.return_value.timestamp.return_value = 1591264652 + request.httprequest.headers = {'Stripe-Signature': stripe_mocks.checkout_session_signature} + request.httprequest.data = stripe_mocks.checkout_session_body + # test setup + bad_tx = self.env['payment.transaction'].create({ + 'reference': 'tx_ref_test_handle_checkout_webhook_wrong_amount', + 'currency_id': self.currency_euro.id, + 'acquirer_id': self.stripe.id, + 'partner_id': self.buyer_id, + 'payment_token_id': self.token.id, + 'type': 'server2server', + 'amount': 10 + }) + wrong_amount_stripe_payment_intent = bad_tx.with_context(off_session=True)._stripe_create_payment_intent() + tx = self.env['payment.transaction'].create({ + 'reference': 'tx_ref_test_handle_checkout_webhook', + 'currency_id': self.currency_euro.id, + 'acquirer_id': self.stripe.id, + 'partner_id': self.buyer_id, + 'payment_token_id': self.token.id, + 'type': 'server2server', + 'amount': 30 + }) + tx.stripe_payment_intent = wrong_amount_stripe_payment_intent.get('payment_intent') + stripe_object = stripe_mocks.checkout_session_object + + actual = self.env['payment.acquirer']._handle_checkout_webhook(stripe_object) + + self.assertFalse(actual) + + def test_handle_checkout_webhook_no_odoo_tx(self): + stripe_object = stripe_mocks.checkout_session_object + + actual = self.stripe._handle_checkout_webhook(stripe_object) + + self.assertFalse(actual) + + @patch('odoo.addons.payment_stripe.models.payment.request') + @patch('odoo.addons.payment_stripe.models.payment.datetime') + def test_handle_checkout_webhook_no_stripe_tx(self, dt, request): + # pass signature verification + dt.utcnow.return_value.timestamp.return_value = 1591264652 + request.httprequest.headers = {'Stripe-Signature': stripe_mocks.checkout_session_signature} + request.httprequest.data = stripe_mocks.checkout_session_body + # test setup + self.env['payment.transaction'].create({ + 'reference': 'tx_ref_test_handle_checkout_webhook', + 'currency_id': self.currency_euro.id, + 'acquirer_id': self.stripe.id, + 'partner_id': self.buyer_id, + 'payment_token_id': self.token.id, + 'type': 'server2server', + 'amount': 30 + }) + stripe_object = stripe_mocks.checkout_session_object + + with self.assertRaises(ValidationError): + self.stripe._handle_checkout_webhook(stripe_object) + + @patch('odoo.addons.payment_stripe.models.payment.request') + @patch('odoo.addons.payment_stripe.models.payment.datetime') + def test_verify_stripe_signature(self, dt, request): + dt.utcnow.return_value.timestamp.return_value = 1591264652 + request.httprequest.headers = {'Stripe-Signature': stripe_mocks.checkout_session_signature} + request.httprequest.data = stripe_mocks.checkout_session_body + + actual = self.stripe._verify_stripe_signature() + + self.assertTrue(actual) + + @patch('odoo.addons.payment_stripe.models.payment.request') + @patch('odoo.addons.payment_stripe.models.payment.datetime') + def test_verify_stripe_signature_tampered_body(self, dt, request): + dt.utcnow.return_value.timestamp.return_value = 1591264652 + request.httprequest.headers = {'Stripe-Signature': stripe_mocks.checkout_session_signature} + request.httprequest.data = stripe_mocks.checkout_session_body.replace(b'1500', b'10') + + with self.assertRaises(ValidationError): + self.stripe._verify_stripe_signature() + + @patch('odoo.addons.payment_stripe.models.payment.request') + @patch('odoo.addons.payment_stripe.models.payment.datetime') + def test_verify_stripe_signature_wrong_secret(self, dt, request): + dt.utcnow.return_value.timestamp.return_value = 1591264652 + request.httprequest.headers = {'Stripe-Signature': stripe_mocks.checkout_session_signature} + request.httprequest.data = stripe_mocks.checkout_session_body + self.stripe.write({ + 'stripe_webhook_secret': 'whsec_vG1fL6CMUouQ7cObF2VJprL_TAMPERED', + }) + + with self.assertRaises(ValidationError): + self.stripe._verify_stripe_signature() + + @patch('odoo.addons.payment_stripe.models.payment.request') + @patch('odoo.addons.payment_stripe.models.payment.datetime') + def test_verify_stripe_signature_too_old(self, dt, request): + dt.utcnow.return_value.timestamp.return_value = 1591264652 + STRIPE_SIGNATURE_AGE_TOLERANCE + 1 + request.httprequest.headers = {'Stripe-Signature': stripe_mocks.checkout_session_signature} + request.httprequest.data = stripe_mocks.checkout_session_body + + with self.assertRaises(ValidationError): + self.stripe._verify_stripe_signature() |
