Added based view test, Added billing address form test, payment view test , Added test for hetzner pricing calculation, Added test for bern pricing calculation, Fixed script to load initial pricing data

This commit is contained in:
Levi 2016-05-12 01:57:34 -05:00
parent 36de71441a
commit bf17e80df4
11 changed files with 360 additions and 19 deletions

View file

@ -10,8 +10,8 @@ class Command(BaseCommand):
hetzner = { hetzner = {
'base_price': 10, 'base_price': 10,
'core_price': 10, 'core_price': 10,
'memory_price': 10, 'memory_price': 5,
'disk_size_price': 10, 'disk_size_price': 1,
'description': 'VM auf einzelner HW, Raid1, kein HA' 'description': 'VM auf einzelner HW, Raid1, kein HA'
} }

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2016-05-12 04:48
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('hosting', '0014_auto_20160505_0541'),
]
operations = [
migrations.RenameField(
model_name='hostingorder',
old_name='VMPlan',
new_name='vm_plan',
),
]

View file

@ -106,7 +106,7 @@ class HostingOrder(models.Model):
ORDER_APPROVED_STATUS = 'Approved' ORDER_APPROVED_STATUS = 'Approved'
ORDER_DECLINED_STATUS = 'Declined' ORDER_DECLINED_STATUS = 'Declined'
VMPlan = models.ForeignKey(VirtualMachinePlan, related_name='hosting_orders') vm_plan = models.ForeignKey(VirtualMachinePlan, related_name='hosting_orders')
customer = models.ForeignKey(StripeCustomer) customer = models.ForeignKey(StripeCustomer)
billing_address = models.ForeignKey(BillingAddress) billing_address = models.ForeignKey(BillingAddress)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
@ -120,8 +120,8 @@ class HostingOrder(models.Model):
return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
@classmethod @classmethod
def create(cls, VMPlan=None, customer=None, billing_address=None): def create(cls, vm_plan=None, customer=None, billing_address=None):
instance = cls.objects.create(VMPlan=VMPlan, customer=customer, instance = cls.objects.create(vm_plan=vm_plan, customer=customer,
billing_address=billing_address) billing_address=billing_address)
return instance return instance

View file

@ -48,15 +48,15 @@
<h3><b>Order summary</b></h3> <h3><b>Order summary</b></h3>
<hr> <hr>
<div class="content"> <div class="content">
<p><b>Type</b> <span class="pull-right">{{object.VMPlan.hosting_company_name}}</span></p> <p><b>Type</b> <span class="pull-right">{{object.vm_plan.hosting_company_name}}</span></p>
<hr> <hr>
<p><b>Cores</b> <span class="pull-right">{{object.VMPlan.cores}}</span></p> <p><b>Cores</b> <span class="pull-right">{{object.vm_plan.cores}}</span></p>
<hr> <hr>
<p><b>Memory</b> <span class="pull-right">{{object.VMPlan.memory}} GiB</span></p> <p><b>Memory</b> <span class="pull-right">{{object.vm_plan.memory}} GiB</span></p>
<hr> <hr>
<p><b>Disk space</b> <span class="pull-right">{{object.VMPlan.disk_size}} GiB</span></p> <p><b>Disk space</b> <span class="pull-right">{{object.vm_plan.disk_size}} GiB</span></p>
<hr> <hr>
<h4>Total<p class="pull-right"><b>{{object.VMPlan.price}} CHF</b></p></h4> <h4>Total<p class="pull-right"><b>{{object.vm_plan.price}} CHF</b></p></h4>
</div> </div>
</div> </div>
</div> </div>

View file

@ -23,7 +23,7 @@
<tr> <tr>
<td scope="row">{{order.id}}</td> <td scope="row">{{order.id}}</td>
<td>{{order.created_at}}</td> <td>{{order.created_at}}</td>
<td>{{order.VMPlan.price}} CHF</td> <td>{{order.vm_plan.price}} CHF</td>
<td>{% if order.approved %} <td>{% if order.approved %}
<span class="text-success strong">Approved</span> <span class="text-success strong">Approved</span>
{% else%} {% else%}

View file

@ -104,7 +104,7 @@
<tr> <tr>
<td scope="row">{{order.id}}</td> <td scope="row">{{order.id}}</td>
<td>{{order.created_at}}</td> <td>{{order.created_at}}</td>
<td>{{order.VMPlan.price}} CHF</td> <td>{{order.vm_plan.price}} CHF</td>
<td>{% if order.approved %} <td>{% if order.approved %}
<span class="text-success strong">Approved</span> <span class="text-success strong">Approved</span>
{% else%} {% else%}

75
hosting/test_models.py Normal file
View file

