Merge pull request #72 from ungleich/develop

Update develop from master because of the hotfix for blog posts
This commit is contained in:
tmslav 2016-05-17 02:04:25 +02:00
commit ac51ce9290
15 changed files with 528 additions and 39 deletions

View file

@ -1,6 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import RailsBetaUser, VirtualMachineType from .models import VirtualMachineType
admin.site.register(RailsBetaUser)
admin.site.register(VirtualMachineType) admin.site.register(VirtualMachineType)

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

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2016-05-14 06:50
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('hosting', '0015_auto_20160512_0448'),
]
operations = [
migrations.DeleteModel(
name='RailsBetaUser',
),
]

View file

@ -10,14 +10,6 @@ from utils.models import BillingAddress
from .managers import VMPlansManager from .managers import VMPlansManager
class RailsBetaUser(models.Model):
email = models.EmailField(unique=True)
received_date = models.DateTimeField('date received')
def __str__(self):
return "%s - %s" % (self.email, self.received_date)
class VirtualMachineType(models.Model): class VirtualMachineType(models.Model):
HETZNER_NUG = 'hetzner_nug' HETZNER_NUG = 'hetzner_nug'
@ -86,6 +78,9 @@ class VirtualMachinePlan(models.Model):
objects = VMPlansManager() objects = VMPlansManager()
def __str__(self):
return "%s" % (self.id)
@cached_property @cached_property
def hosting_company_name(self): def hosting_company_name(self):
return self.vm_type.get_hosting_company_display() return self.vm_type.get_hosting_company_display()
@ -106,7 +101,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)
@ -115,13 +110,16 @@ class HostingOrder(models.Model):
cc_brand = models.CharField(max_length=10) cc_brand = models.CharField(max_length=10)
stripe_charge_id = models.CharField(max_length=100, null=True) stripe_charge_id = models.CharField(max_length=100, null=True)
def __str__(self):
return "%s" % (self.id)
@cached_property @cached_property
def status(self): def status(self):
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

