diff --git a/hosting/admin.py b/hosting/admin.py index 84067ff9..70392113 100644 --- a/hosting/admin.py +++ b/hosting/admin.py @@ -1,6 +1,5 @@ from django.contrib import admin -from .models import RailsBetaUser, VirtualMachineType +from .models import VirtualMachineType -admin.site.register(RailsBetaUser) admin.site.register(VirtualMachineType) diff --git a/hosting/management/commands/create_vm_types.py b/hosting/management/commands/create_vm_types.py index 23961bae..44995634 100644 --- a/hosting/management/commands/create_vm_types.py +++ b/hosting/management/commands/create_vm_types.py @@ -10,8 +10,8 @@ class Command(BaseCommand): hetzner = { 'base_price': 10, 'core_price': 10, - 'memory_price': 10, - 'disk_size_price': 10, + 'memory_price': 5, + 'disk_size_price': 1, 'description': 'VM auf einzelner HW, Raid1, kein HA' } diff --git a/hosting/migrations/0015_auto_20160512_0448.py b/hosting/migrations/0015_auto_20160512_0448.py new file mode 100644 index 00000000..16380513 --- /dev/null +++ b/hosting/migrations/0015_auto_20160512_0448.py @@ -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', + ), + ] diff --git a/hosting/migrations/0016_delete_railsbetauser.py b/hosting/migrations/0016_delete_railsbetauser.py new file mode 100644 index 00000000..8eb00622 --- /dev/null +++ b/hosting/migrations/0016_delete_railsbetauser.py @@ -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', + ), + ] diff --git a/hosting/models.py b/hosting/models.py index dd686312..8b26189a 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -10,14 +10,6 @@ from utils.models import BillingAddress 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): HETZNER_NUG = 'hetzner_nug' @@ -86,6 +78,9 @@ class VirtualMachinePlan(models.Model): objects = VMPlansManager() + def __str__(self): + return "%s" % (self.id) + @cached_property def hosting_company_name(self): return self.vm_type.get_hosting_company_display() @@ -106,7 +101,7 @@ class HostingOrder(models.Model): ORDER_APPROVED_STATUS = 'Approved' 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) billing_address = models.ForeignKey(BillingAddress) created_at = models.DateTimeField(auto_now_add=True) @@ -115,13 +110,16 @@ class HostingOrder(models.Model): cc_brand = models.CharField(max_length=10) stripe_charge_id = models.CharField(max_length=100, null=True) + def __str__(self): + return "%s" % (self.id) + @cached_property def status(self): return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS @classmethod - def create(cls, VMPlan=None, customer=None, billing_address=None): - instance = cls.objects.create(VMPlan=VMPlan, customer=customer, + def create(cls, vm_plan=None, customer=None, billing_address=None): + instance = cls.objects.create(vm_plan=vm_plan, customer=customer, billing_address=billing_address) return instance diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 74b8d5bb..8e1ff691 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -6,7 +6,7 @@
-

Invoice

Order # {{object.id}}

+

Invoice

Order # {{order.id}}


@@ -14,18 +14,18 @@

Billed To:

{{user.name}}
- {{object.billing_address.street_address}},{{order.billing_address.postal_code}}
- {{object.billing_address.city}}, {{object.billing_address.country}}. + {{order.billing_address.street_address}},{{order.billing_address.postal_code}}
+ {{order.billing_address.city}}, {{order.billing_address.country}}.
Order Date:
- {{object.created_at}}

+ {{order.created_at}}

Status:
- {{object.status}} + {% endif %}">{{order.status}}

@@ -35,7 +35,7 @@
Payment Method:
- {{object.cc_brand}} ending **** {{object.last4}}
+ {{order.cc_brand}} ending **** {{order.last4}}
{{user.email}}
@@ -48,15 +48,15 @@

Order summary


-

Type {{object.VMPlan.hosting_company_name}}

+

Type {{order.vm_plan.hosting_company_name}}


-

Cores {{object.VMPlan.cores}}

+

Cores {{order.vm_plan.cores}}


-

Memory {{object.VMPlan.memory}} GiB

+

Memory {{order.vm_plan.memory}} GiB


-

Disk space {{object.VMPlan.disk_size}} GiB

+

Disk space {{order.vm_plan.disk_size}} GiB


-

Total

{{object.VMPlan.price}} CHF

+

Total

{{order.vm_plan.price}} CHF

diff --git a/hosting/templates/hosting/orders.html b/hosting/templates/hosting/orders.html index 99c6464f..ce408783 100644 --- a/hosting/templates/hosting/orders.html +++ b/hosting/templates/hosting/orders.html @@ -23,7 +23,7 @@ {{order.id}} {{order.created_at}} - {{order.VMPlan.price}} CHF + {{order.vm_plan.price}} CHF {% if order.approved %} Approved {% else%} diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index e51e1d4e..55d07b86 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -104,7 +104,7 @@ {{order.id}} {{order.created_at}} - {{order.VMPlan.price}} CHF + {{order.vm_plan.price}} CHF {% if order.approved %} Approved {% else%} diff --git a/hosting/test_models.py b/hosting/test_models.py new file mode 100644 index 00000000..9c9cd71c --- /dev/null +++ b/hosting/test_models.py @@ -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) diff --git a/hosting/test_views.py b/hosting/test_views.py index b2dfe9ae..0e9c7626 100644 --- a/hosting/test_views.py +++ b/hosting/test_views.py @@ -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 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): @@ -70,3 +80,280 @@ class NodeJSHostingViewTest(TestCase, ProcessVMSelectionTestMixin): 'email': "info@node-hosting.ch", '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) diff --git a/hosting/urls.py b/hosting/urls.py index bb195b79..b313859d 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -3,7 +3,7 @@ from django.conf.urls import url from .views import DjangoHostingView, RailsHostingView, PaymentVMView, \ NodeJSHostingView, LoginView, SignupView, IndexView, \ OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\ - VirtualMachineDetailListView + VirtualMachineDetailView urlpatterns = [ # url(r'pricing/?$', VMPricingView.as_view(), name='pricing'), @@ -15,7 +15,7 @@ urlpatterns = [ url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'), url(r'orders/(?P\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'), url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'), - url(r'my-virtual-machines/(?P\d+)/?$', VirtualMachineDetailListView.as_view(), + url(r'my-virtual-machines/(?P\d+)/?$', VirtualMachineDetailView.as_view(), name='virtual_machines'), url(r'login/?$', LoginView.as_view(), name='login'), url(r'signup/?$', SignupView.as_view(), name='signup'), diff --git a/hosting/views.py b/hosting/views.py index b0e76028..1004563c 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -143,8 +143,9 @@ class SignupView(CreateView): return HttpResponseRedirect(self.get_success_url()) -class PaymentVMView(FormView): +class PaymentVMView(LoginRequiredMixin, FormView): template_name = 'hosting/payment.html' + login_url = reverse_lazy('hosting:login') form_class = BillingAddressForm def get_context_data(self, **kwargs): @@ -183,7 +184,7 @@ class PaymentVMView(FormView): billing_address = form.save() # Create a Hosting Order - order = HostingOrder.create(VMPlan=plan, customer=customer, + order = HostingOrder.create(vm_plan=plan, customer=customer, billing_address=billing_address) # Make stripe charge to a customer @@ -219,6 +220,7 @@ class PaymentVMView(FormView): class OrdersHostingDetailView(LoginRequiredMixin, DetailView): template_name = "hosting/order_detail.html" + context_object_name = "order" login_url = reverse_lazy('hosting:login') model = HostingOrder @@ -229,6 +231,7 @@ class OrdersHostingListView(LoginRequiredMixin, ListView): context_object_name = "orders" model = HostingOrder paginate_by = 10 + ordering = '-id' def get_queryset(self): user = self.request.user @@ -242,6 +245,7 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): context_object_name = "vms" model = VirtualMachinePlan paginate_by = 10 + ordering = '-id' def get_queryset(self): user = self.request.user @@ -249,7 +253,7 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): return super(VirtualMachinesPlanListView, self).get_queryset() -class VirtualMachineDetailListView(LoginRequiredMixin, DetailView): +class VirtualMachineDetailView(LoginRequiredMixin, DetailView): template_name = "hosting/virtual_machine_detail.html" login_url = reverse_lazy('hosting:login') model = VirtualMachinePlan diff --git a/requirements.txt b/requirements.txt index f3f2836c..13ea5675 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,7 @@ psycopg2 django-mptt easy_thumbnails django-polymorphic +model-mommy #PLUGINS djangocms_flash diff --git a/utils/test_forms.py b/utils/test_forms.py index 3e5701a7..dc6d9fcc 100644 --- a/utils/test_forms.py +++ b/utils/test_forms.py @@ -1,5 +1,5 @@ from django.test import TestCase -from .forms import ContactUsForm +from .forms import ContactUsForm, BillingAddressForm class ContactUsFormTest(TestCase): @@ -23,3 +23,27 @@ class ContactUsFormTest(TestCase): def test_invalid_form(self): form = ContactUsForm(data=self.incompleted_data) 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()) diff --git a/utils/tests.py b/utils/tests.py index 7ce503c2..83b87a85 100644 --- a/utils/tests.py +++ b/utils/tests.py @@ -1,3 +1,66 @@ 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", + }] + } + }