2020-02-21 15:33:37 +00:00
|
|
|
from django.test import TestCase
|
2020-03-09 10:30:11 +00:00
|
|
|
from django.contrib.auth import get_user_model
|
|
|
|
from datetime import datetime, date, timedelta
|
2020-02-21 15:33:37 +00:00
|
|
|
|
2020-03-09 10:30:11 +00:00
|
|
|
from .models import *
|
2020-04-18 07:02:33 +00:00
|
|
|
from uncloud_service.models import GenericServiceProduct
|
2020-03-09 10:30:11 +00:00
|
|
|
|
|
|
|
class BillingTestCase(TestCase):
|
2020-03-06 08:02:25 +00:00
|
|
|
def setUp(self):
|
2020-03-09 10:30:11 +00:00
|
|
|
self.user = get_user_model().objects.create(
|
|
|
|
username='jdoe',
|
|
|
|
email='john.doe@domain.tld')
|
2020-04-18 07:26:34 +00:00
|
|
|
self.billing_address = BillingAddress.objects.create(
|
|
|
|
owner=self.user,
|
|
|
|
street="unknown",
|
|
|
|
city="unknown",
|
|
|
|
postal_code="unknown")
|
2020-03-06 08:02:25 +00:00
|
|
|
|
2020-03-09 10:30:11 +00:00
|
|
|
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,
|
2020-04-18 07:26:34 +00:00
|
|
|
recurring_period=RecurringPeriod.PER_MONTH,
|
|
|
|
billing_address=self.billing_address)
|
2020-03-09 10:30:11 +00:00
|
|
|
order.add_record(one_time_price, recurring_price, description)
|
|
|
|
|
|
|
|
# Generate & check bill for first month: full recurring_price + setup.
|
2020-04-17 07:15:52 +00:00
|
|
|
first_month_bills = order.bills # Initial bill generated at order creation.
|
2020-03-09 10:30:11 +00:00
|
|
|
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,
|
2020-04-18 07:26:34 +00:00
|
|
|
recurring_period=RecurringPeriod.PER_YEAR,
|
|
|
|
billing_address=self.billing_address)
|
2020-03-09 10:30:11 +00:00
|
|
|
order.add_record(one_time_price, recurring_price, description)
|
|
|
|
|
|
|
|
# Generate & check bill for first year: recurring_price + setup.
|
2020-04-17 07:15:52 +00:00
|
|
|
first_year_bills = order.bills # Initial bill generated at order creation.
|
2020-03-09 10:30:11 +00:00
|
|
|
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,
|
2020-04-18 07:26:34 +00:00
|
|
|
recurring_period=RecurringPeriod.PER_HOUR,
|
|
|
|
billing_address=self.billing_address)
|
2020-03-09 10:30:11 +00:00
|
|
|
order.add_record(one_time_price, recurring_price, description)
|
|
|
|
|
|
|
|
# Generate & check bill for first month: recurring_price + setup.
|
2020-04-17 07:15:52 +00:00
|
|
|
first_month_bills = order.bills
|
2020-03-09 10:30:11 +00:00
|
|
|
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))
|
2020-04-17 08:09:28 +00:00
|
|
|
|
|
|
|
class ProductActivationTestCase(TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.user = get_user_model().objects.create(
|
|
|
|
username='jdoe',
|
|
|
|
email='john.doe@domain.tld')
|
|
|
|
|
2020-04-18 07:26:34 +00:00
|
|
|
self.billing_address = BillingAddress.objects.create(
|
|
|
|
owner=self.user,
|
|
|
|
street="unknown",
|
|
|
|
city="unknown",
|
|
|
|
postal_code="unknown")
|
|
|
|
|
2020-04-17 08:09:28 +00:00
|
|
|
def test_product_activation(self):
|
|
|
|
starting_date = datetime.fromisoformat('2020-03-01')
|
|
|
|
|
|
|
|
order = Order.objects.create(
|
|
|
|
owner=self.user,
|
|
|
|
starting_date=starting_date,
|
2020-04-18 07:26:34 +00:00
|
|
|
recurring_period=RecurringPeriod.PER_MONTH,
|
|
|
|
billing_address=self.billing_address)
|
2020-04-17 08:09:28 +00:00
|
|
|
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.
|
2020-04-18 07:02:33 +00:00
|
|
|
order.add_record(product.one_time_price, product.recurring_price(), product.description)
|
2020-04-17 08:09:28 +00:00
|
|
|
|
|
|
|
# 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
|
|
|
|
)
|