def test_rerun_declined_transactions_for_pair(self):
        from silver.transaction_retries import TransactionRetryAttempter
        attempts = TransactionRetryAttempter()

        initial_try = dt.datetime(2019, 1, 1, 0, 0, 0, 0, tzinfo=pytz.UTC)
        retry_begins = dt.datetime(2019, 1, 3, 0, 0, 0, 0, tzinfo=pytz.UTC)
        retry_ends = dt.datetime(2019, 1, 5, 0, 0, 0, 0, tzinfo=pytz.UTC)

        customer, payment_method = self._create_default_payment_method()

        customer.save()
        payment_method.save()

        trx = TransactionFactory(state=Transaction.States.Failed,
                                 created_at=initial_try,
                                 updated_at=initial_try,
                                 payment_method=payment_method)
        trx.save()

        assert trx.invoice.transactions.count() == 1

        # payment method is not configured to allow retry attempts.
        attempts.check(billing_date=initial_try)
        assert trx.invoice.transactions.count() == 1

        attempts.check(billing_date=retry_begins)
        assert trx.invoice.transactions.count() == 2
    def test_management_command(self):
        initial_try = dt.datetime(2019, 1, 1, 0, 0, 0, 0, tzinfo=pytz.UTC)
        retry_begins = dt.datetime(2019, 1, 3, 0, 0, 0, 0, tzinfo=pytz.UTC)
        retry_ends = dt.datetime(2019, 1, 5, 0, 0, 0, 0, tzinfo=pytz.UTC)

        customer, payment_method = self._create_default_payment_method()

        customer.save()
        payment_method.save()

        trx = TransactionFactory(state=Transaction.States.Failed,
                                 created_at=initial_try,
                                 updated_at=initial_try,
                                 proforma=None,
                                 payment_method=payment_method)
        trx.save()

        assert trx.invoice.transactions.count() == 1

        call_command('retry_failed_transactions',
                     billing_date=initial_try,
                     stdout=self.output)

        assert trx.invoice.transactions.count() == 1

        call_command('retry_failed_transactions',
                     billing_date=retry_begins,
                     stdout=self.output)

        assert trx.invoice.transactions.count() == 2
    def test_failed_docs_query(self):
        from silver.transaction_retries import TransactionRetryAttempter
        attempts = TransactionRetryAttempter()

        c = list(attempts._query_payment_failures())
        assert len(c) == 0

        b = TransactionFactory(state=Transaction.States.Failed)
        b.save()

        c = list(attempts._query_payment_failures())
        assert len(c) == 1
    def test_cannot_issue_new_transaction_while_pending(self):
        """ The TransactionRetryAttempter should only be able to issue
        transactions while there are no pending re-attempted Transactions
        with state Issued. """

        from silver.transaction_retries import TransactionRetryAttempter
        attempts = TransactionRetryAttempter()

        initial_try = dt.datetime(2019, 1, 1, 0, 0, 0, 0, tzinfo=pytz.UTC)
        retry_begins = dt.datetime(2019, 1, 3, 0, 0, 0, 0, tzinfo=pytz.UTC)
        retry_ends = dt.datetime(2019, 1, 5, 0, 0, 0, 0, tzinfo=pytz.UTC)

        customer, payment_method = self._create_default_payment_method()

        customer.save()
        payment_method.save()

        trx = TransactionFactory(state=Transaction.States.Failed,
                                 created_at=initial_try,
                                 updated_at=initial_try,
                                 proforma=None,
                                 payment_method=payment_method)
        trx.save()

        assert trx.invoice.transactions.count() == 1

        # Spam some attempts
        attempts.check(billing_date=retry_begins)
        attempts.check(billing_date=retry_begins)
        attempts.check(billing_date=retry_begins)
        attempts.check(billing_date=retry_begins)

        assert trx.invoice.transactions.count() == 2

        # Spam some attempts with force.
        attempts.check(billing_date=retry_begins, force=True)
        attempts.check(billing_date=retry_begins, force=True)
        attempts.check(billing_date=retry_begins, force=True)
        attempts.check(billing_date=retry_begins, force=True)

        assert trx.invoice.transactions.count() == 2
    def test_no_new_attempts_for_existing_functionality(self):
        from silver.transaction_retries import TransactionRetryAttempter
        attempts = TransactionRetryAttempter()

        c = list(attempts._query_payment_failures())
        assert len(c) == 0

        b = TransactionFactory(state=Transaction.States.Failed)
        b.save()

        invoice = b.invoice
        proforma = b.proforma

        c = list(attempts._query_payment_failures())
        assert len(c) == 1

        # payment method is not configured to allow retry attempts.
        attempts.check(billing_date=timezone.now())

        assert proforma.transactions.count() == 1
        assert invoice.transactions.count() == 1