Compare commits

...

2 Commits

Author SHA1 Message Date
Tris Forster
75de40f2bd Cleaned up access tests 2023-02-23 10:22:58 +11:00
Tris Forster
295999eaef Refactored test access (eventually) 2023-02-22 18:46:12 +11:00
2 changed files with 105 additions and 120 deletions

View File

@ -0,0 +1,56 @@
from django.test import TestCase
from interface import models, utils
from django.contrib.auth.models import User
from django.utils import timezone
from datetime import timedelta
class AccessTestCase(TestCase):
USERS = ()
ENSEMBLES = ()
PROJECTS = ()
@classmethod
def setUpTestData(cls):
cls.users = {}
for details in cls.USERS:
cls.users[details['username']] = User.objects.create_user(**details)
now = timezone.now()
cls.ensembles = {}
for details in cls.ENSEMBLES:
admins = details.pop('admins', [])
obj = models.Ensemble.objects.create(**details)
for admin in admins:
obj.admins.add(cls.users[admin])
cls.ensembles[obj.slug] = obj
cls.projects = {}
for name, ensemble, when in cls.PROJECTS:
obj = cls.ensembles[ensemble].projects.create(name=name, event_date=now+timedelta(days=when))
cls.projects[name] = obj
return
def login(self, user, passwd):
response = self.client.post('/login', {'username': user, 'password': passwd})
self.assertEqual(response.status_code, 302, f"Failed to login as {user}")
def authorize(self, model, **kwargs):
object = model.objects.get(**kwargs)
response = self.client.get(f'{object.get_absolute_url()}?auth={object.auth()}')
self.assertEqual(response.status_code, 302)
def assertAccess(self, urls):
for url, expected in urls.items():
response = self.client.get(url)
self.assertEqual(response.status_code == 200, expected, f"Expected {expected} for {url} (status: {response.status_code})")
def assertObjectList(self, response, expected, element='name'):
self.assertEqual(response.status_code, 200, "No result returned")
objects = response.context['object_list'].values_list(element, flat=True)
self.assertEqual(list(objects), expected)

View File

