Move user/group setup into new generateSampleUserData command

This commit is contained in:
2021-02-04 15:44:07 +00:00
parent 6cb3d1855a
commit 462a16ec42
20 changed files with 300 additions and 253 deletions

View File

@@ -64,7 +64,7 @@ class Command(BaseCommand):
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 = 9000
pk = 1
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 = 200 # Offset to avoid other asset IDs
pk = 9000 # Offset to avoid other asset IDs
for i in range(100):
asset = models.Asset(
pk=pk,

View File

@@ -25,6 +25,8 @@
{% button 'view' url='asset_detail' pk=item.asset_id clazz="btn-sm" %}
{% if perms.assets.change_asset %}
{% button 'edit' url='asset_update' pk=item.asset_id clazz="btn-sm" %}
{% endif %}
{% if perms.assets.add_asset %}
{% button 'duplicate' url='asset_duplicate' pk=item.asset_id clazz="btn-sm" %}
{% endif %}
</div>

20
assets/tests/conftest.py Normal file
View File

@@ -0,0 +1,20 @@
import pytest
from assets import models
import datetime
@pytest.fixture
def test_cable(db):
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")
@pytest.fixture
def test_asset(db):
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

View File

@@ -0,0 +1,70 @@
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
pytestmark = pytest.mark.django_db
@pytest.fixture(scope='session')
def django_db_setup(django_db_setup, 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
def test_basic_access(client):
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')
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, django_user_model):
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

@@ -5,7 +5,7 @@ from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from PyRIGS.tests.base import AutoLoginTest, screenshot_failure_cls, assert_times_equal
from PyRIGS.tests.base import AutoLoginTest, screenshot_failure_cls, assert_times_almost_equal
from PyRIGS.tests.pages import animation_is_finished
from assets import models
from . import pages
@@ -319,7 +319,7 @@ class TestAssetAudit(AutoLoginTest):
self.assertEqual(self.asset.description, new_desc)
# Make sure audit 'log' was filled out
self.assertEqual(self.profile.initials, self.asset.last_audited_by.initials)
assert_times_equal(submit_time, self.asset.last_audited_at)
assert_times_almost_equal(submit_time, self.asset.last_audited_at)
# Check we've removed it from the 'needing audit' list
self.assertNotIn(self.asset.asset_id, self.page.assets)

View File

@@ -11,35 +11,34 @@ from PyRIGS.tests.base import assert_oembed, login
from assets import models
from django.utils import timezone
pytestmark = pytest.mark.django_db
def test_supplier_create(client, django_user_model):
login(client, django_user_model)
def test_supplier_create(admin_client):
url = reverse('supplier_create')
response = client.post(url)
response = admin_client.post(url)
assertFormError(response, 'form', 'name', 'This field is required.')
def test_supplier_edit(client, django_user_model):
login(client, django_user_model)
def test_supplier_edit(admin_client):
supplier = models.Supplier.objects.create(name="Gadgetron Corporation")
url = reverse('supplier_update', kwargs={'pk': supplier.pk})
response = client.post(url, {'name': ""})
response = admin_client.post(url, {'name': ""})
assertFormError(response, 'form', 'name', 'This field is required.')
def test_404(client, django_user_model):
login(client, django_user_model)
def test_404(admin_client):
urls = {'asset_detail', 'asset_update', 'asset_duplicate', 'supplier_detail', 'supplier_update'}
for url_name in urls:
request_url = reverse(url_name, kwargs={'pk': "0000"})
response = client.get(request_url, follow=True)
response = admin_client.get(request_url, follow=True)
assert response.status_code == 404
def test_embed_login_redirect(client, django_user_model):
request_url = reverse('asset_embed', kwargs={'pk': create_test_asset().asset_id})
def test_embed_login_redirect(client, django_user_model, test_asset):
request_url = reverse('asset_embed', kwargs={'pk': test_asset.asset_id})
expected_url = "{0}?next={1}".format(reverse('login_embed'), request_url)
# Request the page and check it redirects
@@ -60,8 +59,8 @@ def test_login_cookie_warning(client, django_user_model):
assert "Cookies do not seem to be enabled" in str(response.content)
def test_x_frame_headers(client, django_user_model):
asset_url = reverse('asset_embed', kwargs={'pk': create_test_asset().asset_id})
def test_x_frame_headers(client, django_user_model, test_asset):
asset_url = reverse('asset_embed', kwargs={'pk': test_asset.asset_id})
login_url = reverse('login_embed')
login(client, django_user_model)
@@ -75,11 +74,11 @@ def test_x_frame_headers(client, django_user_model):
response._headers["X-Frame-Options"]
def test_oembed(client):
asset = create_test_asset()
asset_url = reverse('asset_detail', kwargs={'pk': asset.asset_id})
asset_embed_url = reverse('asset_embed', kwargs={'pk': asset.asset_id})
oembed_url = reverse('asset_oembed', kwargs={'pk': asset.asset_id})
def test_oembed(client, test_asset):
client.logout()
asset_url = reverse('asset_detail', kwargs={'pk': test_asset.asset_id})
asset_embed_url = reverse('asset_embed', kwargs={'pk': test_asset.asset_id})
oembed_url = reverse('asset_oembed', kwargs={'pk': test_asset.asset_id})
alt_oembed_url = reverse('asset_oembed', kwargs={'pk': 999})
alt_asset_embed_url = reverse('asset_embed', kwargs={'pk': 999})
@@ -87,8 +86,9 @@ def test_oembed(client):
assert_oembed(alt_asset_embed_url, alt_oembed_url, client, asset_embed_url, asset_url, oembed_url)
@override_settings(DEBUG=True)
def test_generate_sample_data(client):
@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('generateSampleAssetsData')
@@ -97,14 +97,6 @@ def test_generate_sample_data(client):
assert models.Supplier.objects.all().count() > 50
@override_settings(DEBUG=True)
def test_delete_sample_data(client):
call_command('deleteSampleData')
assert models.Asset.objects.all().count() == 0
assert models.Supplier.objects.all().count() == 0
def test_production_exception(client):
from django.core.management.base import CommandError
@@ -113,34 +105,30 @@ def test_production_exception(client):
call_command('deleteSampleData')
def test_asset_create(client, django_user_model):
login(client, django_user_model)
response = client.post(reverse('asset_create'), {'date_sold': '2000-01-01', 'date_acquired': '2020-01-01', 'purchase_price': '-30', 'salvage_value': '-30'})
def test_asset_create(admin_client):
response = admin_client.post(reverse('asset_create'), {'date_sold': '2000-01-01', 'date_acquired': '2020-01-01', 'purchase_price': '-30', 'salvage_value': '-30'})
assertFormError(response, 'form', 'asset_id', 'This field is required.')
assert_asset_form_errors(response)
def test_cable_create(client, django_user_model):
login(client, django_user_model)
response = client.post(reverse('asset_create'), {'asset_id': 'X$%A', 'is_cable': True})
def test_cable_create(admin_client):
response = admin_client.post(reverse('asset_create'), {'asset_id': 'X$%A', 'is_cable': True})
assertFormError(response, 'form', 'asset_id', 'An Asset ID can only consist of letters and numbers, with a final number')
assertFormError(response, 'form', 'cable_type', 'A cable must have a type')
assertFormError(response, 'form', 'length', 'The length of a cable must be more than 0')
assertFormError(response, 'form', 'csa', 'The CSA of a cable must be more than 0')
def test_asset_edit(client, django_user_model):
login(client, django_user_model)
url = reverse('asset_update', kwargs={'pk': create_test_asset().asset_id})
response = client.post(url, {'date_sold': '2000-12-01', 'date_acquired': '2020-12-01', 'purchase_price': '-50', 'salvage_value': '-50', 'description': "", 'status': "", 'category': ""})
def test_asset_edit(admin_client, test_asset):
url = reverse('asset_update', kwargs={'pk': test_asset.asset_id})
response = admin_client.post(url, {'date_sold': '2000-12-01', 'date_acquired': '2020-12-01', 'purchase_price': '-50', 'salvage_value': '-50', 'description': "", 'status': "", 'category': ""})
assert_asset_form_errors(response)
def test_cable_edit(client, django_user_model):
login(client, django_user_model)
url = reverse('asset_update', kwargs={'pk': create_test_cable().asset_id})
def test_cable_edit(admin_client, test_cable):
url = reverse('asset_update', kwargs={'pk': test_cable.asset_id})
# TODO Why do I have to send is_cable=True here?
response = client.post(url, {'is_cable': True, 'length': -3, 'csa': -3})
response = admin_client.post(url, {'is_cable': True, 'length': -3, 'csa': -3})
# TODO Can't figure out how to select the 'none' option...
# assertFormError(response, 'form', 'cable_type', 'A cable must have a type')
@@ -148,71 +136,14 @@ def test_cable_edit(client, django_user_model):
assertFormError(response, 'form', 'csa', 'The CSA of a cable must be more than 0')
def test_asset_duplicate(client, django_user_model):
login(client, django_user_model)
url = reverse('asset_duplicate', kwargs={'pk': create_test_cable().asset_id})
response = client.post(url, {'is_cable': True, 'length': 0, 'csa': 0})
def test_asset_duplicate(admin_client, test_cable):
url = reverse('asset_duplicate', kwargs={'pk': test_cable.asset_id})
response = admin_client.post(url, {'is_cable': True, 'length': 0, 'csa': 0})
assertFormError(response, 'form', 'length', 'The length of a cable must be more than 0')
assertFormError(response, 'form', 'csa', 'The CSA of a cable must be more than 0')
def test_basic_access(client, django_user_model):
create_asset_one()
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')
url = reverse('asset_detail', kwargs={'pk': "9000"})
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': "9000"})
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, django_user_model):
create_asset_one()
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': "9000"})
response = client.get(url)
assertContains(response, 'Purchase Details')
assertContains(response, 'View Revision History')
@override_settings(DEBUG=True)
def create_asset_one():
# Shortcut to create the levels - bonus side effect of testing the command (hopefully) matches production
call_command('generateSampleAssetsData')
# Create an asset with ID 1 to make things easier in loops (we can always use pk=1)
category = models.AssetCategory.objects.create(name="Number One")
status = models.AssetStatus.objects.create(name="Probably Fine", should_show=True)
return models.Asset.objects.create(asset_id="1", description="Half Price Fish", status=status, category=category, date_acquired=datetime.date(2020, 2, 1))
def assert_asset_form_errors(response):
assertFormError(response, 'form', 'description', 'This field is required.')
assertFormError(response, 'form', 'status', 'This field is required.')
@@ -220,18 +151,3 @@ def assert_asset_form_errors(response):
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', 'salvage_value', 'A price cannot be negative')
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")
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