bda.tests -- Split view tests and use shared test helpers

This commit is contained in:
Aurélien Delobelle 2018-10-28 14:31:10 +01:00
parent a71fbb0ed3
commit f8610d4ff1
3 changed files with 244 additions and 174 deletions

View file

@ -1,221 +1,198 @@
import json import json
import os
from datetime import timedelta from datetime import timedelta
from unittest import mock
from urllib.parse import urlencode
from django.conf import settings from django.test import TestCase
from django.contrib.auth.models import User
from django.core.management import call_command
from django.test import Client, TestCase
from django.utils import timezone from django.utils import timezone
from ..models import CategorieSpectacle, Salle, Spectacle, Tirage from .testcases import BdATestHelpers, BdAViewTestCaseMixin
def create_user(username, is_cof=False, is_buro=False): class InscriptionViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
user = User.objects.create_user(username=username, password=username) url_name = "bda-tirage-inscription"
user.profile.is_cof = is_cof
user.profile.is_buro = is_buro http_methods = ["GET", "POST"]
user.profile.save()
return user auth_user = "bda_member"
auth_forbidden = [None, "bda_other"]
bda_testdata = True
@property
def url_kwargs(self):
return {"tirage_id": self.tirage.id}
@property
def url_expected(self):
return "/bda/inscription/{}".format(self.tirage.id)
def user_is_cof(user): class PlacesViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
return (user is not None) and user.profile.is_cof url_name = "bda-places-attribuees"
auth_user = "bda_member"
auth_forbidden = [None, "bda_other"]
bda_testdata = True
@property
def url_kwargs(self):
return {"tirage_id": self.tirage.id}
@property
def url_expected(self):
return "/bda/places/{}".format(self.tirage.id)
def user_is_staff(user): class EtatPlacesViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
return (user is not None) and user.profile.is_buro url_name = "bda-etat-places"
auth_user = "bda_member"
auth_forbidden = [None, "bda_other"]
bda_testdata = True
@property
def url_kwargs(self):
return {"tirage_id": self.tirage.id}
@property
def url_expected(self):
return "/bda/etat-places/{}".format(self.tirage.id)
class BdATestHelpers: class TirageViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
def setUp(self): url_name = "bda-tirage"
# Some user with different access privileges
staff = create_user(username="bda_staff", is_cof=True, is_buro=True)
staff_c = Client()
staff_c.force_login(staff)
member = create_user(username="bda_member", is_cof=True) http_methods = ["GET", "POST"]
member_c = Client()
member_c.force_login(member)
other = create_user(username="bda_other") auth_user = "bda_staff"
other_c = Client() auth_forbidden = [None, "bda_other", "bda_member"]
other_c.force_login(other)
self.client_matrix = [ bda_testdata = True
(staff, staff_c),
(member, member_c),
(other, other_c),
(None, Client()),
]
def require_custommails(self): @property
data_file = os.path.join( def url_kwargs(self):
settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json" return {"tirage_id": self.tirage.id}
)
call_command("syncmails", data_file, verbosity=0)
def check_restricted_access( @property
self, url, validate_user=user_is_cof, redirect_url=None def url_expected(self):
): return "/bda/tirage/{}".format(self.tirage.id)
for (user, client) in self.client_matrix:
resp = client.get(url, follow=True)
if validate_user(user):
self.assertEqual(200, resp.status_code)
elif redirect_url:
self.assertRedirects(resp, redirect_url)
elif user is None:
# client is not logged in
login_url = "/login"
if url:
login_url += "?{}".format(urlencode({"next": url}, safe="/"))
self.assertRedirects(resp, login_url)
else:
self.assertEqual(403, resp.status_code)
def test_perform_tirage_disabled(self):
class TestBdAViews(BdATestHelpers, TestCase):
def setUp(self):
# Signals handlers on login/logout send messages.
# Due to the way the Django' test Client performs login, this raise an
# error. As workaround, we mock the Django' messages module.
patcher_messages = mock.patch("gestioncof.signals.messages")
patcher_messages.start()
self.addCleanup(patcher_messages.stop)
# Set up the helpers
super().setUp()
# Some BdA stuff
self.tirage = Tirage.objects.create(
title="Test tirage",
appear_catalogue=True,
ouverture=timezone.now(),
fermeture=timezone.now(),
)
self.category = CategorieSpectacle.objects.create(name="Category")
self.location = Salle.objects.create(name="here")
Spectacle.objects.bulk_create(
[
Spectacle(
title="foo",
date=timezone.now(),
location=self.location,
price=0,
slots=42,
tirage=self.tirage,
listing=False,
category=self.category,
),
Spectacle(
title="bar",
date=timezone.now(),
location=self.location,
price=1,
slots=142,
tirage=self.tirage,
listing=False,
category=self.category,
),
Spectacle(
title="baz",
date=timezone.now(),
location=self.location,
price=2,
slots=242,
tirage=self.tirage,
listing=False,
category=self.category,
),
]
)
def test_bda_inscriptions(self):
# TODO: test the form
url = "/bda/inscription/{}".format(self.tirage.id)
self.check_restricted_access(url)
def test_bda_places(self):
url = "/bda/places/{}".format(self.tirage.id)
self.check_restricted_access(url)
def test_etat_places(self):
url = "/bda/etat-places/{}".format(self.tirage.id)
self.check_restricted_access(url)
def test_perform_tirage(self):
# Only staff member can perform a tirage
url = "/bda/tirage/{}".format(self.tirage.id)
self.check_restricted_access(url, validate_user=user_is_staff)
_, staff_c = self.client_matrix[0]
# Cannot be performed if disabled # Cannot be performed if disabled
self.tirage.enable_do_tirage = False self.tirage.enable_do_tirage = False
self.tirage.save() self.tirage.save()
resp = staff_c.get(url) resp = self.client.get(self.url)
self.assertTemplateUsed(resp, "tirage-failed.html") self.assertTemplateUsed(resp, "tirage-failed.html")
def test_perform_tirage_opened_registrations(self):
# Cannot be performed if registrations are still open # Cannot be performed if registrations are still open
self.tirage.enable_do_tirage = True self.tirage.enable_do_tirage = True
self.tirage.fermeture = timezone.now() + timedelta(seconds=3600) self.tirage.fermeture = timezone.now() + timedelta(seconds=3600)
self.tirage.save() self.tirage.save()
resp = staff_c.get(url) resp = self.client.get(self.url)
self.assertTemplateUsed(resp, "tirage-failed.html") self.assertTemplateUsed(resp, "tirage-failed.html")
def test_perform_tirage(self):
# Otherwise, perform the tirage # Otherwise, perform the tirage
self.tirage.enable_do_tirage = True
self.tirage.fermeture = timezone.now() self.tirage.fermeture = timezone.now()
self.tirage.save() self.tirage.save()
resp = staff_c.get(url) resp = self.client.get(self.url)
self.assertTemplateNotUsed(resp, "tirage-failed.html") self.assertTemplateNotUsed(resp, "tirage-failed.html")
def test_spectacles_list(self):
url = "/bda/spectacles/{}".format(self.tirage.id)
self.check_restricted_access(url, validate_user=user_is_staff)
def test_spectacle_detail(self): class SpectacleListViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
show = self.tirage.spectacle_set.first() url_name = "bda-liste-spectacles"
url = "/bda/spectacles/{}/{}".format(self.tirage.id, show.id)
self.check_restricted_access(url, validate_user=user_is_staff)
def test_tirage_unpaid(self): auth_user = "bda_staff"
url = "/bda/spectacles/unpaid/{}".format(self.tirage.id) auth_forbidden = [None, "bda_other", "bda_member"]
self.check_restricted_access(url, validate_user=user_is_staff)
def test_send_reminders(self): bda_testdata = True
@property
def url_kwargs(self):
return {"tirage_id": self.tirage.id}
@property
def url_expected(self):
return "/bda/spectacles/{}".format(self.tirage.id)
class SpectacleViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
url_name = "bda-spectacle"
auth_user = "bda_staff"
auth_forbidden = [None, "bda_other", "bda_member"]
bda_testdata = True
@property
def url_kwargs(self):
return {"tirage_id": self.tirage.id, "spectacle_id": self.show1.id}
@property
def url_expected(self):
return "/bda/spectacles/{}/{}".format(self.tirage.id, self.show1.id)
class UnpaidViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
url_name = "bda-unpaid"
auth_user = "bda_staff"
auth_forbidden = [None, "bda_other", "bda_member"]
bda_testdata = True
@property
def url_kwargs(self):
return {"tirage_id": self.tirage.id}
@property
def url_expected(self):
return "/bda/spectacles/unpaid/{}".format(self.tirage.id)
class SendRemindersViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
url_name = "bda-rappels"
auth_user = "bda_staff"
auth_forbidden = [None, "bda_other", "bda_member"]
bda_testdata = True
@property
def url_kwargs(self):
return {"spectacle_id": self.show1.id}
@property
def url_expected(self):
return "/bda/mails-rappel/{}".format(self.show1.id)
def test_post(self):
self.require_custommails() self.require_custommails()
# Just get the page resp = self.client.post(self.url)
show = self.tirage.spectacle_set.first()
url = "/bda/mails-rappel/{}".format(show.id)
self.check_restricted_access(url, validate_user=user_is_staff)
# Actually send the reminder emails
_, staff_c = self.client_matrix[0]
resp = staff_c.post(url)
self.assertEqual(200, resp.status_code) self.assertEqual(200, resp.status_code)
# TODO: check that emails are sent # TODO: check that emails are sent
def test_catalogue_api(self):
class CatalogueViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
auth_user = None
auth_forbidden = []
bda_testdata = True
def test_api_list(self):
url_list = "/bda/catalogue/list" url_list = "/bda/catalogue/list"
url_details = "/bda/catalogue/details?id={}".format(self.tirage.id) resp = self.client.get(url_list)
url_descriptions = "/bda/catalogue/descriptions?id={}".format(self.tirage.id)
# Anyone can get
def anyone_can_get(url):
self.check_restricted_access(url, validate_user=lambda user: True)
anyone_can_get(url_list)
anyone_can_get(url_details)
anyone_can_get(url_descriptions)
# The resulting JSON contains the information
_, client = self.client_matrix[0]
# List
resp = client.get(url_list)
self.assertJSONEqual( self.assertJSONEqual(
resp.content.decode("utf-8"), resp.content.decode("utf-8"),
[{"id": self.tirage.id, "title": self.tirage.title}], [{"id": self.tirage.id, "title": self.tirage.title}],
) )
# Details def test_api_details(self):
resp = client.get(url_details) url_details = "/bda/catalogue/details?id={}".format(self.tirage.id)
resp = self.client.get(url_details)
self.assertJSONEqual( self.assertJSONEqual(
resp.content.decode("utf-8"), resp.content.decode("utf-8"),
{ {
@ -224,8 +201,9 @@ class TestBdAViews(BdATestHelpers, TestCase):
}, },
) )
# Descriptions def test_api_descriptions(self):
resp = client.get(url_descriptions) url_descriptions = "/bda/catalogue/descriptions?id={}".format(self.tirage.id)
resp = self.client.get(url_descriptions)
raw = resp.content.decode("utf-8") raw = resp.content.decode("utf-8")
try: try:
results = json.loads(raw) results = json.loads(raw)

