forked from ungleich-public/dynamicweb
591 lines
16 KiB
Python
591 lines
16 KiB
Python
# datacenterlight/tests/test_views.py
|
|
|
|
import json
|
|
from unittest.mock import patch
|
|
|
|
from django.contrib.messages import get_messages
|
|
from django.contrib.sessions.middleware import SessionMiddleware
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from django.core.exceptions import ValidationError
|
|
from django.test import RequestFactory, TestCase
|
|
from django.urls import reverse
|
|
|
|
from datacenterlight.forms import ContactForm
|
|
from datacenterlight.views import (
|
|
ContactUsView,
|
|
IndexView,
|
|
OrderConfirmationView,
|
|
PaymentOrderView,
|
|
WhyDataCenterLightView,
|
|
create_incomplete_intent_request,
|
|
get_error_response_dict,
|
|
show_error,
|
|
)
|
|
from utils.forms import BillingAddressFormSignup
|
|
from .factories import CMSIntegrationFactory
|
|
|
|
|
|
class SessionRequestMixin:
|
|
"""
|
|
Adds a real Django session to RequestFactory requests.
|
|
"""
|
|
|
|
def add_session(self, request):
|
|
middleware = SessionMiddleware(lambda request: None)
|
|
middleware.process_request(request)
|
|
request.session.save()
|
|
return request
|
|
|
|
|
|
class ContactUsViewTests(TestCase, SessionRequestMixin):
|
|
def setUp(self):
|
|
self.factory = RequestFactory()
|
|
|
|
def test_get_redirects_to_index(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:contact_us")
|
|
)
|
|
|
|
self.assertRedirects(
|
|
response,
|
|
reverse("datacenterlight:index"),
|
|
fetch_redirect_response=False,
|
|
)
|
|
|
|
def test_form_valid_renders_index_template(self):
|
|
request = self.factory.post(
|
|
reverse("datacenterlight:contact_us")
|
|
)
|
|
|
|
view = ContactUsView()
|
|
view.setup(request)
|
|
|
|
form = ContactForm()
|
|
|
|
response = view.form_valid(form)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertContains(response, "Thank you")
|
|
|
|
def test_form_invalid_renders_index_template(self):
|
|
request = self.factory.post(
|
|
reverse("datacenterlight:contact_us")
|
|
)
|
|
|
|
view = ContactUsView()
|
|
view.setup(request)
|
|
|
|
# Bind the form with invalid/missing data.
|
|
form = ContactForm(data={})
|
|
|
|
self.assertFalse(form.is_valid())
|
|
|
|
response = view.form_invalid(form)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertContains(response, "index")
|
|
|
|
|
|
class IndexViewTests(TestCase, SessionRequestMixin):
|
|
|
|
def setUp(self):
|
|
self.factory = RequestFactory()
|
|
|
|
def test_get_redirects_to_cms_index(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:whydatacenterlight")
|
|
)
|
|
|
|
self.assertRedirects(
|
|
response,
|
|
reverse("datacenterlight:cms_index"),
|
|
fetch_redirect_response=False,
|
|
)
|
|
|
|
def test_index_t_redirect_chain(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:index_t"),
|
|
follow=True,
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertEqual(
|
|
response.redirect_chain[0][0],
|
|
reverse("datacenterlight:cms_index"),
|
|
)
|
|
|
|
def test_index_g_uses_index_view(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:index_g"),
|
|
follow=True,
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertEqual(
|
|
response.redirect_chain[0][0],
|
|
reverse("datacenterlight:cms_index"),
|
|
)
|
|
|
|
def test_index_f_uses_index_view(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:index_f"),
|
|
follow=True,
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertEqual(
|
|
response.redirect_chain[0][0],
|
|
reverse("datacenterlight:cms_index"),
|
|
)
|
|
|
|
def test_index_l_uses_index_view(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:index_l"),
|
|
follow=True,
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertEqual(
|
|
response.redirect_chain[0][0],
|
|
reverse("datacenterlight:cms_index"),
|
|
)
|
|
|
|
def test_cms_index_redirects_to_cms(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:cms_index"),
|
|
follow=True,
|
|
)
|
|
|
|
def test_get_success_url(self):
|
|
request = self.factory.get(
|
|
reverse("datacenterlight:index")
|
|
)
|
|
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
self.assertEqual(
|
|
view.get_success_url(),
|
|
reverse("datacenterlight:index") + "#requestform",
|
|
)
|
|
|
|
def test_get_context_data_contains_base_url(self):
|
|
request = self.factory.get(
|
|
reverse("datacenterlight:index")
|
|
)
|
|
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with patch(
|
|
"datacenterlight.views.CreateView.get_context_data",
|
|
return_value={},
|
|
):
|
|
context = view.get_context_data()
|
|
|
|
self.assertIn("base_url", context)
|
|
self.assertIn("contact_form", context)
|
|
self.assertIs(context["contact_form"], ContactForm)
|
|
|
|
self.assertEqual(
|
|
context["base_url"],
|
|
f"{request.scheme}://{request.get_host()}",
|
|
)
|
|
|
|
# ------------------------------------------------------------------
|
|
# validate_cores
|
|
# ------------------------------------------------------------------
|
|
|
|
def test_validate_cores_accepts_one(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
self.assertIsNone(view.validate_cores(1))
|
|
|
|
def test_validate_cores_accepts_48(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
self.assertIsNone(view.validate_cores(48))
|
|
|
|
def test_validate_cores_rejects_zero(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
view.validate_cores(0)
|
|
|
|
def test_validate_cores_rejects_more_than_48(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
view.validate_cores(49)
|
|
|
|
def test_validate_cores_rejects_negative_number(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
view.validate_cores(-1)
|
|
|
|
# ------------------------------------------------------------------
|
|
# validate_memory
|
|
# ------------------------------------------------------------------
|
|
|
|
def test_validate_memory_requires_pid(self):
|
|
request = self.factory.post(
|
|
"/",
|
|
{
|
|
"ram": "1",
|
|
},
|
|
)
|
|
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
view.validate_memory(1)
|
|
|
|
def test_validate_memory_rejects_unknown_plugin(self):
|
|
request = self.factory.post(
|
|
"/",
|
|
{
|
|
"pid": "999999999",
|
|
},
|
|
)
|
|
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
view.validate_memory(1)
|
|
|
|
# ------------------------------------------------------------------
|
|
# validate_storage
|
|
# ------------------------------------------------------------------
|
|
|
|
def test_validate_storage_accepts_10(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
self.assertIsNone(view.validate_storage(10))
|
|
|
|
def test_validate_storage_accepts_2000(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
self.assertIsNone(view.validate_storage(2000))
|
|
|
|
def test_validate_storage_rejects_below_10(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
view.validate_storage(9)
|
|
|
|
def test_validate_storage_rejects_above_2000(self):
|
|
request = self.factory.post("/")
|
|
view = IndexView()
|
|
view.setup(request)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
view.validate_storage(2001)
|
|
|
|
# ------------------------------------------------------------------
|
|
# POST without a valid pricing name
|
|
# ------------------------------------------------------------------
|
|
|
|
def test_post_with_unknown_pricing_name_redirects_to_referer(self):
|
|
response = self.client.post(
|
|
reverse("datacenterlight:index"),
|
|
{
|
|
"cpu": "2",
|
|
"ram": "4",
|
|
"storage": "20",
|
|
"config": "1",
|
|
"pricing_name": "definitely-does-not-exist",
|
|
},
|
|
HTTP_REFERER="/some-page/",
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 302)
|
|
self.assertEqual(
|
|
response["Location"],
|
|
"/some-page/#order_form",
|
|
)
|
|
|
|
messages = list(
|
|
get_messages(response.wsgi_request)
|
|
)
|
|
|
|
self.assertTrue(messages)
|
|
self.assertIn(
|
|
"Incorrect pricing name",
|
|
str(messages[0]),
|
|
)
|
|
|
|
|
|
class WhyDataCenterLightViewTests(TestCase):
|
|
|
|
def test_template_name(self):
|
|
view = WhyDataCenterLightView()
|
|
|
|
self.assertEqual(
|
|
view.template_name,
|
|
"datacenterlight/whydatacenterlight.html",
|
|
)
|
|
|
|
def test_get_redirects_to_cms_index(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:whydatacenterlight")
|
|
)
|
|
|
|
self.assertRedirects(
|
|
response,
|
|
reverse("datacenterlight:cms_index"),
|
|
fetch_redirect_response=False,
|
|
)
|
|
|
|
|
|
class PaymentOrderViewTests(TestCase, SessionRequestMixin):
|
|
|
|
def setUp(self):
|
|
self.factory = RequestFactory()
|
|
CMSIntegrationFactory.create(name="default", domain=None)
|
|
|
|
def set_payment_session(self, **extra):
|
|
session = self.client.session
|
|
|
|
session["vat_validation_status"] = "not_needed"
|
|
session["card_id"] = None
|
|
session["token"] = None
|
|
session["id_payment_method"] = None
|
|
|
|
session.update(extra)
|
|
session.save()
|
|
|
|
def test_product_lookup_with_unknown_product_returns_empty_json(self):
|
|
self.set_payment_session()
|
|
|
|
response = self.client.post(
|
|
reverse("datacenterlight:payment"),
|
|
{
|
|
"product": "1",
|
|
"generic_payment_form-product_name": "999999999",
|
|
},
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.json(), {})
|
|
|
|
def test_get_form_class_for_anonymous_user(self):
|
|
request = self.factory.get(
|
|
reverse("datacenterlight:payment")
|
|
)
|
|
request.user = AnonymousUser()
|
|
|
|
view = PaymentOrderView()
|
|
view.setup(request)
|
|
|
|
form_class = view.get_form_class()
|
|
|
|
self.assertIsNotNone(form_class)
|
|
self.assertIs(form_class, BillingAddressFormSignup)
|
|
|
|
def test_generic_payment_page_renders(self):
|
|
self.set_payment_session()
|
|
|
|
response = self.client.get(
|
|
reverse("datacenterlight:payment"),
|
|
{
|
|
"type": "generic",
|
|
},
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertTemplateUsed(
|
|
response,
|
|
"datacenterlight/landing_payment.html",
|
|
)
|
|
|
|
|
|
class OrderConfirmationViewTests(TestCase, SessionRequestMixin):
|
|
|
|
def setUp(self):
|
|
self.factory = RequestFactory()
|
|
CMSIntegrationFactory.create(name="default", domain=None)
|
|
|
|
def test_get_without_payment_data_redirects_to_index(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:order_confirmation")
|
|
)
|
|
|
|
self.assertRedirects(
|
|
response,
|
|
reverse("datacenterlight:index"),
|
|
fetch_redirect_response=False,
|
|
)
|
|
|
|
def test_post_without_payment_method_returns_error(self):
|
|
response = self.client.post(
|
|
reverse("datacenterlight:order_confirmation")
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
data = response.json()
|
|
|
|
self.assertIn("status", data)
|
|
self.assertFalse(data["status"])
|
|
|
|
def test_order_confirmation_url_exists(self):
|
|
response = self.client.get(
|
|
reverse("datacenterlight:order_confirmation")
|
|
)
|
|
|
|
self.assertIn(
|
|
response.status_code,
|
|
(200, 302, 404),
|
|
)
|
|
|
|
@patch(
|
|
"datacenterlight.views.StripeUtils."
|
|
"get_cards_details_from_payment_method"
|
|
)
|
|
def test_generic_recurring_payment_renders_confirmation(
|
|
self,
|
|
mock_get_card_details,
|
|
):
|
|
mock_get_card_details.return_value = {
|
|
"response_object": {
|
|
"brand": "visa",
|
|
"last4": "4242",
|
|
"exp_month": 12,
|
|
"exp_year": 2030,
|
|
}
|
|
}
|
|
|
|
session = self.client.session
|
|
|
|
session["generic_payment_type"] = "generic"
|
|
|
|
session["generic_payment_details"] = {
|
|
"amount": 100,
|
|
"amount_before_vat": 100,
|
|
"vat_rate": 0,
|
|
"vat_amount": 0,
|
|
"product_name": "Test Product",
|
|
"product_id": 1,
|
|
"product_slug": "test-product",
|
|
"recurring": True,
|
|
"description": "Test product",
|
|
"recurring_interval": "month",
|
|
"exclude_vat_calculations": False,
|
|
}
|
|
|
|
session["id_payment_method"] = "pm_test"
|
|
session["customer"] = "cus_test"
|
|
session["vat_validation_status"] = "not_needed"
|
|
|
|
session.save()
|
|
|
|
response = self.client.get(
|
|
reverse("datacenterlight:order_confirmation")
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertTemplateUsed(
|
|
response,
|
|
"datacenterlight/order_detail.html",
|
|
)
|
|
|
|
self.assertIn(
|
|
"generic_payment_details",
|
|
response.context,
|
|
)
|
|
|
|
mock_get_card_details.assert_called_once_with(
|
|
"pm_test"
|
|
)
|
|
|
|
|
|
class HelperFunctionTests(TestCase, SessionRequestMixin):
|
|
|
|
def setUp(self):
|
|
self.factory = RequestFactory()
|
|
|
|
def test_create_incomplete_intent_request(self):
|
|
request = self.factory.post(
|
|
"/payment/",
|
|
{
|
|
"amount": "100",
|
|
},
|
|
)
|
|
|
|
self.add_session(request)
|
|
|
|
request.session["specs"] = {
|
|
"cpu": 2,
|
|
"ram": 4,
|
|
"storage": 20,
|
|
}
|
|
|
|
request.session["template"] = {
|
|
"id": 123,
|
|
}
|
|
|
|
request.session.save()
|
|
|
|
result = create_incomplete_intent_request(request)
|
|
|
|
self.assertIsInstance(result, str)
|
|
|
|
|
|
def test_show_error_returns_json_response(self):
|
|
request = self.factory.get(
|
|
reverse("datacenterlight:payment")
|
|
)
|
|
|
|
self.add_session(request)
|
|
|
|
# Add messages middleware because show_error()
|
|
# uses django.contrib.messages.
|
|
from django.contrib.messages.middleware import MessageMiddleware
|
|
|
|
MessageMiddleware(
|
|
lambda request: None
|
|
).process_request(request)
|
|
|
|
response = show_error(
|
|
"Something went wrong",
|
|
request,
|
|
)
|
|
|
|
self.assertEqual(
|
|
response.status_code,
|
|
200,
|
|
)
|
|
|
|
data = json.loads(
|
|
response.content.decode("utf-8")
|
|
)
|
|
self.assertFalse(data["status"])
|
|
self.assertEqual(
|
|
data["msg_title"],
|
|
"Error.",
|
|
)
|