Yet more test shenanigans

Can you tell I'm getting fed up?
This commit is contained in:
2021-02-07 00:05:47 +00:00
parent 4f912932ca
commit 788fb3efe6
13 changed files with 135 additions and 156 deletions

View File

@@ -94,7 +94,6 @@ ROOT_URLCONF = 'PyRIGS.urls'
WSGI_APPLICATION = 'PyRIGS.wsgi.application' WSGI_APPLICATION = 'PyRIGS.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',

View File

@@ -0,0 +1,27 @@
import pytest
from django.core.management import call_command
from django.template.defaultfilters import striptags
from django.urls.exceptions import NoReverseMatch
from RIGS.models import Event
from assets.models import Asset
@pytest.mark.parametrize("command", ['generateSampleAssetsData', 'generateSampleRIGSData', 'generateSampleUserData', 'deleteSampleData'])
def test_production_exception(command):
from django.core.management.base import CommandError
with pytest.raises(CommandError, match=".*production"):
call_command(command)
def test_sample_data(settings):
settings.DEBUG = True
call_command('generateSampleData')
assert Asset.objects.all().count() > 50
assert Event.objects.all().count() > 100
call_command('deleteSampleData')
assert Asset.objects.all().count() == 0
assert Event.objects.all().count() == 0
# Cleanup
call_command('flush', '--noinput')
call_command('migrate')

View File

@@ -1,12 +1,15 @@
from PyRIGS import urls
from django.core.management import call_command
import pytest import pytest
from django.urls import URLPattern, URLResolver, reverse from django.core.management import call_command
from django.urls.exceptions import NoReverseMatch
from django.test.utils import override_settings
from pytest_django.asserts import assertContains, assertRedirects, assertTemplateUsed, assertInHTML
from django.template.defaultfilters import striptags from django.template.defaultfilters import striptags
from assets import models from django.urls import URLPattern, URLResolver
from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
from pytest_django.asserts import assertRedirects, assertContains, assertNotContains
from pytest_django.asserts import assertTemplateUsed, assertInHTML
from PyRIGS import urls
from RIGS.models import Event
from assets.models import Asset
def find_urls_recursive(patterns): def find_urls_recursive(patterns):
@@ -34,13 +37,18 @@ def get_request_url(url):
print("Couldn't test url " + pattern) print("Couldn't test url " + pattern)
@pytest.fixture(scope='class', autouse=True) @pytest.fixture(scope='module', autouse=True)
def run_sample_data(django_db_blocker): # We need stuff setup so we don't get 404 errors everywhere def sample_data(django_db_blocker):
with django_db_blocker.unblock(): with django_db_blocker.unblock():
from django.conf import settings from django.conf import settings
settings.DEBUG = True settings.DEBUG = True
call_command('generateSampleData') call_command('generateSampleData')
assert Asset.objects.all().count() > 50
assert Event.objects.all().count() > 100
settings.DEBUG = False settings.DEBUG = False
yield
call_command('flush', '--noinput')
call_command('migrate')
def test_unauthenticated(client): # Nothing should be available to the unauthenticated def test_unauthenticated(client): # Nothing should be available to the unauthenticated
@@ -73,8 +81,50 @@ def test_page_titles(admin_client):
# print(response.content.decode(), file=open('output.html', 'w')) # print(response.content.decode(), file=open('output.html', 'w'))
def test_delete_sample_data(settings): def test_basic_access(client):
settings.DEBUG = True client.logout()
call_command('deleteSampleData') assert client.login(username="basic", password="basic")
assert models.Asset.objects.all().count() == 0
assert models.Supplier.objects.all().count() == 0 url = reverse('asset_list')
response = client.get(url)
# Check edit and duplicate buttons NOT shown in list
assertNotContains(response, 'Edit')
assertNotContains(response,
'Duplicate') # If this line is randomly failing, check the debug toolbar HTML hasn't crept in
url = reverse('asset_detail', kwargs={'pk': 1})
response = client.get(url)
assertNotContains(response, 'Purchase Details')
assertNotContains(response, 'View Revision History')
urlz = {'asset_history', 'asset_update', 'asset_duplicate'}
for url_name in urlz:
request_url = reverse(url_name, kwargs={'pk': 1})
response = client.get(request_url, follow=True)
assert response.status_code == 403
request_url = reverse('supplier_create')
response = client.get(request_url, follow=True)
assert response.status_code == 403
request_url = reverse('supplier_update', kwargs={'pk': 1})
response = client.get(request_url, follow=True)
assert response.status_code == 403
client.logout()
def test_keyholder_access(client):
client.logout()
assert client.login(username="keyholder", password="keyholder")
url = reverse('asset_list')
response = client.get(url)
# Check edit and duplicate buttons shown in list
assertContains(response, 'Edit')
assertContains(response, 'Duplicate')
url = reverse('asset_detail', kwargs={'pk': 1})
response = client.get(url)
assertContains(response, 'Purchase Details')
assertContains(response, 'View Revision History')
client.logout()

