diff --git a/PyRIGS/settings.py b/PyRIGS/settings.py
index 272d1713..9f09f0c5 100644
--- a/PyRIGS/settings.py
+++ b/PyRIGS/settings.py
@@ -27,9 +27,7 @@ SECRET_KEY = env('SECRET_KEY', default='gxhy(a#5mhp289_=6xx$7jh=eh$ymxg^ymc+di*0
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG', cast=bool, default=True)
-
STAGING = env('STAGING', cast=bool, default=False)
-
CI = env('CI', cast=bool, default=False)
ALLOWED_HOSTS = ['pyrigs.nottinghamtec.co.uk', 'rigs.nottinghamtec.co.uk', 'pyrigs.herokuapp.com']
@@ -55,6 +53,7 @@ if DEBUG:
# Application definition
INSTALLED_APPS = (
+ 'whitenoise.runserver_nostatic',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
diff --git a/PyRIGS/tests/base.py b/PyRIGS/tests/base.py
index 3e483ec6..399a9afa 100644
--- a/PyRIGS/tests/base.py
+++ b/PyRIGS/tests/base.py
@@ -13,10 +13,12 @@ from RIGS import models as rigsmodels
from . import pages
from envparse import env
+from pytest_django.asserts import assertContains
-def create_datetime(year, month, day, hour, min):
+
+def create_datetime(year, month, day, hour, minute):
tz = pytz.timezone(settings.TIME_ZONE)
- return tz.localize(datetime(year, month, day, hour, min)).astimezone(pytz.utc)
+ return tz.localize(datetime(year, month, day, hour, minute)).astimezone(tz)
def create_browser():
@@ -60,6 +62,7 @@ class AutoLoginTest(BaseTest):
login_page.login("EventTest", "EventTestPassword")
+# FIXME Refactor as a pytest fixture
def screenshot_failure(func):
def wrapper_func(self, *args, **kwargs):
try:
@@ -85,3 +88,27 @@ def screenshot_failure_cls(cls):
def assert_times_equal(first_time, second_time):
assert first_time.replace(microsecond=0, second=0) == second_time.replace(microsecond=0, second=0)
+
+
+def assert_oembed(alt_event_embed_url, alt_oembed_url, client, event_embed_url, event_url, oembed_url):
+ # Test the meta tag is in place
+ response = client.get(event_url, follow=True, HTTP_HOST='example.com')
+ assertContains(response, '" in pattern:
@@ -34,8 +34,18 @@ def get_request_url(url):
print("Couldn't test url " + pattern)
+
+@pytest.fixture(scope='session')
+def django_db_setup(django_db_setup, django_db_blocker):
+ with django_db_blocker.unblock():
+ from django.conf import settings
+ settings.DEBUG = True
+ call_command('generateSampleRIGSData') # We need stuff setup so we don't get 404 errors everywhere
+ create_asset_one()
+ settings.DEBUG = False
+
+
def test_unauthenticated(client): # Nothing should be available to the unauthenticated
- create_asset_one()
for url in find_urls_recursive(urls.urlpatterns):
request_url = get_request_url(url)
if request_url and 'user' not in request_url: # User module is full of edge cases
@@ -52,12 +62,11 @@ def test_unauthenticated(client): # Nothing should be available to the unauthen
def test_page_titles(admin_client):
- create_asset_one()
for url in filter((lambda u: "embed" not in u.name), find_urls_recursive(urls.urlpatterns)):
request_url = get_request_url(url)
response = admin_client.get(request_url)
if hasattr(response, "context_data") and "page_title" in response.context_data:
- expected_title = response.context_data["page_title"]
+ expected_title = striptags(response.context_data["page_title"])
# try:
assertInHTML('
{} | Rig Information Gathering System'.format(expected_title), response.content.decode())
print("{} | {}".format(request_url, expected_title)) # If test fails, tell me where!
diff --git a/RIGS/management/commands/generateSampleData.py b/RIGS/management/commands/generateSampleData.py
index 0b456c83..fdcec461 100644
--- a/RIGS/management/commands/generateSampleData.py
+++ b/RIGS/management/commands/generateSampleData.py
@@ -1,6 +1,7 @@
from django.core.management import call_command
from django.core.management.base import BaseCommand
-import time
+
+from RIGS import models
class Command(BaseCommand):
help = 'Adds sample data to use for testing'
@@ -9,3 +10,4 @@ class Command(BaseCommand):
def handle(self, *args, **options):
call_command('generateSampleRIGSData')
call_command('generateSampleAssetsData')
+ # call_command('createinitialrevisions') TODO
diff --git a/RIGS/management/commands/generateSampleRIGSData.py b/RIGS/management/commands/generateSampleRIGSData.py
index aa0c4c0d..5394035e 100644
--- a/RIGS/management/commands/generateSampleRIGSData.py
+++ b/RIGS/management/commands/generateSampleRIGSData.py
@@ -41,7 +41,7 @@ class Command(BaseCommand):
with transaction.atomic():
models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
- self.setupGenericProfiles()
+ # self.setupGenericProfiles()
self.setupUsefulProfiles()
models.Profile.objects.bulk_create(self.profiles)
@@ -157,6 +157,7 @@ class Command(BaseCommand):
for i, name in enumerate(names):
pk = i + 1
newVenue = models.Venue(pk=pk, name=name)
+
if i % 2 == 0:
newVenue.three_phase_available = True
diff --git a/RIGS/rigboard.py b/RIGS/rigboard.py
index b84ae190..6d07e4f6 100644
--- a/RIGS/rigboard.py
+++ b/RIGS/rigboard.py
@@ -27,7 +27,7 @@ from django.views import generic
from z3c.rml import rml2pdf
from PyRIGS import decorators
-from PyRIGS.views import OEmbedView
+from PyRIGS.views import OEmbedView, is_ajax
from RIGS import models, forms
__author__ = 'ghost'
@@ -349,7 +349,7 @@ class EventAuthorisationRequest(generic.FormView, generic.detail.SingleObjectMix
return self.get_object()
def get_success_url(self):
- if self.request.is_ajax():
+ if is_ajax(self.request):
url = reverse_lazy('closemodal')
messages.info(self.request, "location.reload()")
else:
diff --git a/RIGS/tests/conftest.py b/RIGS/tests/conftest.py
new file mode 100644
index 00000000..cc38e2e4
--- /dev/null
+++ b/RIGS/tests/conftest.py
@@ -0,0 +1,7 @@
+from RIGS import models
+import pytest
+
+
+@pytest.fixture(autouse=True)
+def vat_rate(db):
+ return models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
diff --git a/RIGS/tests/test_functional.py b/RIGS/tests/test_functional.py
index 82ea36d3..a554aad3 100644
--- a/RIGS/tests/test_functional.py
+++ b/RIGS/tests/test_functional.py
@@ -8,54 +8,13 @@ from django.http import HttpResponseBadRequest
from django.test import TestCase
from django.urls import reverse
+import PyRIGS.tests.base
+import PyRIGS.tests.test_unit
from RIGS import models
-from pytest_django.asserts import assertContains, assertNotContains
-
-
-class BaseCase(TestCase):
- @classmethod
- def setUpTestData(cls):
- cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
- cls.profile = models.Profile.objects.get_or_create(
- first_name='Test',
- last_name='TEC User',
- username='eventauthtest',
- email='teccie@functional.test',
- is_superuser=True # lazily grant all permissions
- )[0]
-
- def setUp(self):
- super().setUp()
- self.profile.set_password('testuser')
- self.profile.save()
- self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
- venue = models.Venue.objects.create(name='Authorisation Test Venue')
- client = models.Person.objects.create(name='Authorisation Test Person', email='authorisation@functional.test')
- organisation = models.Organisation.objects.create(name='Authorisation Test Organisation', union_account=True)
- self.event = models.Event.objects.create(
- name='Authorisation Test',
- start_date=date.today(),
- venue=venue,
- person=client,
- organisation=organisation,
- )
-
-
-class TestEventValidation(BaseCase):
- def test_create(self):
- url = reverse('event_create')
- # end time before start access after start
- response = self.client.post(url, {'start_date': datetime.date(2020, 1, 1), 'start_time': datetime.time(10, 00),
- 'end_time': datetime.time(9, 00),
- 'access_at': datetime.datetime(2020, 1, 5, 10)})
- self.assertFormError(response, 'form', 'end_time',
- "Unless you've invented time travel, the event can't finish before it has started.")
- self.assertFormError(response, 'form', 'access_at',
- "Regardless of what some clients might think, access time cannot be after the event has started.")
+from pytest_django.asserts import assertContains, assertNotContains, assertFormError
def setup_event():
- models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
venue = models.Venue.objects.create(name='Authorisation Test Venue')
client = models.Person.objects.create(name='Authorisation Test Person', email='authorisation@functional.test')
organisation = models.Organisation.objects.create(name='Authorisation Test Organisation', union_account=True)
@@ -84,6 +43,18 @@ def setup_mail(event, profile):
return auth_data, hmac, url
+def test_create(admin_client):
+ url = reverse('event_create')
+ # end time before start access after start
+ response = admin_client.post(url, {'start_date': datetime.date(2020, 1, 1), 'start_time': datetime.time(10, 00),
+ 'end_time': datetime.time(9, 00),
+ 'access_at': datetime.datetime(2020, 1, 5, 10)})
+ assertFormError(response, 'form', 'end_time',
+ "Unless you've invented time travel, the event can't finish before it has started.")
+ assertFormError(response, 'form', 'access_at',
+ "Regardless of what some clients might think, access time cannot be after the event has started.")
+
+
def test_requires_valid_hmac(client, admin_user):
event = setup_event()
auth_data, hmac, url = setup_mail(event, admin_user)
@@ -152,36 +123,36 @@ def test_email_sent(admin_client, admin_user, mailoutbox):
assert mailoutbox[1].to == [settings.AUTHORISATION_NOTIFICATION_ADDRESS]
-class TECEventAuthorisationTest(BaseCase):
- def setUp(self):
- super().setUp()
- self.url = reverse('event_authorise_request', kwargs={'pk': self.event.pk})
+def test_email_check(admin_client, admin_user):
+ event = setup_event()
+ url = reverse('event_authorise_request', kwargs={'pk': event.pk})
+ admin_user.email = 'teccie@someotherdomain.com'
+ admin_user.save()
- def test_email_check(self):
- self.profile.email = 'teccie@someotherdomain.com'
- self.profile.save()
+ response = admin_client.post(url)
- response = self.client.post(self.url)
+ assertContains(response, 'must have an @nottinghamtec.co.uk email address')
- self.assertContains(response, 'must have an @nottinghamtec.co.uk email address')
- def test_request_send(self):
- self.profile.email = 'teccie@nottinghamtec.co.uk'
- self.profile.save()
- response = self.client.post(self.url)
- self.assertContains(response, 'This field is required.')
+def test_request_send(admin_client, admin_user):
+ event = setup_event()
+ url = reverse('event_authorise_request', kwargs={'pk': event.pk})
+ admin_user.email = 'teccie@nottinghamtec.co.uk'
+ admin_user.save()
+ response = admin_client.post(url)
+ assertContains(response, 'This field is required.')
- mail.outbox = []
+ mail.outbox = []
- response = self.client.post(self.url, {'email': 'client@functional.test'})
- self.assertEqual(response.status_code, 302)
- self.assertEqual(len(mail.outbox), 1)
- email = mail.outbox[0]
- self.assertIn('client@functional.test', email.to)
- self.assertIn('/event/%d/' % (self.event.pk), email.body)
+ response = admin_client.post(url, {'email': 'client@functional.test'})
+ assert response.status_code == 302
+ assert len(mail.outbox) == 1
+ email = mail.outbox[0]
+ assert 'client@functional.test' in email.to
+ assert '/event/%d/' % event.pk in email.body
- # Check sent by details are populated
- self.event.refresh_from_db()
- self.assertEqual(self.event.auth_request_by, self.profile)
- self.assertEqual(self.event.auth_request_to, 'client@functional.test')
- self.assertIsNotNone(self.event.auth_request_at)
+ # Check sent by details are populated
+ event.refresh_from_db()
+ assert event.auth_request_by == admin_user
+ assert event.auth_request_to == 'client@functional.test'
+ assert event.auth_request_at is not None
diff --git a/RIGS/tests/test_unit.py b/RIGS/tests/test_unit.py
index a4288c19..a6fcc994 100644
--- a/RIGS/tests/test_unit.py
+++ b/RIGS/tests/test_unit.py
@@ -8,9 +8,14 @@ from django.urls import reverse, reverse_lazy
from django.utils import timezone
from pytest_django.asserts import assertRedirects, assertNotContains, assertContains
-from PyRIGS.tests.base import assert_times_equal
+import PyRIGS.tests.test_unit
+from PyRIGS.tests.base import assert_times_equal, assert_oembed, login
from RIGS import models
+import pytest
+
+pytestmark = pytest.mark.django_db
+
class TestAdminMergeObjects(TestCase):
@classmethod
@@ -201,7 +206,7 @@ class TestInvoiceDelete(TestCase):
self.assertTrue(models.Invoice.objects.get(pk=self.invoices[2].pk))
# Actually delete it
- response = self.client.post(request_url, follow=True)
+ self.client.post(request_url, follow=True)
# Check the invoice is deleted
self.assertRaises(ObjectDoesNotExist, models.Invoice.objects.get, pk=self.invoices[2].pk)
@@ -216,7 +221,7 @@ class TestInvoiceDelete(TestCase):
self.assertTrue(models.Invoice.objects.get(pk=self.invoices[1].pk))
# Try to actually delete it
- response = self.client.post(request_url, follow=True)
+ self.client.post(request_url, follow=True)
# Check this didn't work
self.assertTrue(models.Invoice.objects.get(pk=self.invoices[1].pk))
@@ -257,102 +262,71 @@ class TestPrintPaperwork(TestCase):
self.assertEqual(response.status_code, 200)
-class TestEmbeddedViews(TestCase):
- @classmethod
- def setUpTestData(cls):
- cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True,
- is_active=True, is_staff=True)
-
- cls.events = {
- 1: models.Event.objects.create(name="TE E1", start_date=date.today()),
- 2: models.Event.objects.create(name="TE E2", start_date=date.today())
- }
-
- cls.invoices = {
- 1: models.Invoice.objects.create(event=cls.events[1]),
- 2: models.Invoice.objects.create(event=cls.events[2])
- }
-
- cls.payments = {
- 1: models.Payment.objects.create(invoice=cls.invoices[1], date=date.today(), amount=12.34,
- method=models.Payment.CASH)
- }
-
- def setUp(self):
- self.profile.set_password('testuser')
- self.profile.save()
-
- def testLoginRedirect(self):
- request_url = reverse('event_embed', kwargs={'pk': 1})
- expected_url = "{0}?next={1}".format(reverse('login_embed'), request_url)
-
- # Request the page and check it redirects
- response = self.client.get(request_url, follow=True)
- self.assertRedirects(response, expected_url, status_code=302, target_status_code=200)
-
- # Now login
- self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
-
- # And check that it no longer redirects
- response = self.client.get(request_url, follow=True)
- self.assertEqual(len(response.redirect_chain), 0)
-
- def testLoginCookieWarning(self):
- login_url = reverse('login_embed')
- response = self.client.post(login_url, follow=True)
- self.assertContains(response, "Cookies do not seem to be enabled")
-
- def testXFrameHeaders(self):
- event_url = reverse('event_embed', kwargs={'pk': 1})
- login_url = reverse('login_embed')
-
- self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
-
- response = self.client.get(event_url, follow=True)
- with self.assertRaises(KeyError):
- response._headers["X-Frame-Options"]
-
- response = self.client.get(login_url, follow=True)
- with self.assertRaises(KeyError):
- response._headers["X-Frame-Options"]
-
- def testOEmbed(self):
- event_url = reverse('event_detail', kwargs={'pk': 1})
- event_embed_url = reverse('event_embed', kwargs={'pk': 1})
- oembed_url = reverse('event_oembed', kwargs={'pk': 1})
-
- alt_oembed_url = reverse('event_oembed', kwargs={'pk': 999})
- alt_event_embed_url = reverse('event_embed', kwargs={'pk': 999})
-
- # Test the meta tag is in place
- response = self.client.get(event_url, follow=True, HTTP_HOST='example.com')
- self.assertContains(response, ' 100)
+ # Request the page and check it redirects
+ response = client.get(request_url, follow=True)
+ assertRedirects(response, expected_url, status_code=302, target_status_code=200)
- def test_production_exception(self):
- from django.core.management.base import CommandError
+ # Now login
+ login(client, django_user_model)
- self.assertRaisesRegex(CommandError, ".*production", call_command, 'generateSampleRIGSData')
+ # And check that it no longer redirects
+ response = client.get(request_url, follow=True)
+ assert len(response.redirect_chain) == 0
+
+
+def test_login_cookie_warning(client):
+ login_url = reverse('login_embed')
+ response = client.post(login_url, follow=True)
+ assertContains(response, "Cookies do not seem to be enabled")
+
+
+def test_xframe_headers(admin_client):
+ event = create_event()
+ event_url = reverse('event_embed', kwargs={'pk': event.pk})
+ login_url = reverse('login_embed')
+
+ response = admin_client.get(event_url, follow=True)
+ with pytest.raises(KeyError):
+ response._headers["X-Frame-Options"]
+
+ response = admin_client.get(login_url, follow=True)
+ with pytest.raises(KeyError):
+ response._headers["X-Frame-Options"]
+
+
+def test_oembed(client):
+ event = create_event()
+ event_url = reverse('event_detail', kwargs={'pk': event.pk})
+ event_embed_url = reverse('event_embed', kwargs={'pk': event.pk})
+ oembed_url = reverse('event_oembed', kwargs={'pk': event.pk})
+
+ alt_oembed_url = reverse('event_oembed', kwargs={'pk': 999})
+ alt_event_embed_url = reverse('event_embed', kwargs={'pk': 999})
+
+ assert_oembed(alt_event_embed_url, alt_oembed_url, client, event_embed_url, event_url, oembed_url)
+
+
+@override_settings(DEBUG=True)
+def test_generate_sample_data():
+ # Run the management command and check there are no exceptions
+ call_command('generateSampleRIGSData')
+
+ # Check there are lots of events
+ assert models.Event.objects.all().count() > 100
+
+
+def test_production_exception():
+ from django.core.management.base import CommandError
+ with pytest.raises(CommandError):
+ call_command("generateSampleRIGSData")
def search(client, url, found, notfound, arguments):
diff --git a/assets/management/commands/generateSampleAssetsData.py b/assets/management/commands/generateSampleAssetsData.py
index 0c021d98..32cce0a5 100644
--- a/assets/management/commands/generateSampleAssetsData.py
+++ b/assets/management/commands/generateSampleAssetsData.py
@@ -57,14 +57,14 @@ class Command(BaseCommand):
def create_categories(self):
choices = ['Case', 'Video', 'General', 'Sound', 'Lighting', 'Rigging']
- pk = 1
+ pk = 99
for cat in choices:
self.categories.append(models.AssetCategory(pk=pk, name=cat))
pk += 1
def create_assets(self):
asset_description = ['Large cable', 'Shiny thing', 'New lights', 'Really expensive microphone', 'Box of fuse flaps', 'Expensive tool we didn\'t agree to buy', 'Cable drums', 'Boring amount of tape', 'Video stuff no one knows how to use', 'More amplifiers', 'Heatshrink']
- pk = 1
+ pk = 9000
for i in range(100):
asset = models.Asset(
pk=pk,
@@ -89,7 +89,7 @@ class Command(BaseCommand):
csas = [0.75, 1.00, 1.25, 2.5, 4]
lengths = [1, 2, 5, 10, 15, 20, 25, 30, 50, 100]
- pk = 102 # Offset to avoid other asset IDs
+ pk = 200 # Offset to avoid other asset IDs
for i in range(100):
asset = models.Asset(
pk=pk,
diff --git a/assets/tests/test_unit.py b/assets/tests/test_unit.py
index 587c7094..66331d05 100644
--- a/assets/tests/test_unit.py
+++ b/assets/tests/test_unit.py
@@ -2,35 +2,16 @@ import datetime
import pytest
from django.core.management import call_command
+from django.test import override_settings
from django.test.utils import override_settings
from django.urls import reverse
from pytest_django.asserts import assertFormError, assertRedirects, assertContains, assertNotContains
-from assets import models, urls
+from PyRIGS.tests.base import assert_oembed, login
-pytestmark = pytest.mark.django_db # TODO
+from assets import models
-
-def login(client, django_user_model):
- pwd = 'testuser'
- usr = "TestUser"
- django_user_model.objects.create_user(username=usr, email="TestUser@test.com", password=pwd, is_superuser=True, is_active=True, is_staff=True)
- assert client.login(username=usr, password=pwd)
-
-
-def create_test_asset():
- working = models.AssetStatus.objects.create(name="Working", should_show=True)
- lighting = models.AssetCategory.objects.create(name="Lighting")
- asset = models.Asset.objects.create(asset_id="1991", description="Spaceflower", status=working, category=lighting, date_acquired=datetime.date(1991, 12, 26))
- return asset
-
-
-def create_test_cable():
- category = models.AssetCategory.objects.create(name="Sound")
- status = models.AssetStatus.objects.create(name="Broken", should_show=True)
- connector = models.Connector.objects.create(description="16A IEC", current_rating=16, voltage_rating=240, num_pins=3)
- cable_type = models.CableType.objects.create(circuits=11, cores=3, plug=connector, socket=connector)
- return models.Asset.objects.create(asset_id="666", description="125A -> Jack", comments="The cable from Hell...", status=status, category=category, date_acquired=datetime.date(2006, 6, 6), is_cable=True, cable_type=cable_type, length=10, csa="1.5")
+pytestmark = pytest.mark.django_db
def test_supplier_create(client, django_user_model):
@@ -103,20 +84,7 @@ def test_oembed(client):
alt_oembed_url = reverse('asset_oembed', kwargs={'pk': 999})
alt_asset_embed_url = reverse('asset_embed', kwargs={'pk': 999})
- # Test the meta tag is in place
- response = client.get(asset_url, follow=True, HTTP_HOST='example.com')
- assert '