75
bda/tests/testcases.py Normal file
View file

@ -0,0 +1,75 @@
import os
from django.conf import settings
from django.core.management import call_command
from django.utils import timezone
from shared.tests.testcases import ViewTestCaseMixin
from ..models import CategorieSpectacle, Salle, Spectacle, Tirage
from .utils import create_user
class BdAViewTestCaseMixin(ViewTestCaseMixin):
def get_users_base(self):
return {
"bda_other": create_user(username="bda_other"),
"bda_member": create_user(username="bda_member", is_cof=True),
"bda_staff": create_user(username="bda_staff", is_cof=True, is_buro=True),
}
class BdATestHelpers:
bda_testdata = False
def setUp(self):
super().setUp()
if self.bda_testdata:
self.load_bda_testdata()
def require_custommails(self):
data_file = os.path.join(
settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json"
)
call_command("syncmails", data_file, verbosity=0)
def load_bda_testdata(self):
self.tirage = Tirage.objects.create(
title="Test tirage",
appear_catalogue=True,
ouverture=timezone.now(),
fermeture=timezone.now(),
)
self.category = CategorieSpectacle.objects.create(name="Category")
self.location = Salle.objects.create(name="here")
self.show1 = Spectacle.objects.create(
title="foo",
date=timezone.now(),
location=self.location,
price=0,
slots=42,
tirage=self.tirage,
listing=False,
category=self.category,
)
self.show2 = Spectacle.objects.create(
title="bar",
date=timezone.now(),
location=self.location,
price=1,
slots=142,
tirage=self.tirage,
listing=False,
category=self.category,
)
self.show3 = Spectacle.objects.create(
title="baz",
date=timezone.now(),
location=self.location,
price=2,
slots=242,
tirage=self.tirage,
listing=False,
category=self.category,
)

17
bda/tests/utils.py Normal file
View file

@ -0,0 +1,17 @@
from django.contrib.auth.models import User
def create_user(username, is_cof=False, is_buro=False):
user = User.objects.create_user(username=username, password=username)
user.profile.is_cof = is_cof
user.profile.is_buro = is_buro
user.profile.save()
return user
def user_is_cof(user):
return (user is not None) and user.profile.is_cof
def user_is_staff(user):
return (user is not None) and user.profile.is_buro