View File

@@ -3,19 +3,16 @@ import pytest
from django.utils import timezone from django.utils import timezone
@pytest.fixture(autouse=True)
def vat_rate(db):
return models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
@pytest.fixture @pytest.fixture
def basic_event(db): def basic_event(db):
return models.Event.objects.create(name="TE E1", start_date=timezone.now()) event = models.Event.objects.create(name="TE E1", start_date=timezone.now())
yield event
event.delete()
@pytest.fixture @pytest.fixture
def ra(basic_event, admin_user): def ra(basic_event, admin_user):
return models.RiskAssessment.objects.create(event=basic_event, nonstandard_equipment=False, nonstandard_use=False, ra = models.RiskAssessment.objects.create(event=basic_event, nonstandard_equipment=False, nonstandard_use=False,
contractors=False, other_companies=False, crew_fatigue=False, contractors=False, other_companies=False, crew_fatigue=False,
big_power=False, power_mic=admin_user, generators=False, big_power=False, power_mic=admin_user, generators=False,
other_companies_power=False, nonstandard_equipment_power=False, other_companies_power=False, nonstandard_equipment_power=False,
@@ -24,24 +21,30 @@ def ra(basic_event, admin_user):
area_outside_of_control=True, barrier_required=True, area_outside_of_control=True, barrier_required=True,
nonstandard_emergency_procedure=True, special_structures=False, nonstandard_emergency_procedure=True, special_structures=False,
suspended_structures=False, outside=False) suspended_structures=False, outside=False)
yield ra
ra.delete()
@pytest.fixture @pytest.fixture
def venue(db): def venue(db):
return models.Venue.objects.create(name="Venue 1") venue = models.Venue.objects.create(name="Venue 1")
yield venue
venue.delete()
@pytest.fixture # TODO parameterise with Event sizes @pytest.fixture # TODO parameterise with Event sizes
def checklist(basic_event, venue, admin_user): def checklist(basic_event, venue, admin_user):
return models.EventChecklist.objects.create(event=basic_event, power_mic=admin_user, safe_parking=False, checklist = models.EventChecklist.objects.create(event=basic_event, power_mic=admin_user, safe_parking=False,
safe_packing=False, exits=False, trip_hazard=False, warning_signs=False, safe_packing=False, exits=False, trip_hazard=False, warning_signs=False,
ear_plugs=False, hs_location="Locked away safely", ear_plugs=False, hs_location="Locked away safely",
extinguishers_location="Somewhere, I forgot", earthing=False, pat=False, extinguishers_location="Somewhere, I forgot", earthing=False, pat=False,
date=timezone.now(), venue=venue) date=timezone.now(), venue=venue)
yield checklist
checklist.delete()
@pytest.fixture @pytest.fixture
def many_events(db, scope="class"): def many_events(db, scope="class"):
return { many_events = {
# produce 7 normal events - 5 current # produce 7 normal events - 5 current
1: models.Event.objects.create(name="TE E1", start_date=date.today() + timedelta(days=6), 1: models.Event.objects.create(name="TE E1", start_date=date.today() + timedelta(days=6),
description="start future no end"), description="start future no end"),
@@ -90,3 +93,6 @@ def many_events(db, scope="class"):
status=models.Event.CANCELLED, status=models.Event.CANCELLED,
description="non rig today cancelled"), description="non rig today cancelled"),
} }
yield many_events
for event in many_events:
event.delete()

View File

@@ -9,7 +9,6 @@ from django.test import TestCase
from django.urls import reverse from django.urls import reverse
import PyRIGS.tests.base import PyRIGS.tests.base
import PyRIGS.tests.test_unit
from RIGS import models from RIGS import models
from pytest_django.asserts import assertContains, assertNotContains, assertFormError from pytest_django.asserts import assertContains, assertNotContains, assertFormError
@@ -109,7 +108,7 @@ def test_duplicate_warning(client, admin_user):
assertContains(response, 'amount has changed') assertContains(response, 'amount has changed')
@pytest.mark.django_db(transaction=True) @pytest.mark.django_db
def test_email_sent(admin_client, admin_user, mailoutbox): def test_email_sent(admin_client, admin_user, mailoutbox):
event = setup_event() event = setup_event()
auth_data, hmac, url = setup_mail(event, admin_user) auth_data, hmac, url = setup_mail(event, admin_user)

