from django.test import TestCase from django.contrib.auth import get_user_model from datetime import datetime, date, timedelta from .models import * from uncloud_service.models import GenericServiceProduct class NotABillingTC(TestCase): #class BillingTestCase(TestCase): def setUp(self): self.user = get_user_model().objects.create( username='jdoe', email='john.doe@domain.tld') self.billing_address = BillingAddress.objects.create( owner=self.user, street="unknown", city="unknown", postal_code="unknown") def test_basic_monthly_billing(self): one_time_price = 10 recurring_price = 20 description = "Test Product 1" # Three months: full, full, partial. # starting_date = datetime.fromisoformat('2020-03-01') starting_date = datetime(2020,3,1) ending_date = datetime(2020,5,8) # Create order to be billed. order = Order.objects.create( owner=self.user, starting_date=starting_date, ending_date=ending_date, recurring_period=RecurringPeriod.PER_30D, recurring_price=recurring_price, one_time_price=one_time_price, description=description, billing_address=self.billing_address) # Generate & check bill for first month: full recurring_price + setup. first_month_bills = order.generate_initial_bill() self.assertEqual(len(first_month_bills), 1) self.assertEqual(first_month_bills[0].amount, one_time_price + recurring_price) # Generate & check bill for second month: full recurring_price. second_month_bills = Bill.generate_for(2020, 4, self.user) self.assertEqual(len(second_month_bills), 1) self.assertEqual(second_month_bills[0].amount, recurring_price) # Generate & check bill for third and last month: partial recurring_price. third_month_bills = Bill.generate_for(2020, 5, self.user) self.assertEqual(len(third_month_bills), 1) # 31 days in May. self.assertEqual(float(third_month_bills[0].amount), round(round((7/31), AMOUNT_DECIMALS) * recurring_price, AMOUNT_DECIMALS)) # Check that running Bill.generate_for() twice does not create duplicates. self.assertEqual(len(Bill.generate_for(2020, 3, self.user)), 0) def test_basic_yearly_billing(self): one_time_price = 10 recurring_price = 150 description = "Test Product 1" starting_date = datetime.fromisoformat('2020-03-31T08:05:23') # Create order to be billed. order = Order.objects.create( owner=self.user, starting_date=starting_date, recurring_period=RecurringPeriod.PER_365D, recurring_price=recurring_price, one_time_price=one_time_price, description=description, billing_address=self.billing_address) # Generate & check bill for first year: recurring_price + setup. first_year_bills = order.generate_initial_bill() self.assertEqual(len(first_year_bills), 1) self.assertEqual(first_year_bills[0].starting_date.date(), date.fromisoformat('2020-03-31')) self.assertEqual(first_year_bills[0].ending_date.date(), date.fromisoformat('2021-03-30')) self.assertEqual(first_year_bills[0].amount, recurring_price + one_time_price) # Generate & check bill for second year: recurring_price. second_year_bills = Bill.generate_for(2021, 3, self.user) self.assertEqual(len(second_year_bills), 1) self.assertEqual(second_year_bills[0].starting_date.date(), date.fromisoformat('2021-03-31')) self.assertEqual(second_year_bills[0].ending_date.date(), date.fromisoformat('2022-03-30')) self.assertEqual(second_year_bills[0].amount, recurring_price) # Check that running Bill.generate_for() twice does not create duplicates. self.assertEqual(len(Bill.generate_for(2020, 3, self.user)), 0) self.assertEqual(len(Bill.generate_for(2020, 4, self.user)), 0) self.assertEqual(len(Bill.generate_for(2020, 2, self.user)), 0) self.assertEqual(len(Bill.generate_for(2021, 3, self.user)), 0) def test_basic_hourly_billing(self): one_time_price = 10 recurring_price = 1.4 description = "Test Product 1" starting_date = datetime.fromisoformat('2020-03-31T08:05:23') ending_date = datetime.fromisoformat('2020-04-01T11:13:32') # Create order to be billed. order = Order.objects.create( owner=self.user, starting_date=starting_date, ending_date=ending_date, recurring_period=RecurringPeriod.PER_HOUR, recurring_price=recurring_price, one_time_price=one_time_price, description=description, billing_address=self.billing_address) # Generate & check bill for first month: recurring_price + setup. first_month_bills = order.generate_initial_bill() self.assertEqual(len(first_month_bills), 1) self.assertEqual(float(first_month_bills[0].amount), round(16 * recurring_price, AMOUNT_DECIMALS) + one_time_price) # Generate & check bill for first month: recurring_price. second_month_bills = Bill.generate_for(2020, 4, self.user) self.assertEqual(len(second_month_bills), 1) self.assertEqual(float(second_month_bills[0].amount), round(12 * recurring_price, AMOUNT_DECIMALS)) class ProductActivationTestCase(TestCase): def setUp(self): self.user = get_user_model().objects.create( username='jdoe', email='john.doe@domain.tld') self.billing_address = BillingAddress.objects.create( owner=self.user, street="unknown", city="unknown", postal_code="unknown") def test_product_activation(self): starting_date = datetime.fromisoformat('2020-03-01') one_time_price = 0 recurring_price = 1 description = "Test Product" order = Order.objects.create( owner=self.user, starting_date=starting_date, recurring_period=RecurringPeriod.PER_30D, recurring_price=recurring_price, one_time_price=one_time_price, description=description, billing_address=self.billing_address) product = GenericServiceProduct( custom_description=description, custom_one_time_price=one_time_price, custom_recurring_price=recurring_price, owner=self.user, order=order) product.save() # Validate initial state: must be awaiting payment. self.assertEqual(product.status, UncloudStatus.AWAITING_PAYMENT) # Pay initial bill, check that product is activated. order.generate_initial_bill() amount = product.order.bills[0].amount payment = Payment(owner=self.user, amount=amount) payment.save() self.assertEqual( GenericServiceProduct.objects.get(uuid=product.uuid).status, UncloudStatus.PENDING ) class BillingAddressTestCase(TestCase): def setUp(self): self.user = get_user_model().objects.create( username='jdoe', email='john.doe@domain.tld') self.billing_address_01 = BillingAddress.objects.create( owner=self.user, street="unknown1", city="unknown1", postal_code="unknown1", country="CH") self.billing_address_02 = BillingAddress.objects.create( owner=self.user, street="unknown2", city="unknown2", postal_code="unknown2", country="CH") def test_billing_with_single_address(self): # Create new orders somewhere in the past so that we do not encounter # auto-created initial bills. starting_date = datetime.fromisoformat('2020-03-01') order_01 = Order.objects.create( owner=self.user, starting_date=starting_date, recurring_period=RecurringPeriod.PER_30D, billing_address=self.billing_address_01) order_02 = Order.objects.create( owner=self.user, starting_date=starting_date, recurring_period=RecurringPeriod.PER_30D, billing_address=self.billing_address_01) # We need a single bill since we work with a single address. bills = Bill.generate_for(2020, 4, self.user) self.assertEqual(len(bills), 1) def test_billing_with_multiple_addresses(self): # Create new orders somewhere in the past so that we do not encounter # auto-created initial bills. starting_date = datetime.fromisoformat('2020-03-01') order_01 = Order.objects.create( owner=self.user, starting_date=starting_date, recurring_period=RecurringPeriod.PER_30D, billing_address=self.billing_address_01) order_02 = Order.objects.create( owner=self.user, starting_date=starting_date, recurring_period=RecurringPeriod.PER_30D, billing_address=self.billing_address_02) # We need different bills since we work with different addresses. bills = Bill.generate_for(2020, 4, self.user) self.assertEqual(len(bills), 2)