@ -0,0 +1,75 @@
from django.test import TestCase
from model_mommy import mommy
from django.core.management import call_command
from .models import VirtualMachineType
class VirtualMachineTypeModelTest(TestCase):
def setUp(self):
self.HETZNER_NUG_NAME = 'hetzner_nug'
self.HETZNER_NAME = 'hetzner'
self.HETZNER_RAID6_NAME = 'hetzner_raid6'
self.HETZNER_GLUSTERFS_NAME = 'hetzner_glusterfs'
self.BERN_NAME = 'bern'
self.HETZNER_NUG_EXPECTED_PRICE = 79
self.HETZNER_EXPECTED_PRICE = 180
self.HETZNER_RAID6_EXPECTED_PRICE = 216
self.HETZNER_GLUSTERFS_EXPECTED_PRICE = 252
self.BERN_EXPECTED_PRICE = 202
call_command('create_vm_types')
def test_calculate_price(self):
# hetzner_nug
specifications = {
'cores': 2,
'memory': 10,
'disk_size': 100
}
vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NUG_NAME)
calculated_price = vm_type.calculate_price(specifications)
self.assertEqual(calculated_price, self.HETZNER_NUG_EXPECTED_PRICE)
# hetzner
specifications = {
'cores': 2,
'memory': 10,
'disk_size': 100
}
vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NAME)
calculated_price = vm_type.calculate_price(specifications)
self.assertEqual(calculated_price, self.HETZNER_EXPECTED_PRICE)
# hetzner_raid6
specifications = {
'cores': 2,
'memory': 10,
'disk_size': 100
}
vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_RAID6_NAME)
calculated_price = vm_type.calculate_price(specifications)
self.assertEqual(calculated_price, self.HETZNER_RAID6_EXPECTED_PRICE)
# hetzner_glusterfs
specifications = {
'cores': 2,
'memory': 10,
'disk_size': 100
}
vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_GLUSTERFS_NAME)
calculated_price = vm_type.calculate_price(specifications)
self.assertEqual(calculated_price, self.HETZNER_GLUSTERFS_EXPECTED_PRICE)
# bern
specifications = {
'cores': 2,
'memory': 10,
'disk_size': 100
}
vm_type = VirtualMachineType.objects.get(hosting_company=self.BERN_NAME)
calculated_price = vm_type.calculate_price(specifications)
self.assertEqual(calculated_price, self.BERN_EXPECTED_PRICE)

View file

@ -1,8 +1,17 @@
from django.test import TestCase from unittest import mock
from django.conf import settings
from django.test import TestCase, RequestFactory
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.urlresolvers import resolve from django.core.urlresolvers import resolve
from .models import VirtualMachineType
from .views import DjangoHostingView, RailsHostingView, NodeJSHostingView from model_mommy import mommy
from membership.models import CustomUser, StripeCustomer
from .models import VirtualMachineType, HostingOrder
from .views import DjangoHostingView, RailsHostingView, NodeJSHostingView, LoginView, SignupView,\
PaymentVMView
from utils.tests import BaseTestCase
class ProcessVMSelectionTestMixin(object): class ProcessVMSelectionTestMixin(object):
@ -70,3 +79,152 @@ class NodeJSHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
'email': "info@node-hosting.ch", 'email': "info@node-hosting.ch",
'vm_types': VirtualMachineType.get_serialized_vm_types(), 'vm_types': VirtualMachineType.get_serialized_vm_types(),
} }
class PaymentVMViewTest(BaseTestCase):
def setUp(self):
super(PaymentVMViewTest, self).setUp()
self.view = PaymentVMView
# VM
self.vm = mommy.make(VirtualMachineType, base_price=10000,
memory_price=100,
core_price=1000,
disk_size_price=1)
# post data
self.billing_address = {
'street_address': 'street name',
'city': 'MyCity',
'postal_code': '32123123123123',
'country': 'VE',
'token': 'a23kfmslwxhkwis'
}
# urls
self.url = reverse('hosting:payment')
# Session data
self.session_data = {
'vm_specs': {
'hosting_company': self.vm.hosting_company,
'cores': 1,
'memory': 10,
'disk_size': 10000,
'price': 22000,
}
}
session = self.customer_client.session
session.update(self.session_data)
session.save()
def test_url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
@mock.patch('utils.stripe_utils.StripeUtils.create_customer')
def test_post(self, stripe_mocked_call):
# Anonymous user should get redirect to login
response = self.client.post(self.url)
expected_url = "%s?next=%s" % (reverse('hosting:login'), reverse('hosting:payment'))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Customer user should be able to pay
stripe_mocked_call.return_value = {
'paid': True,
'response_object': self.stripe_mocked_customer,
'error': None
}
response = self.customer_client.post(self.url, self.billing_address)
self.assertEqual(response.status_code, 200)
self.assertTrue(StripeCustomer.objects.filter(user__email=self.customer.email).exists())
stripe_customer = StripeCustomer.objects.get(user__email=self.customer.email)
self.assertEqual(stripe_customer.user, self.customer)
self.assertTrue(HostingOrder.objects.filter(customer=stripe_customer).exists())
hosting_order = HostingOrder.objects.filter(customer=stripe_customer)[0]
vm_plan = {
'cores': hosting_order.vm_plan.cores,
'memory': hosting_order.vm_plan.memory,
'disk_size': hosting_order.vm_plan.disk_size,
'price': hosting_order.vm_plan.price,
'hosting_company': hosting_order.vm_plan.vm_type.hosting_company
}
self.assertEqual(vm_plan, self.session_data.get('vm_specs'))
def test_get(self):
# Anonymous user should get redirect to login
response = self.client.get(self.url)
expected_url = "%s?next=%s" % (reverse('hosting:login'), reverse('hosting:payment'))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Logged user should get the page
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['stripe_key'],
settings.STRIPE_API_PUBLIC_KEY)
class LoginViewTest(TestCase):
def setUp(self):
self.url = reverse('hosting:login')
self.view = LoginView
self.expected_template = 'hosting/login.html'
self.user = mommy.make('membership.CustomUser')
self.password = 'fake_password'
self.user.set_password(self.password)
self.user.save()
def test_url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
def test_get(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, self.expected_template)
def test_anonymous_user_can_login(self):
data = {
'email': self.user.email,
'password': self.password
}
response = self.client.post(self.url, data=data, follow=True)
self.assertEqual(response.context['user'], self.user)
self.assertEqual(response.status_code, 200)
class SignupViewTest(TestCase):
def setUp(self):
self.url = reverse('hosting:signup')
self.expected_template = 'hosting/signup.html'
self.view = SignupView
self.signup_data = {
'name': 'ungleich',
'email': 'test@ungleich.com',
'password': 'fake_password',
'confirm_password': 'fake_password',
}
def test_url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
def test_get(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, self.expected_template)
def test_anonymous_user_can_signup(self):
response = self.client.post(self.url, data=self.signup_data, follow=True)
self.user = CustomUser.objects.get(email=self.signup_data.get('email'))
self.assertEqual(response.context['user'], self.user)
self.assertEqual(response.status_code, 200)