View File

@@ -652,7 +652,6 @@ class TestCalendar(BaseRigboardTest):
@screenshot_failure_cls @screenshot_failure_cls
@pytest.mark.xfail(reason="Bootstrap select handling broken for some reason, pending rewrite", run=False)
class TestHealthAndSafety(BaseRigboardTest): class TestHealthAndSafety(BaseRigboardTest):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@@ -871,8 +870,8 @@ class TestHealthAndSafety(BaseRigboardTest):
self.page.hs_location = "The Moon" self.page.hs_location = "The Moon"
self.page.extinguishers_location = "With the rest of the fire" self.page.extinguishers_location = "With the rest of the fire"
# If we do this first the search fails, for ... reasons # If we do this first the search fails, for ... reasons
self.page.power_mic.search(self.profile.name) self.page.power_mic.search("Test") # FIXME
# self.page.power_mic.toggle() self.page.power_mic.toggle()
self.assertFalse(self.page.power_mic.is_open) self.assertFalse(self.page.power_mic.is_open)
vehicle_name = 'Brian' vehicle_name = 'Brian'

View File

@@ -1,14 +1,12 @@
from datetime import date from datetime import date
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.core.management import call_command
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import override_settings
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
from pytest_django.asserts import assertRedirects, assertNotContains, assertContains from pytest_django.asserts import assertRedirects, assertNotContains, assertContains
import PyRIGS.tests.test_unit
from PyRIGS.tests.base import assert_times_almost_equal, assert_oembed, login from PyRIGS.tests.base import assert_times_almost_equal, assert_oembed, login
from RIGS import models from RIGS import models
@@ -369,20 +367,3 @@ def test_ra_redirect(admin_client, admin_user, ra):
response = admin_client.get(request_url, follow=True) response = admin_client.get(request_url, follow=True)
assertRedirects(response, expected_url, status_code=302, target_status_code=200) assertRedirects(response, expected_url, status_code=302, target_status_code=200)
def test_production_exception():
from django.core.management.base import CommandError
with pytest.raises(CommandError):
call_command("generateSampleRIGSData")
@pytest.mark.django_db(transaction=True)
def test_generate_sample_data(settings):
settings.DEBUG = True
# Run the management command and check there are no exceptions
call_command('generateSampleUserData')
call_command('generateSampleRIGSData')
# Check there are lots of events
assert models.Event.objects.all().count() > 100

View File

@@ -5,22 +5,31 @@ import datetime
@pytest.fixture @pytest.fixture
def category(db): def category(db):
return models.AssetCategory.objects.create(name="Sound") category = models.AssetCategory.objects.create(name="Sound")
yield category
category.delete()
@pytest.fixture @pytest.fixture
def status(db): def status(db):
return models.AssetStatus.objects.create(name="Broken", should_show=True) status = models.AssetStatus.objects.create(name="Broken", should_show=True)
yield status
status.delete()
@pytest.fixture @pytest.fixture
def test_cable(db, category, status): def test_cable(db, category, status):
connector = models.Connector.objects.create(description="16A IEC", current_rating=16, voltage_rating=240, num_pins=3) 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) cable_type = models.CableType.objects.create(circuits=11, cores=3, plug=connector, socket=connector)
return models.Asset.objects.create(asset_id="9666", 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") cable = models.Asset.objects.create(asset_id="9666", 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")
yield cable
connector.delete()
cable_type.delete()
cable.delete()
@pytest.fixture @pytest.fixture
def test_asset(db, category, status): def test_asset(db, category, status):
asset = models.Asset.objects.create(asset_id="91991", description="Spaceflower", status=status, category=category, date_acquired=datetime.date(1991, 12, 26)) asset = models.Asset.objects.create(asset_id="91991", description="Spaceflower", status=status, category=category, date_acquired=datetime.date(1991, 12, 26))
return asset yield asset
asset.delete()

View File

