class TestBillingAutoPay(BaseInvoiceTestCase): def setUp(self): super(TestBillingAutoPay, self).setUp() self.account.created_by_domain = self.domain self.account.save() self.currency = generator.init_default_currency() self.web_user = generator.arbitrary_web_user() self.dimagi_user = generator.arbitrary_web_user(is_dimagi=True) self.fake_card = FakeStripeCard() self.fake_stripe_customer = FakeStripeCustomer(cards=[self.fake_card]) self.account.update_autopay_user(self.web_user.username) self.invoice_date = utils.months_from_date( self.subscription.date_start, random.randint(2, self.subscription_length) ) self.account_2 = generator.billing_account(self.dimagi_user, self.web_user) self.domain_2 = generator.arbitrary_domain() self.subscription_2, self.subscription_length_2 = generator.generate_domain_subscription_from_date( generator.get_start_date(), self.account_2, self.domain_2.name, min_num_months=self.min_subscription_length ) tasks.generate_invoices(self.invoice_date) @mock.patch.object(StripePaymentMethod, "customer") def test_get_autopayable_invoices(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.payment_method = StripePaymentMethod( web_user=self.web_user.username, customer_id=self.fake_stripe_customer.id ) self.payment_method.set_autopay(self.fake_card, self.account) self.payment_method.save() autopayable_invoice = Invoice.objects.filter(subscription=self.subscription) date_due = autopayable_invoice.first().date_due autopayable_invoices = Invoice.autopayable_invoices(date_due) self.assertItemsEqual(autopayable_invoices, autopayable_invoice) @mock.patch.object(StripePaymentMethod, "customer") @mock.patch.object(Charge, "create") def test_pay_autopayable_invoices(self, fake_charge, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.payment_method = StripePaymentMethod( web_user=self.web_user.username, customer_id=self.fake_stripe_customer.id ) self.payment_method.set_autopay(self.fake_card, self.account) self.payment_method.save() original_outbox_length = len(mail.outbox) autopayable_invoice = Invoice.objects.filter(subscription=self.subscription) date_due = autopayable_invoice.first().date_due AutoPayInvoicePaymentHandler().pay_autopayable_invoices(date_due) self.assertAlmostEqual(autopayable_invoice.first().get_total(), 0) self.assertEqual(len(PaymentRecord.objects.all()), 1) self.assertEqual(len(mail.outbox), original_outbox_length + 1)
def test_set_autopay(self, fake_customer): fake_customer.__get__ = mock.Mock( return_value=self.fake_stripe_customer) self.assertEqual(self.billing_account.auto_pay_user, None) self.assertFalse(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account, None) self.assertEqual( self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True'}) self.assertEqual(self.billing_account.auto_pay_user, self.web_user) self.assertTrue(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account_2, None) self.assertEqual( self.fake_card.metadata, { "auto_pay_{}".format(self.billing_account.id): 'True', "auto_pay_{}".format(self.billing_account_2.id): 'True' }) other_web_user = generator.create_arbitrary_web_user_name() other_payment_method = StripePaymentMethod(web_user=other_web_user) different_fake_card = FakeStripeCard() other_payment_method.set_autopay(different_fake_card, self.billing_account, None) self.assertEqual(self.billing_account.auto_pay_user, other_web_user) self.assertTrue(different_fake_card.metadata["auto_pay_{}".format( self.billing_account.id)]) self.assertFalse(self.fake_card.metadata["auto_pay_{}".format( self.billing_account.id)] == 'True')
def test_set_autopay(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.assertEqual(self.billing_account.auto_pay_user, None) self.assertFalse(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True'}) self.assertEqual(self.billing_account.auto_pay_user, self.web_user.username) self.assertTrue(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account_2, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True', "auto_pay_{}".format(self.billing_account_2.id): 'True'}) other_web_user = generator.arbitrary_web_user() other_payment_method = StripePaymentMethod(web_user=other_web_user.username) different_fake_card = FakeStripeCard() other_payment_method.set_autopay(different_fake_card, self.billing_account, None) self.assertEqual(self.billing_account.auto_pay_user, other_web_user.username) self.assertTrue(different_fake_card.metadata["auto_pay_{}".format(self.billing_account.id)]) self.assertFalse(self.fake_card.metadata["auto_pay_{}".format(self.billing_account.id)] == 'True')
class TestStripePaymentMethod(BaseAccountingTest): def setUp(self): super(TestStripePaymentMethod, self).setUp() self.web_user = generator.create_arbitrary_web_user_name() self.dimagi_user = generator.create_arbitrary_web_user_name(is_dimagi=True) self.fake_card = FakeStripeCard() self.fake_stripe_customer = FakeStripeCustomer(cards=[self.fake_card]) self.currency = generator.init_default_currency() self.billing_account = generator.billing_account(self.dimagi_user, self.web_user) self.billing_account_2 = generator.billing_account(self.dimagi_user, self.web_user) self.payment_method = StripePaymentMethod(web_user=self.web_user, customer_id=self.fake_stripe_customer.id) self.payment_method.save() def test_set_autopay(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.assertEqual(self.billing_account.auto_pay_user, None) self.assertFalse(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True'}) self.assertEqual(self.billing_account.auto_pay_user, self.web_user) self.assertTrue(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account_2, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True', "auto_pay_{}".format(self.billing_account_2.id): 'True'}) other_web_user = generator.create_arbitrary_web_user_name() other_payment_method = StripePaymentMethod(web_user=other_web_user) different_fake_card = FakeStripeCard() other_payment_method.set_autopay(different_fake_card, self.billing_account, None) self.assertEqual(self.billing_account.auto_pay_user, other_web_user) self.assertTrue(different_fake_card.metadata["auto_pay_{}".format(self.billing_account.id)]) self.assertFalse(self.fake_card.metadata["auto_pay_{}".format(self.billing_account.id)] == 'True') def test_unset_autopay(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.payment_method.set_autopay(self.fake_card, self.billing_account, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True'}) self.payment_method.unset_autopay(self.fake_card, self.billing_account) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'False'}) self.assertIsNone(self.billing_account.auto_pay_user) self.assertFalse(self.billing_account.auto_pay_enabled)
class TestStripePaymentMethod(BaseAccountingTest): def setUp(self): super(TestStripePaymentMethod, self).setUp() self.web_user = generator.arbitrary_web_user() self.dimagi_user = generator.arbitrary_web_user(is_dimagi=True) self.fake_card = FakeStripeCard() self.fake_stripe_customer = FakeStripeCustomer(cards=[self.fake_card]) self.currency = generator.init_default_currency() self.billing_account = generator.billing_account(self.dimagi_user, self.web_user) self.billing_account_2 = generator.billing_account(self.dimagi_user, self.web_user) self.payment_method = StripePaymentMethod(web_user=self.web_user.username, customer_id=self.fake_stripe_customer.id) self.payment_method.save() def test_set_autopay(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.assertEqual(self.billing_account.auto_pay_user, None) self.assertFalse(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True'}) self.assertEqual(self.billing_account.auto_pay_user, self.web_user.username) self.assertTrue(self.billing_account.auto_pay_enabled) self.payment_method.set_autopay(self.fake_card, self.billing_account_2, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True', "auto_pay_{}".format(self.billing_account_2.id): 'True'}) other_web_user = generator.arbitrary_web_user() other_payment_method = StripePaymentMethod(web_user=other_web_user.username) different_fake_card = FakeStripeCard() other_payment_method.set_autopay(different_fake_card, self.billing_account, None) self.assertEqual(self.billing_account.auto_pay_user, other_web_user.username) self.assertTrue(different_fake_card.metadata["auto_pay_{}".format(self.billing_account.id)]) self.assertFalse(self.fake_card.metadata["auto_pay_{}".format(self.billing_account.id)] == 'True') def test_unset_autopay(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.payment_method.set_autopay(self.fake_card, self.billing_account, None) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'True'}) self.payment_method.unset_autopay(self.fake_card, self.billing_account) self.assertEqual(self.fake_card.metadata, {"auto_pay_{}".format(self.billing_account.id): 'False'}) self.assertIsNone(self.billing_account.auto_pay_user) self.assertFalse(self.billing_account.auto_pay_enabled)
class TestBillingAutoPay(BaseInvoiceTestCase): def setUp(self): super(TestBillingAutoPay, self).setUp() self._generate_autopayable_entities() self._generate_non_autopayable_entities() self._generate_invoices() def _generate_autopayable_entities(self): """ Create account, domain and subscription linked to the autopay user that have autopay enabled """ self.autopay_account = self.account self.autopay_account.created_by_domain = self.domain self.autopay_account.save() self.autopay_user = generator.arbitrary_web_user() self.fake_card = FakeStripeCard() self.fake_stripe_customer = FakeStripeCustomer(cards=[self.fake_card]) self.autopay_account.update_autopay_user(self.autopay_user.username, self.domain) def _generate_non_autopayable_entities(self): """ Create account, domain, and subscription linked to the autopay user, but that don't have autopay enabled """ self.non_autopay_account = generator.billing_account( web_user_creator=generator.arbitrary_web_user(is_dimagi=True), web_user_contact=self.autopay_user ) self.non_autopay_domain = generator.arbitrary_domain() # Non-autopay subscription has same parameters as the autopayable subscription self.non_autopay_subscription = generator.generate_domain_subscription( self.non_autopay_account, self.non_autopay_domain, date_start=self.subscription.date_start, date_end=add_months_to_date(self.subscription.date_start, self.subscription_length), ) def _generate_invoices(self): """ Create invoices for both autopayable and non-autopayable subscriptions """ # invoice date is 2 months before the end of the subscription (this is arbitrary) invoice_date = utils.months_from_date(self.subscription.date_start, self.subscription_length - 2) tasks.generate_invoices(invoice_date) @mock.patch.object(StripePaymentMethod, 'customer') def test_get_autopayable_invoices(self, fake_customer): """ Invoice.autopayable_invoices() should return invoices that can be automatically paid """ self._create_autopay_method(fake_customer) autopayable_invoice = Invoice.objects.filter(subscription=self.subscription) date_due = autopayable_invoice.first().date_due autopayable_invoices = Invoice.autopayable_invoices(date_due) self.assertItemsEqual(autopayable_invoices, autopayable_invoice) def test_get_autopayable_invoices_returns_nothing(self): """ Invoice.autopayable_invoices() should not return invoices if the customer does not have an autopay method """ not_autopayable_invoice = Invoice.objects.filter(subscription=self.non_autopay_subscription) date_due = not_autopayable_invoice.first().date_due autopayable_invoices = Invoice.autopayable_invoices(date_due) self.assertItemsEqual(autopayable_invoices, []) @mock.patch.object(StripePaymentMethod, 'customer') @mock.patch.object(Charge, 'create') def test_pay_autopayable_invoices(self, fake_charge, fake_customer): self._create_autopay_method(fake_customer) original_outbox_length = len(mail.outbox) autopayable_invoice = Invoice.objects.filter(subscription=self.subscription) date_due = autopayable_invoice.first().date_due AutoPayInvoicePaymentHandler().pay_autopayable_invoices(date_due) self.assertAlmostEqual(autopayable_invoice.first().get_total(), 0) self.assertEqual(len(PaymentRecord.objects.all()), 1) self.assertEqual(len(mail.outbox), original_outbox_length + 1) def _create_autopay_method(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.payment_method = StripePaymentMethod(web_user=self.autopay_user.username, customer_id=self.fake_stripe_customer.id) self.payment_method.set_autopay(self.fake_card, self.autopay_account, self.domain) self.payment_method.save()
class TestBillingAutoPay(BaseInvoiceTestCase): @classmethod def setUpClass(cls): super(TestBillingAutoPay, cls).setUpClass() cls._generate_autopayable_entities() cls._generate_non_autopayable_entities() cls._generate_invoices() @classmethod def tearDownClass(cls): cls.non_autopay_domain.delete() super(TestBillingAutoPay, cls).tearDownClass() @classmethod def _generate_autopayable_entities(cls): """ Create account, domain and subscription linked to the autopay user that have autopay enabled """ cls.autopay_account = cls.account cls.autopay_account.created_by_domain = cls.domain cls.autopay_account.save() cls.autopay_user_email = generator.create_arbitrary_web_user_name() cls.fake_card = FakeStripeCard() cls.fake_stripe_customer = FakeStripeCustomer(cards=[cls.fake_card]) cls.autopay_account.update_autopay_user(cls.autopay_user_email, cls.domain) @classmethod def _generate_non_autopayable_entities(cls): """ Create account, domain, and subscription linked to the autopay user, but that don't have autopay enabled """ cls.non_autopay_account = generator.billing_account( web_user_creator=generator.create_arbitrary_web_user_name( is_dimagi=True), web_user_contact=cls.autopay_user_email) cls.non_autopay_domain = generator.arbitrary_domain() # Non-autopay subscription has same parameters as the autopayable subscription cheap_plan = SoftwarePlan.objects.create(name='cheap') cheap_product_rate = SoftwareProductRate.objects.create( monthly_fee=100, name=cheap_plan.name) cheap_plan_version = SoftwarePlanVersion.objects.create( plan=cheap_plan, product_rate=cheap_product_rate, role=Role.objects.first(), ) cls.non_autopay_subscription = generator.generate_domain_subscription( cls.non_autopay_account, cls.non_autopay_domain, plan_version=cheap_plan_version, date_start=cls.subscription.date_start, date_end=add_months_to_date(cls.subscription.date_start, cls.subscription_length), ) @classmethod def _generate_invoices(cls): """ Create invoices for both autopayable and non-autopayable subscriptions """ # invoice date is 2 months before the end of the subscription (this is arbitrary) invoice_date = utils.months_from_date(cls.subscription.date_start, cls.subscription_length - 2) tasks.calculate_users_in_all_domains(invoice_date) tasks.generate_invoices(invoice_date) @mock.patch.object(StripePaymentMethod, 'customer') def test_get_autopayable_invoices(self, fake_customer): """ Invoice.autopayable_invoices() should return invoices that can be automatically paid """ self._create_autopay_method(fake_customer) autopayable_invoice = Invoice.objects.filter( subscription=self.subscription) date_due = autopayable_invoice.first().date_due autopayable_invoices = Invoice.autopayable_invoices(date_due) self.assertItemsEqual(autopayable_invoices, autopayable_invoice) def test_get_autopayable_invoices_returns_nothing(self): """ Invoice.autopayable_invoices() should not return invoices if the customer does not have an autopay method """ not_autopayable_invoice = Invoice.objects.filter( subscription=self.non_autopay_subscription) date_due = not_autopayable_invoice.first().date_due autopayable_invoices = Invoice.autopayable_invoices(date_due) self.assertItemsEqual(autopayable_invoices, []) @mock.patch.object(StripePaymentMethod, 'customer') @mock.patch.object(Charge, 'create') def test_pay_autopayable_invoices(self, fake_charge, fake_customer): self._create_autopay_method(fake_customer) fake_charge.return_value = StripeObject(id='transaction_id') original_outbox_length = len(mail.outbox) autopayable_invoice = Invoice.objects.filter( subscription=self.subscription) date_due = autopayable_invoice.first().date_due AutoPayInvoicePaymentHandler().pay_autopayable_invoices(date_due) self.assertAlmostEqual(autopayable_invoice.first().get_total(), 0) self.assertEqual(len(PaymentRecord.objects.all()), 1) self.assertEqual(len(mail.outbox), original_outbox_length + 1) def _create_autopay_method(self, fake_customer): fake_customer.__get__ = mock.Mock( return_value=self.fake_stripe_customer) self.payment_method = StripePaymentMethod( web_user=self.autopay_user_email, customer_id=self.fake_stripe_customer.id) self.payment_method.set_autopay(self.fake_card, self.autopay_account, self.domain) self.payment_method.save() @mock.patch.object(StripePaymentMethod, 'customer') @mock.patch.object(Charge, 'create') @mock.patch.object(PaymentRecord, 'create_record') def test_when_create_record_fails_stripe_is_not_charged( self, fake_create_record, fake_create, fake_customer): fake_create_record.side_effect = Exception self._create_autopay_method(fake_customer) self.original_outbox_length = len(mail.outbox) self._run_autopay() self.assertFalse(fake_create.called) self._assert_no_side_effects() @mock.patch.object(StripePaymentMethod, 'customer') @mock.patch.object(Charge, 'create') def test_when_stripe_fails_no_payment_record_exists( self, fake_create, fake_customer): fake_create.side_effect = Exception self._create_autopay_method(fake_customer) self.original_outbox_length = len(mail.outbox) self._run_autopay() self._assert_no_side_effects() def _run_autopay(self): autopayable_invoice = Invoice.objects.filter( subscription=self.subscription) date_due = autopayable_invoice.first().date_due AutoPayInvoicePaymentHandler().pay_autopayable_invoices(date_due) def _assert_no_side_effects(self): self.assertEqual(PaymentRecord.objects.count(), 0) self.assertEqual(len(mail.outbox), self.original_outbox_length)
class TestBillingAutoPay(BaseInvoiceTestCase): @classmethod def setUpClass(cls): super(TestBillingAutoPay, cls).setUpClass() cls._generate_autopayable_entities() cls._generate_non_autopayable_entities() cls._generate_invoices() @classmethod def tearDownClass(cls): cls.non_autopay_domain.delete() super(TestBillingAutoPay, cls).tearDownClass() @classmethod def _generate_autopayable_entities(cls): """ Create account, domain and subscription linked to the autopay user that have autopay enabled """ cls.autopay_account = cls.account cls.autopay_account.created_by_domain = cls.domain cls.autopay_account.save() cls.autopay_user_email = generator.create_arbitrary_web_user_name() cls.fake_card = FakeStripeCard() cls.fake_stripe_customer = FakeStripeCustomer(cards=[cls.fake_card]) cls.autopay_account.update_autopay_user(cls.autopay_user_email, cls.domain) @classmethod def _generate_non_autopayable_entities(cls): """ Create account, domain, and subscription linked to the autopay user, but that don't have autopay enabled """ cls.non_autopay_account = generator.billing_account( web_user_creator=generator.create_arbitrary_web_user_name(is_dimagi=True), web_user_contact=cls.autopay_user_email ) cls.non_autopay_domain = generator.arbitrary_domain() # Non-autopay subscription has same parameters as the autopayable subscription cheap_plan = SoftwarePlan.objects.create(name='cheap') cheap_product_rate = SoftwareProductRate.objects.create(monthly_fee=100, name=cheap_plan.name) cheap_plan_version = SoftwarePlanVersion.objects.create( plan=cheap_plan, product_rate=cheap_product_rate, role=Role.objects.first(), ) cls.non_autopay_subscription = generator.generate_domain_subscription( cls.non_autopay_account, cls.non_autopay_domain, plan_version=cheap_plan_version, date_start=cls.subscription.date_start, date_end=add_months_to_date(cls.subscription.date_start, cls.subscription_length), ) @classmethod def _generate_invoices(cls): """ Create invoices for both autopayable and non-autopayable subscriptions """ # invoice date is 2 months before the end of the subscription (this is arbitrary) invoice_date = utils.months_from_date(cls.subscription.date_start, cls.subscription_length - 2) tasks.generate_invoices(invoice_date) @mock.patch.object(StripePaymentMethod, 'customer') def test_get_autopayable_invoices(self, fake_customer): """ Invoice.autopayable_invoices() should return invoices that can be automatically paid """ self._create_autopay_method(fake_customer) autopayable_invoice = Invoice.objects.filter(subscription=self.subscription) date_due = autopayable_invoice.first().date_due autopayable_invoices = Invoice.autopayable_invoices(date_due) self.assertItemsEqual(autopayable_invoices, autopayable_invoice) def test_get_autopayable_invoices_returns_nothing(self): """ Invoice.autopayable_invoices() should not return invoices if the customer does not have an autopay method """ not_autopayable_invoice = Invoice.objects.filter(subscription=self.non_autopay_subscription) date_due = not_autopayable_invoice.first().date_due autopayable_invoices = Invoice.autopayable_invoices(date_due) self.assertItemsEqual(autopayable_invoices, []) @mock.patch.object(StripePaymentMethod, 'customer') @mock.patch.object(Charge, 'create') def test_pay_autopayable_invoices(self, fake_charge, fake_customer): self._create_autopay_method(fake_customer) fake_charge.return_value = StripeObject(id='transaction_id') original_outbox_length = len(mail.outbox) autopayable_invoice = Invoice.objects.filter(subscription=self.subscription) date_due = autopayable_invoice.first().date_due AutoPayInvoicePaymentHandler().pay_autopayable_invoices(date_due) self.assertAlmostEqual(autopayable_invoice.first().get_total(), 0) self.assertEqual(len(PaymentRecord.objects.all()), 1) self.assertEqual(len(mail.outbox), original_outbox_length + 1) def _create_autopay_method(self, fake_customer): fake_customer.__get__ = mock.Mock(return_value=self.fake_stripe_customer) self.payment_method = StripePaymentMethod(web_user=self.autopay_user_email, customer_id=self.fake_stripe_customer.id) self.payment_method.set_autopay(self.fake_card, self.autopay_account, self.domain) self.payment_method.save() @mock.patch.object(StripePaymentMethod, 'customer') @mock.patch.object(Charge, 'create') @mock.patch.object(PaymentRecord, 'create_record') def test_when_create_record_fails_stripe_is_not_charged(self, fake_create_record, fake_create, fake_customer): fake_create_record.side_effect = Exception self._create_autopay_method(fake_customer) self.original_outbox_length = len(mail.outbox) self._run_autopay() self.assertFalse(fake_create.called) self._assert_no_side_effects() @mock.patch.object(StripePaymentMethod, 'customer') @mock.patch.object(Charge, 'create') def test_when_stripe_fails_no_payment_record_exists(self, fake_create, fake_customer): fake_create.side_effect = Exception self._create_autopay_method(fake_customer) self.original_outbox_length = len(mail.outbox) self._run_autopay() self._assert_no_side_effects() def _run_autopay(self): autopayable_invoice = Invoice.objects.filter(subscription=self.subscription) date_due = autopayable_invoice.first().date_due AutoPayInvoicePaymentHandler().pay_autopayable_invoices(date_due) def _assert_no_side_effects(self): self.assertEqual(PaymentRecord.objects.count(), 0) self.assertEqual(len(mail.outbox), self.original_outbox_length)