View file

@ -143,8 +143,9 @@ class SignupView(CreateView):
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())
class PaymentVMView(FormView): class PaymentVMView(LoginRequiredMixin, FormView):
template_name = 'hosting/payment.html' template_name = 'hosting/payment.html'
login_url = reverse_lazy('hosting:login')
form_class = BillingAddressForm form_class = BillingAddressForm
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -183,7 +184,7 @@ class PaymentVMView(FormView):
billing_address = form.save() billing_address = form.save()
# Create a Hosting Order # Create a Hosting Order
order = HostingOrder.create(VMPlan=plan, customer=customer, order = HostingOrder.create(vm_plan=plan, customer=customer,
billing_address=billing_address) billing_address=billing_address)
# Make stripe charge to a customer # Make stripe charge to a customer

View file

@ -1,5 +1,5 @@
from django.test import TestCase from django.test import TestCase
from .forms import ContactUsForm from .forms import ContactUsForm, BillingAddressForm
class ContactUsFormTest(TestCase): class ContactUsFormTest(TestCase):
@ -23,3 +23,27 @@ class ContactUsFormTest(TestCase):
def test_invalid_form(self): def test_invalid_form(self):
form = ContactUsForm(data=self.incompleted_data) form = ContactUsForm(data=self.incompleted_data)
self.assertFalse(form.is_valid()) self.assertFalse(form.is_valid())
class BillingAddressFormTest(TestCase):
def setUp(self):
self.completed_data = {
'street_address': 'street name',
'city': 'MyCity',
'postal_code': '32123123123123',
'country': 'VE',
'token': 'a23kfmslwxhkwis'
}
self.incompleted_data = {
'street_address': 'test',
}
def test_valid_form(self):
form = BillingAddressForm(data=self.completed_data)
self.assertTrue(form.is_valid())
def test_invalid_form(self):
form = BillingAddressForm(data=self.incompleted_data)
self.assertFalse(form.is_valid())

View file

@ -1,3 +1,66 @@
from django.test import TestCase from django.test import TestCase
from django.test import Client
from model_mommy import mommy
# Create your tests here.
class BaseTestCase(TestCase):
"""
Base class to initialize the test cases
"""
def setUp(self):
# Password
self.dummy_password = 'test_password'
# Users
self.customer, self.another_customer = mommy.make('membership.CustomUser',
_quantity=2)
self.customer.set_password(self.dummy_password)
self.customer.save()
self.another_customer.set_password(self.dummy_password)
self.another_customer.save()
# Stripe mocked data
self.stripe_mocked_customer = self.customer_stripe_mocked_data()
# Clients
self.customer_client = self.get_client(self.customer)
self.another_customer_client = self.get_client(self.another_customer)
def get_client(self, user):
"""
Authenticate a user and return the client
"""
client = Client()
client.login(email=user.email, password=self.dummy_password)
return client
def customer_stripe_mocked_data(self):
return {
"id": "cus_8R1y9UWaIIjZqr",
"object": "customer",
"currency": "usd",
"default_source": "card_18A9up2eZvKYlo2Cq2RJMGeF",
"email": "vmedixtodd+1@gmail.com",
"livemode": False,
"metadata": {
},
"shipping": None,
"sources": {
"object": "list",
"data": [{
"id": "card_18A9up2eZvKYlo2Cq2RJMGeF",
"object": "card",
"brand": "Visa",
"country": "US",
"customer": "cus_8R1y9UWaIIjZqr",
"cvc_check": "pass",
"dynamic_last4": None,
"exp_month": 12,
"exp_year": 2018,
"funding": "credit",
"last4": "4242",
}]
}
}