@@ -1,71 +0,0 @@
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 PyRIGS.tests.base import assert_oembed, login
from assets import models
from django.utils import timezone
@pytest.fixture(scope='class', autouse=True)
def run_sample_data(django_db_blocker): # We need stuff setup so we don't get 404 errors everywhere
with django_db_blocker.unblock():
from django.conf import settings
settings.DEBUG = True
call_command('generateSampleUserData')
call_command('generateSampleAssetsData')
settings.DEBUG = False
class TestAccess():
def test_basic_access(client):
client.logout()
assert client.login(username="basic", password="basic")
url = reverse('asset_list')
response = client.get(url)
# Check edit and duplicate buttons NOT shown in list
assertNotContains(response, 'Edit')
assertNotContains(response, 'Duplicate') # If this line is randomly failing, check the debug toolbar HTML hasn't crept in
url = reverse('asset_detail', kwargs={'pk': 1})
response = client.get(url)
assertNotContains(response, 'Purchase Details')
assertNotContains(response, 'View Revision History')
urls = {'asset_history', 'asset_update', 'asset_duplicate'}
for url_name in urls:
request_url = reverse(url_name, kwargs={'pk': 1})
response = client.get(request_url, follow=True)
assert response.status_code == 403
request_url = reverse('supplier_create')
response = client.get(request_url, follow=True)
assert response.status_code == 403
request_url = reverse('supplier_update', kwargs={'pk': 1})
response = client.get(request_url, follow=True)
assert response.status_code == 403
def test_keyholder_access(client):
client.logout()
assert client.login(username="keyholder", password="keyholder")
url = reverse('asset_list')
response = client.get(url)
# Check edit and duplicate buttons shown in list
assertContains(response, 'Edit')
assertContains(response, 'Duplicate')
url = reverse('asset_detail', kwargs={'pk': 1})
response = client.get(url)
assertContains(response, 'Purchase Details')
assertContains(response, 'View Revision History')

View File

@@ -313,6 +313,7 @@ class TestAssetAudit(AutoLoginTest):
# Now do it properly # Now do it properly
self.page.modal.description = new_desc = "A BIG hammer" self.page.modal.description = new_desc = "A BIG hammer"
self.page.modal.submit() self.page.modal.submit()
self.driver.implicitly_wait(4)
self.wait.until(animation_is_finished()) self.wait.until(animation_is_finished())
submit_time = timezone.now() submit_time = timezone.now()
# Check data is correct # Check data is correct

View File

@@ -1,7 +1,6 @@
import datetime import datetime
import pytest import pytest
from django.core.management import call_command
from django.urls import reverse from django.urls import reverse
from pytest_django.asserts import assertFormError, assertRedirects, assertContains, assertNotContains from pytest_django.asserts import assertFormError, assertRedirects, assertContains, assertNotContains
@@ -130,23 +129,3 @@ def assert_asset_form_errors(response):
assertFormError(response, 'form', 'date_sold', 'Cannot sell an item before it is acquired') assertFormError(response, 'form', 'date_sold', 'Cannot sell an item before it is acquired')
assertFormError(response, 'form', 'purchase_price', 'A price cannot be negative') assertFormError(response, 'form', 'purchase_price', 'A price cannot be negative')
assertFormError(response, 'form', 'salvage_value', 'A price cannot be negative') assertFormError(response, 'form', 'salvage_value', 'A price cannot be negative')
def test_production_exception(client):
from django.core.management.base import CommandError
with pytest.raises(CommandError, match=".*production"):
call_command('generateSampleAssetsData')
call_command('deleteSampleData')
@pytest.mark.django_db(transaction=True)
def test_generate_sample_data(settings):
settings.DEBUG = True
print(models.AssetCategory.objects.all())
# Run the management command and check there are no exceptions
call_command('generateSampleAssetsData')
# Check there are lots
assert models.Asset.objects.all().count() > 50
assert models.Supplier.objects.all().count() > 50

View File

@@ -1,6 +1,10 @@
from django.conf import settings from django.conf import settings
import django import django
import pytest import pytest
from django.core.management import call_command
from RIGS.models import VatRate
import random
from django.db import connection
def pytest_configure(): def pytest_configure():
@@ -13,7 +17,6 @@ def pytest_configure():
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def splinter_webdriver(): def splinter_webdriver():
"""Override splinter webdriver name."""
return 'chrome' return 'chrome'
@@ -22,12 +25,8 @@ def splinter_screenshot_dir():
return 'screenshots/' return 'screenshots/'
def _has_transactional_marker(item): @pytest.fixture(autouse=True) # Also enables DB access for all tests as a useful side effect
db_marker = item.get_closest_marker("django_db") def vat_rate(db):
if db_marker and db_marker.kwargs.get("transaction"): vat_rate = VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
return 1 yield vat_rate
return 0 vat_rate.delete()
def pytest_collection_modifyitems(items): # Always run database-mulching tests last
items.sort(key=_has_transactional_marker)

View File

@@ -2,3 +2,4 @@
DJANGO_SETTINGS_MODULE = PyRIGS.settings DJANGO_SETTINGS_MODULE = PyRIGS.settings
filterwarnings = filterwarnings =
ignore:.*site-packages.*:DeprecationWarning ignore:.*site-packages.*:DeprecationWarning
addopts = --create-db