forked from uncloud/uncloud
		
	
		
			
				
	
	
		
			169 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
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 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')
 | 
						|
        ending_date   = datetime.fromisoformat('2020-05-08')
 | 
						|
 | 
						|
        # Create order to be billed.
 | 
						|
        order = Order.objects.create(
 | 
						|
                owner=self.user,
 | 
						|
                starting_date=starting_date,
 | 
						|
                ending_date=ending_date,
 | 
						|
                recurring_period=RecurringPeriod.PER_MONTH,
 | 
						|
                billing_address=self.billing_address)
 | 
						|
        order.add_record(one_time_price, recurring_price, description)
 | 
						|
 | 
						|
        # Generate & check bill for first month: full recurring_price + setup.
 | 
						|
        first_month_bills = order.bills # Initial bill generated at order creation.
 | 
						|
        self.assertEqual(len(first_month_bills), 1)
 | 
						|
        self.assertEqual(first_month_bills[0].total, 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].total, 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].total),
 | 
						|
                round((7/31) * 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_YEAR,
 | 
						|
                billing_address=self.billing_address)
 | 
						|
        order.add_record(one_time_price, recurring_price, description)
 | 
						|
 | 
						|
        # Generate & check bill for first year: recurring_price + setup.
 | 
						|
        first_year_bills = order.bills # Initial bill generated at order creation.
 | 
						|
        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].total,
 | 
						|
                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].total, 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,
 | 
						|
                billing_address=self.billing_address)
 | 
						|
        order.add_record(one_time_price, recurring_price, description)
 | 
						|
 | 
						|
        # Generate & check bill for first month: recurring_price + setup.
 | 
						|
        first_month_bills = order.bills
 | 
						|
        self.assertEqual(len(first_month_bills), 1)
 | 
						|
        self.assertEqual(float(first_month_bills[0].total),
 | 
						|
                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].total),
 | 
						|
                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')
 | 
						|
 | 
						|
        order = Order.objects.create(
 | 
						|
                owner=self.user,
 | 
						|
                starting_date=starting_date,
 | 
						|
                recurring_period=RecurringPeriod.PER_MONTH,
 | 
						|
                billing_address=self.billing_address)
 | 
						|
        order.save()
 | 
						|
 | 
						|
        product = GenericServiceProduct(
 | 
						|
                custom_description="Test product",
 | 
						|
                custom_one_time_price=0,
 | 
						|
                custom_recurring_price=20,
 | 
						|
                owner=self.user,
 | 
						|
                order=order)
 | 
						|
        product.save()
 | 
						|
 | 
						|
        # XXX: to be automated.
 | 
						|
        order.add_record(product.one_time_price, product.recurring_price(), product.description)
 | 
						|
 | 
						|
        # Validate initial state: must be awaiting payment.
 | 
						|
        self.assertEqual(product.status, UncloudStatus.AWAITING_PAYMENT)
 | 
						|
 | 
						|
        # Pay initial bill, check that product is activated.
 | 
						|
        amount = product.order.bills[0].total
 | 
						|
        payment = Payment(owner=self.user, amount=amount)
 | 
						|
        payment.save()
 | 
						|
        self.assertEqual(
 | 
						|
                GenericServiceProduct.objects.get(uuid=product.uuid).status,
 | 
						|
                UncloudStatus.PENDING
 | 
						|
                )
 |