@ -2,85 +2,88 @@ from django.test import TestCase, Client
from interface import models, utils from interface import models, utils
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils import timezone
from datetime import timedelta
class AccessTestCase(TestCase): from . import AccessTestCase
@classmethod class InterfaceAccessTestCase(AccessTestCase):
def setUpTestData(cls):
admin = User.objects.create_user(username='admin', password='foobar', is_superuser=True, is_staff=True) USERS = (
homer = User.objects.create_user(username='homer', password='maggie') {'username': 'admin', 'password': 'secret', 'is_superuser': True, 'is_staff': True},
{'username': 'homer', 'password': 'maggie'},
)
now = timezone.now() ENSEMBLES = (
{'name': 'The Be Sharps', 'slug': 'be-sharps', 'admins': ['homer']},
{'name': 'Lisa & the Bleeding Gums', 'slug': 'bleeding-gums'},
{'name': 'Party Posse'},
)
b_sharps = models.Ensemble.objects.create(name='The Be Sharps') PROJECTS = (
b_sharps.admins.add(homer) ('Baker St', 'bleeding-gums', -12),
bleeding_gums = models.Ensemble.objects.create(name='Lisa and the Bleeding Gums', slug='bleeding-gums') ('Navy Recruitment Day', 'party-posse', 6),
party_posse = models.Ensemble.objects.create(name="Party Posse", slug='party-posse') ('Barbershop Contest', 'be-sharps', 28),
('Open Mic Night', 'bleeding-gums', 1)
bleeding_gums.projects.create(name='Baker St', event_date=now-timedelta(days=12)) )
party_posse.projects.create(name='Navy Recruitment Day', event_date=now+timedelta(days=6))
b_sharps.projects.create(name='Baby on Board', event_date=now+timedelta(days=28))
bleeding_gums.projects.create(name='Open Mic Night', event_date=now+timedelta(hours=1))
def test_bad_login(self):
with self.assertRaisesMessage(self.failureException, 'Failed to login as admin'):
self.login('admin', 'admin')
def test_admin_ensembles(self): def test_admin_ensembles(self):
self.client.post('/login', {'username': 'admin', 'password': 'foobar'}) self.login('admin', 'secret')
response = self.client.get('/ensembles') response = self.client.get('/ensembles')
self.assertObjectList(response, ['Lisa and the Bleeding Gums', 'Party Posse', 'The Be Sharps']) self.assertObjectList(response, ['The Be Sharps', 'Lisa & the Bleeding Gums', 'Party Posse'])
self.assertContains(response, 'Django Admin') self.assertContains(response, 'Django Admin')
def test_admin_ensemble_permissions(self): def test_admin_ensemble_permissions(self):
self.client.post('/login', {'username': 'admin', 'password': 'foobar'}) self.login('admin', 'secret')
response = self.client.get('/ensembles/party-posse') response = self.client.get('/ensembles/party-posse')
self.assertTrue(response.context['request'].is_admin) self.assertTrue(response.context['request'].is_admin)
self.assertContains(response, "Add project") self.assertContains(response, "Add project")
self.assertAccess({ self.assertAccess({
'/ensembles/the-be-sharps': True, '/ensembles/be-sharps': True,
'/ensembles/bleeding-gums': True, '/ensembles/bleeding-gums': True,
'/ensembles/party-posse': True, '/ensembles/party-posse': True,
'/ensembles/unknown': False, '/ensembles/unknown': False,
'/ensembles/the-be-sharps/new-project': True, '/ensembles/be-sharps/new-project': True,
}) })
def test_admin_projects(self): def test_admin_projects(self):
self.client.post('/login', {'username': 'admin', 'password': 'foobar'}) self.login('admin', 'secret')
response = self.client.get('/projects') response = self.client.get('/projects')
self.assertObjectList(response, ['Open Mic Night', 'Navy Recruitment Day', 'Baby on Board']) self.assertObjectList(response, ['Open Mic Night', 'Navy Recruitment Day', 'Barbershop Contest'])
self.assertObjectList(self.client.get('/ensembles/bleeding-gums'), ['Open Mic Night']) self.assertObjectList(self.client.get('/ensembles/bleeding-gums'), ['Open Mic Night'])
self.assertObjectList(self.client.get('/ensembles/bleeding-gums?inactive'), ['Open Mic Night', 'Baker St']) self.assertObjectList(self.client.get('/ensembles/bleeding-gums?inactive'), ['Open Mic Night', 'Baker St'])
def test_user_ensembles(self): def test_user_ensembles(self):
self.client.post('/login', {'username': 'homer', 'password': 'maggie'}) self.login('homer', 'maggie')
response = self.client.get('/ensembles') response = self.client.get('/ensembles')
self.assertObjectList(response, ['The Be Sharps']) self.assertObjectList(response, ['The Be Sharps'])
self.assertNotContains(response, 'Django Admin') self.assertNotContains(response, 'Django Admin')
def test_user_ensemble_permissions(self): def test_user_ensemble_permissions(self):
self.client.post('/login', {'username': 'homer', 'password': 'maggie'}) self.login('homer', 'maggie')
response = self.client.get('/ensembles/the-be-sharps') response = self.client.get('/ensembles/be-sharps')
self.assertTrue(response.context['request'].is_admin) self.assertTrue(response.context['request'].is_admin)
self.assertContains(response, "Add project") self.assertContains(response, "Add project")
self.assertContains(response, 'Show all') self.assertContains(response, 'Show all')
self.assertAccess({ self.assertAccess({
'/ensembles/the-be-sharps': True, '/ensembles/be-sharps': True,
'/ensembles/bleeding-gums': False, '/ensembles/bleeding-gums': False,
'/ensembles/party-posse': False, '/ensembles/party-posse': False,
'/ensembles/the-be-sharps/new-project': True, '/ensembles/be-sharps/new-project': True,
'/ensembles/party-posse/new-project': False, '/ensembles/party-posse/new-project': False,
}) })
self.authorize(models.Ensemble, slug='bleeding-gums') self.authorize(models.Ensemble, slug='bleeding-gums')
self.assertAccess({ self.assertAccess({
'/ensembles/the-be-sharps': True, '/ensembles/be-sharps': True,
'/ensembles/bleeding-gums': True, '/ensembles/bleeding-gums': True,
'/ensembles/party-posse': False, '/ensembles/party-posse': False,
'/ensembles/the-be-sharps/new-project': True, '/ensembles/be-sharps/new-project': True,
'/ensembles/party-posse/new-project': False, '/ensembles/party-posse/new-project': False,
}) })
response = self.client.get('/ensembles/bleeding-gums') response = self.client.get('/ensembles/bleeding-gums')
@ -89,9 +92,9 @@ class AccessTestCase(TestCase):
self.assertNotContains(response, 'Show all') self.assertNotContains(response, 'Show all')
def test_user_projects(self): def test_user_projects(self):
self.client.post('/login', {'username': 'homer', 'password': 'maggie'}) self.login('homer', 'maggie')
response = self.client.get('/projects') response = self.client.get('/projects')
self.assertObjectList(response, ['Baby on Board']) self.assertObjectList(response, ['Barbershop Contest'])
response = self.client.get('/projects/3') response = self.client.get('/projects/3')
self.assertTrue(response.context['request'].is_admin) self.assertTrue(response.context['request'].is_admin)
@ -107,7 +110,7 @@ class AccessTestCase(TestCase):
self.authorize(models.Project, pk=4) self.authorize(models.Project, pk=4)
response = self.client.get('/projects') response = self.client.get('/projects')
self.assertObjectList(response, ['Open Mic Night', 'Baby on Board']) self.assertObjectList(response, ['Open Mic Night', 'Barbershop Contest'])
response = self.client.get('/projects/4') response = self.client.get('/projects/4')
self.assertFalse(response.context['request'].is_admin) self.assertFalse(response.context['request'].is_admin)
@ -125,7 +128,7 @@ class AccessTestCase(TestCase):
self.assertObjectList(response, ['Party Posse']) self.assertObjectList(response, ['Party Posse'])
self.assertAccess({ self.assertAccess({
'/ensembles/the-be-sharps': False, '/ensembles/be-sharps': False,
'/ensembles/party-posse': True, '/ensembles/party-posse': True,
'/ensembles/bleeding-gums': False, '/ensembles/bleeding-gums': False,
'/ensembles/unknown': False, '/ensembles/unknown': False,
@ -136,7 +139,7 @@ class AccessTestCase(TestCase):
def test_anon_authorized_project(self): def test_anon_authorized_project(self):
self.authorize(models.Project, pk=4) self.authorize(models.Project, pk=4)
self.assertObjectList(self.client.get('/projects'), ['Open Mic Night']) self.assertObjectList(self.client.get('/projects'), ['Open Mic Night'])
self.assertObjectList(self.client.get('/ensembles'), ['Lisa and the Bleeding Gums']) self.assertObjectList(self.client.get('/ensembles'), ['Lisa & the Bleeding Gums'])
self.assertAccess({ self.assertAccess({
'/projects/4': True, '/projects/4': True,
@ -148,92 +151,18 @@ class AccessTestCase(TestCase):
def test_anon_permission_denied(self): def test_anon_permission_denied(self):
self.assertAccess({ self.assertAccess({
'/ensembles': True, '/ensembles': True,
'/ensembles/the-be-sharps': False, '/ensembles/be-sharps': False,
'/ensembles/party-posse': False, '/ensembles/party-posse': False,
'/ensembles/bleeding-gums': False, '/ensembles/bleeding-gums': False,
'/ensembles/unknown': False, '/ensembles/unknown': False,
}) })
def authorize(self, model, **kwargs): def test_anon_deauthorize_project(self):
object = model.objects.get(**kwargs) self.authorize(models.Project, pk=4)
response = self.client.get(f'{object.get_absolute_url()}?auth={object.auth()}') self.assertAccess({
self.assertEqual(response.status_code, 302) '/projects/4': True
})
def assertAccess(self, urls): models.Project.objects.filter(pk=4).update(nonce=2)
for url, expected in urls.items(): self.assertAccess({
response = self.client.get(url) '/projects/4': False
self.assertEqual(response.status_code == 200, expected, f"Expected {expected} for {url} (status: {response.status_code})") })
def assertObjectList(self, response, expected, element='name'):
self.assertEqual(response.status_code, 200, "No result returned")
objects = response.context['object_list'].values_list(element, flat=True)
self.assertEqual(list(objects), expected)
"""
def test_redirect(self):
self.skipTest("No redirect")
response = self.client.get('/')
self.assertRedirects(response, '/register?')
def test_redirect_project(self):
response = self.client.get('/projects/1')
self.assertEqual(response.status_code, 404)
#def test_redirect_with_code(self):
# response = self.client.get('/?code=123-456-789')
# self.assertRedirects(response, '/register?code=123-456-789')
def test_register(self):
response = self.client.get('/ensembles/1')
self.assertEqual(response.status_code, 404)
url = utils.signed_url('register', group='ensemble', pk=1)
response = self.client.get(url + "i")
self.assertEqual(response.status_code, 400)
response = self.client.get(url)
self.assertRedirects(response, '/ensembles/1')
response = self.client.get('/ensembles/1')
self.assertEqual(response.context['object'].pk, 1)
response = self.client.get('/projects/1', )
def old_test_register(self):
response = self.client.post('/register', {'code': '123-456-789', })
self.assertFormError(response, 'form', 'passphrase', 'This field is required.')
response = self.client.post('/register', {'code': '123-456-789', 'passphrase': 'Foo'})
self.assertFormError(response, 'form', None, 'Incorrect code or passphrase')
response = self.client.post('/register', {'code': '12-34', 'passphrase': 'Homer'})
self.assertRedirects(response, '/')
response = self.client.get(response.url)
self.assertEqual(response.context['object'].pk, 1)
# revisting original url get redirected back to homepage
response = self.client.get('/?code=12-34')
response = self.client.get(response.url)
response = self.client.get(response.url)
self.assertEqual(response.context['object'].pk, 1)
# providing a new code
response = self.client.get('/?code=23-45')
self.assertRedirects(response, '/register?code=23-45')
response = self.client.get(response.url)
#self.assertQuerysetEqual(response.context['current'], ['<Ensemble: The Be Sharps>'])
#self.assertEqual(response.context['form'].code.initial, 'foo')
response = self.client.post('/register', {'code': '23-45', 'passphrase': 'maggie'})
self.assertRedirects(response, '/')
response = self.client.get('/')
self.assertEqual(response.context['object'].pk, 2)
# can use previous link to switch back without passphrase
response = self.client.get('/?code=12-34')
response = self.client.get(response.url)
response = self.client.get(response.url)
self.assertEqual(response.context['object'].pk, 1)
"""