@ -6,7 +6,7 @@
<div class="row"> <div class="row">
<div class="col-xs-8 col-xs-offset-2"> <div class="col-xs-8 col-xs-offset-2">
<div class="invoice-title"> <div class="invoice-title">
<h2>Invoice</h2><h3 class="pull-right">Order # {{object.id}}</h3> <h2>Invoice</h2><h3 class="pull-right">Order # {{order.id}}</h3>
</div> </div>
<hr> <hr>
<div class="row"> <div class="row">
@ -14,18 +14,18 @@
<address> <address>
<h3><b>Billed To:</b></h3> <h3><b>Billed To:</b></h3>
{{user.name}}<br> {{user.name}}<br>
{{object.billing_address.street_address}},{{order.billing_address.postal_code}}<br> {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br>
{{object.billing_address.city}}, {{object.billing_address.country}}. {{order.billing_address.city}}, {{order.billing_address.country}}.
</address> </address>
</div> </div>
<div class="col-xs-6 text-right"> <div class="col-xs-6 text-right">
<address> <address>
<strong>Order Date:</strong><br> <strong>Order Date:</strong><br>
{{object.created_at}}<br><br> {{order.created_at}}<br><br>
<strong>Status:</strong><br> <strong>Status:</strong><br>
<strong class="{% if object.status == 'Approved' %}text-success <strong class="{% if order.status == 'Approved' %}text-success
{%else%} text-danger {%else%} text-danger
{% endif %}">{{object.status}}</strong> {% endif %}">{{order.status}}</strong>
<br><br> <br><br>
</address> </address>
@ -35,7 +35,7 @@
<div class="col-xs-6"> <div class="col-xs-6">
<address> <address>
<strong>Payment Method:</strong><br> <strong>Payment Method:</strong><br>
{{object.cc_brand}} ending **** {{object.last4}}<br> {{order.cc_brand}} ending **** {{order.last4}}<br>
{{user.email}} {{user.email}}
</address> </address>
</div> </div>
@ -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">{{order.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">{{order.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">{{order.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">{{order.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>{{order.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 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,18 @@
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, VirtualMachinePlan
from .views import DjangoHostingView, RailsHostingView, NodeJSHostingView, LoginView, SignupView, \
PaymentVMView, OrdersHostingDetailView, OrdersHostingListView, VirtualMachineDetailView, \
VirtualMachinesPlanListView
from utils.tests import BaseTestCase
class ProcessVMSelectionTestMixin(object): class ProcessVMSelectionTestMixin(object):
@ -70,3 +80,280 @@ 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 VirtualMachineDetailViewTest(BaseTestCase):
def setUp(self):
super(VirtualMachineDetailViewTest, self).setUp()
self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
self.vm = mommy.make(VirtualMachinePlan)
self.order = mommy.make(HostingOrder, customer=self.stripe_customer, vm_plan=self.vm)
self.url = reverse('hosting:virtual_machines', kwargs={'pk': self.vm.id})
self.view = VirtualMachineDetailView()
self.expected_template = 'hosting/virtual_machine_detail.html'
def url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
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:virtual_machines',
kwargs={'pk': self.vm.id}))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Customer should be able to get data
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['virtual_machine'], self.vm)
self.assertTemplateUsed(response, self.expected_template)
class VirtualMachinesPlanListViewTest(BaseTestCase):
def setUp(self):
super(VirtualMachinesPlanListViewTest, self).setUp()
self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
mommy.make(HostingOrder, customer=self.stripe_customer, approved=True, _quantity=20)
_vms = VirtualMachinePlan.objects.all()
self.vms = sorted(_vms, key=lambda vm: vm.id, reverse=True)
self.url = reverse('hosting:virtual_machines')
self.view = VirtualMachinesPlanListView()
self.expected_template = 'hosting/virtual_machines.html'
def url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
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:virtual_machines'))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Customer should be able to get his orders
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(list(response.context['vms']), self.vms[:10])
self.assertTemplateUsed(response, self.expected_template)
class OrderHostingDetailViewTest(BaseTestCase):
def setUp(self):
super(OrderHostingDetailViewTest, self).setUp()
self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
self.order = mommy.make(HostingOrder, customer=self.stripe_customer)
self.url = reverse('hosting:orders', kwargs={'pk': self.order.id})
self.view = OrdersHostingDetailView()
self.expected_template = 'hosting/order_detail.html'
def url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
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:orders', kwargs={'pk': self.order.id}))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Customer should be able to get data
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['order'], self.order)
self.assertTemplateUsed(response, self.expected_template)
class OrdersHostingListViewTest(BaseTestCase):
def setUp(self):
super(OrdersHostingListViewTest, self).setUp()
self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
_orders = mommy.make(HostingOrder, customer=self.stripe_customer, _quantity=20)
self.orders = sorted(_orders, key=lambda order: order.id, reverse=True)
self.url = reverse('hosting:orders')
self.view = OrdersHostingListView()
self.expected_template = 'hosting/orders.html'
def url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
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:orders'))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Customer should be able to get his orders
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(list(response.context['orders']), self.orders[:10])
self.assertTemplateUsed(response, self.expected_template)
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

@ -3,7 +3,7 @@ from django.conf.urls import url
from .views import DjangoHostingView, RailsHostingView, PaymentVMView, \ from .views import DjangoHostingView, RailsHostingView, PaymentVMView, \
NodeJSHostingView, LoginView, SignupView, IndexView, \ NodeJSHostingView, LoginView, SignupView, IndexView, \
OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\ OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\
VirtualMachineDetailListView VirtualMachineDetailView
urlpatterns = [ urlpatterns = [
# url(r'pricing/?$', VMPricingView.as_view(), name='pricing'), # url(r'pricing/?$', VMPricingView.as_view(), name='pricing'),
@ -15,7 +15,7 @@ urlpatterns = [
url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'), url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'),
url(r'orders/(?P<pk>\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'), url(r'orders/(?P<pk>\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'),
url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'), url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'),
url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineDetailListView.as_view(), url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineDetailView.as_view(),
name='virtual_machines'), name='virtual_machines'),
url(r'login/?$', LoginView.as_view(), name='login'), url(r'login/?$', LoginView.as_view(), name='login'),
url(r'signup/?$', SignupView.as_view(), name='signup'), url(r'signup/?$', SignupView.as_view(), name='signup'),

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
@ -219,6 +220,7 @@ class PaymentVMView(FormView):
class OrdersHostingDetailView(LoginRequiredMixin, DetailView): class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
template_name = "hosting/order_detail.html" template_name = "hosting/order_detail.html"
context_object_name = "order"
login_url = reverse_lazy('hosting:login') login_url = reverse_lazy('hosting:login')
model = HostingOrder model = HostingOrder
@ -229,6 +231,7 @@ class OrdersHostingListView(LoginRequiredMixin, ListView):
context_object_name = "orders" context_object_name = "orders"
model = HostingOrder model = HostingOrder
paginate_by = 10 paginate_by = 10
ordering = '-id'
def get_queryset(self): def get_queryset(self):
user = self.request.user user = self.request.user
@ -242,6 +245,7 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
context_object_name = "vms" context_object_name = "vms"
model = VirtualMachinePlan model = VirtualMachinePlan
paginate_by = 10 paginate_by = 10
ordering = '-id'
def get_queryset(self): def get_queryset(self):
user = self.request.user user = self.request.user
@ -249,7 +253,7 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
return super(VirtualMachinesPlanListView, self).get_queryset() return super(VirtualMachinesPlanListView, self).get_queryset()
class VirtualMachineDetailListView(LoginRequiredMixin, DetailView): class VirtualMachineDetailView(LoginRequiredMixin, DetailView):
template_name = "hosting/virtual_machine_detail.html" template_name = "hosting/virtual_machine_detail.html"
login_url = reverse_lazy('hosting:login') login_url = reverse_lazy('hosting:login')
model = VirtualMachinePlan model = VirtualMachinePlan

View file

@ -16,6 +16,7 @@ psycopg2
django-mptt django-mptt
easy_thumbnails easy_thumbnails
django-polymorphic django-polymorphic
model-mommy
#PLUGINS #PLUGINS
djangocms_flash djangocms_flash

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",
}]
}
}