Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add ACH to stripe email template #1105

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Conversation

suejung-sentry
Copy link
Contributor

Purpose/Motivation

What is the feature? Why is this being done?

Links to relevant tickets

What does this PR do?

Include a brief description of the changes in this PR. Bullet points are your friend.

Notes to Reviewer

Anything to note to the team? Any tips on how to review, or where to start?

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

Copy link

sentry-io bot commented Jan 21, 2025

🔍 Existing Issues For Review

Your pull request is modifying functions with the following pre-existing issues:

📄 File: billing/views.py

Function Unhandled Issue
invoice_payment_failed AttributeError: card /webhooks/stripe
Event Count: 3

Did you find this useful? React with a 👍 or 👎

Copy link

codecov bot commented Jan 21, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
2695 2 2693 7
View the top 2 failed tests by shortest run time
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026230297360'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennife...me='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371520'>
mocked_send_email = <MagicMock name='send_email' id='140026230297360'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent()
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
    
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': 'visa',
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:393: AssertionError
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins_no_card
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026210109296'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82...ame='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins_no_card>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371040'>
mocked_send_email = <MagicMock name='send_email' id='140026210109296'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins_no_card(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent(noCard=True)
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "default_payment_method": None,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': None,
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:467: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

@codecov-notifications
Copy link

codecov-notifications bot commented Jan 21, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
2695 2 2693 7
View the top 2 failed tests by shortest run time
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026230297360'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennife...me='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371520'>
mocked_send_email = <MagicMock name='send_email' id='140026230297360'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent()
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
    
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': 'visa',
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:393: AssertionError
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins_no_card
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026210109296'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82...ame='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins_no_card>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371040'>
mocked_send_email = <MagicMock name='send_email' id='140026210109296'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins_no_card(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent(noCard=True)
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "default_payment_method": None,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': None,
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:467: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

@codecov-qa
Copy link

codecov-qa bot commented Jan 21, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
2695 2 2693 7
View the top 2 failed tests by shortest run time
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026230297360'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennife...me='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371520'>
mocked_send_email = <MagicMock name='send_email' id='140026230297360'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent()
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
    
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': 'visa',
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:393: AssertionError
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins_no_card
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026210109296'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82...ame='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins_no_card>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371040'>
mocked_send_email = <MagicMock name='send_email' id='140026210109296'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins_no_card(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent(noCard=True)
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "default_payment_method": None,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': None,
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:467: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

Copy link

codecov-public-qa bot commented Jan 21, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
2696 2 2694 6
View the top 2 failed tests by shortest run time
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026230297360'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennife...me='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371520'>
mocked_send_email = <MagicMock name='send_email' id='140026230297360'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent()
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
    
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': 'visa',
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:393: AssertionError
billing/tests/test_views.py::StripeWebhookHandlerTests::test_invoice_payment_failed_sends_email_to_admins_no_card
Stack Traces | 0.034s run time
self = <MagicMock name='send_email' id='140026210109296'>
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82...ame='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]

.../local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = <billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins_no_card>
retrieve_paymentintent_mock = <MagicMock name='retrieve' id='140026268371040'>
mocked_send_email = <MagicMock name='send_email' id='140026210109296'>

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins_no_card(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent(noCard=True)
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "default_payment_method": None,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
>       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': None,
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:467: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

Copy link
Contributor

github-actions bot commented Jan 21, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
2702 2 2694 6
View the top 2 failed tests by shortest run time
test_invoice_payment_failed_sends_email_to_admins
Stack Traces | 0.034s run time
self = &lt;MagicMock name='send_email' id='140026230297360'&gt;
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennife...me='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
&gt;               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]

/usr/local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = &lt;billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins&gt;
retrieve_paymentintent_mock = &lt;MagicMock name='retrieve' id='140026268371520'&gt;
mocked_send_email = &lt;MagicMock name='send_email' id='140026230297360'&gt;

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent()
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type="visa",
                last_four="1234",
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
    
&gt;       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240, card_type='visa', last_four='1234', cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='jennifermendoza', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea23', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='andrea62', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=True, card_type='visa', last_four='1234', is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': True,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...: 'visa', ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': 'visa',
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:393: AssertionError
test_invoice_payment_failed_sends_email_to_admins_no_card
Stack Traces | 0.034s run time
self = &lt;MagicMock name='send_email' id='140026210109296'&gt;
calls = [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82...ame='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.
    
        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.
    
        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
&gt;               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="  Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E                 Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E                call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]

/usr/local/lib/python3.12/unittest/mock.py:986: AssertionError

During handling of the above exception, another exception occurred:

self = &lt;billing.tests.test_views.StripeWebhookHandlerTests testMethod=test_invoice_payment_failed_sends_email_to_admins_no_card&gt;
retrieve_paymentintent_mock = &lt;MagicMock name='retrieve' id='140026268371040'&gt;
mocked_send_email = &lt;MagicMock name='send_email' id='140026210109296'&gt;

    @patch("services.task.TaskService.send_email")
    @patch("services.billing.stripe.PaymentIntent.retrieve")
    def test_invoice_payment_failed_sends_email_to_admins_no_card(
        self,
        retrieve_paymentintent_mock,
        mocked_send_email,
    ):
        non_admin = OwnerFactory(email="[email protected]")
        admin_1 = OwnerFactory(email="[email protected]")
        admin_2 = OwnerFactory(email="[email protected]")
        self.owner.admins = [admin_1.ownerid, admin_2.ownerid]
        self.owner.plan_activated_users = [non_admin.ownerid]
        self.owner.email = "[email protected]"
        self.owner.save()
    
        retrieve_paymentintent_mock.return_value = MockPaymentIntent(noCard=True)
    
        response = self._send_event(
            payload={
                "type": "invoice.payment_failed",
                "data": {
                    "object": {
                        "customer": self.owner.stripe_customer_id,
                        "subscription": self.owner.stripe_subscription_id,
                        "default_payment_method": None,
                        "total": 24000,
                        "hosted_invoice_url": "https://stripe.com",
                        "payment_intent": "payment_intent_asdf",
                    }
                },
            }
        )
    
        self.owner.refresh_from_db()
        assert response.status_code == status.HTTP_204_NO_CONTENT
        assert self.owner.delinquent is True
    
        expected_calls = [
            call(
                to_addr=self.owner.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=self.owner.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_1.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_1.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
            call(
                to_addr=admin_2.email,
                subject="Your Codecov payment failed",
                template_name="failed-payment",
                name=admin_2.username,
                amount=240,
                card_type=None,
                last_four=None,
                cta_link="https://stripe.com",
                date=datetime.now().strftime("%B %-d, %Y"),
            ),
        ]
&gt;       mocked_send_email.assert_has_calls(expected_calls)
E       AssertionError: Calls not found.
E       Expected: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025'),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240, card_type=None, last_four=None, cta_link='https://stripe.com', date='January 21, 2025')]
E         Actual: [call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='corey82', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christian42', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='christina95', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None),
E        call(to_addr='[email protected]', subject='Your Codecov payment failed', template_name='failed-payment', name='spalmurray-codecov', amount=240.0, cta_link='https://stripe.com', date='January 21, 2025', is_credit_card=False, card_type=None, last_four=None, is_us_bank=False, bank_name=None, bank_last_four=None)]
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {'amount': 24...1, 2025', ...}
E         
E         Omitting 9 identical items, use -vv to show
E         Left contains 4 more items:
E         {'bank_last_four': None,
E          'bank_name': None,
E          'is_credit_card': False,
E          'is_us_bank': False}
E         Use -v to get more diff
E       Kwargs:
E       assert {'amount': 24...e': None, ...} == {}
E         
E         Left contains 13 more items:
E         {'amount': 240.0,
E          'bank_last_four': None,
E          'bank_name': None,
E          'card_type': None,
E          'cta_link': 'https://stripe.com',...
E         
E         ...Full output truncated (9 lines hidden), use '-vv' to show

billing/tests/test_views.py:467: AssertionError

📣 Thoughts on this report? Let Codecov know! | Powered by Codecov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant