diff --git a/bda/tests/test_views.py b/bda/tests/test_views.py index 7204a320..bd851dc7 100644 --- a/bda/tests/test_views.py +++ b/bda/tests/test_views.py @@ -1,221 +1,198 @@ import json -import os from datetime import timedelta -from unittest import mock -from urllib.parse import urlencode -from django.conf import settings -from django.contrib.auth.models import User -from django.core.management import call_command -from django.test import Client, TestCase +from django.test import TestCase 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): - 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 +class InscriptionViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase): + url_name = "bda-tirage-inscription" + + http_methods = ["GET", "POST"] + + 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): - return (user is not None) and user.profile.is_cof +class PlacesViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase): + 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): - return (user is not None) and user.profile.is_buro +class EtatPlacesViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase): + 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: - def setUp(self): - # 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) +class TirageViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase): + url_name = "bda-tirage" - member = create_user(username="bda_member", is_cof=True) - member_c = Client() - member_c.force_login(member) + http_methods = ["GET", "POST"] - other = create_user(username="bda_other") - other_c = Client() - other_c.force_login(other) + auth_user = "bda_staff" + auth_forbidden = [None, "bda_other", "bda_member"] - self.client_matrix = [ - (staff, staff_c), - (member, member_c), - (other, other_c), - (None, Client()), - ] + bda_testdata = True - def require_custommails(self): - data_file = os.path.join( - settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json" - ) - call_command("syncmails", data_file, verbosity=0) + @property + def url_kwargs(self): + return {"tirage_id": self.tirage.id} - def check_restricted_access( - self, url, validate_user=user_is_cof, redirect_url=None - ): - 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) + @property + def url_expected(self): + return "/bda/tirage/{}".format(self.tirage.id) - -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] + def test_perform_tirage_disabled(self): # Cannot be performed if disabled self.tirage.enable_do_tirage = False self.tirage.save() - resp = staff_c.get(url) + resp = self.client.get(self.url) self.assertTemplateUsed(resp, "tirage-failed.html") + + def test_perform_tirage_opened_registrations(self): # Cannot be performed if registrations are still open self.tirage.enable_do_tirage = True self.tirage.fermeture = timezone.now() + timedelta(seconds=3600) self.tirage.save() - resp = staff_c.get(url) + resp = self.client.get(self.url) self.assertTemplateUsed(resp, "tirage-failed.html") + + def test_perform_tirage(self): # Otherwise, perform the tirage + self.tirage.enable_do_tirage = True self.tirage.fermeture = timezone.now() self.tirage.save() - resp = staff_c.get(url) + resp = self.client.get(self.url) 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): - show = self.tirage.spectacle_set.first() - url = "/bda/spectacles/{}/{}".format(self.tirage.id, show.id) - self.check_restricted_access(url, validate_user=user_is_staff) +class SpectacleListViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase): + url_name = "bda-liste-spectacles" - def test_tirage_unpaid(self): - url = "/bda/spectacles/unpaid/{}".format(self.tirage.id) - self.check_restricted_access(url, validate_user=user_is_staff) + auth_user = "bda_staff" + auth_forbidden = [None, "bda_other", "bda_member"] - 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() - # Just get the page - 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) + resp = self.client.post(self.url) self.assertEqual(200, resp.status_code) # 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_details = "/bda/catalogue/details?id={}".format(self.tirage.id) - 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) + resp = self.client.get(url_list) self.assertJSONEqual( resp.content.decode("utf-8"), [{"id": self.tirage.id, "title": self.tirage.title}], ) - # Details - resp = client.get(url_details) + def test_api_details(self): + url_details = "/bda/catalogue/details?id={}".format(self.tirage.id) + resp = self.client.get(url_details) self.assertJSONEqual( resp.content.decode("utf-8"), { @@ -224,8 +201,9 @@ class TestBdAViews(BdATestHelpers, TestCase): }, ) - # Descriptions - resp = client.get(url_descriptions) + def test_api_descriptions(self): + url_descriptions = "/bda/catalogue/descriptions?id={}".format(self.tirage.id) + resp = self.client.get(url_descriptions) raw = resp.content.decode("utf-8") try: results = json.loads(raw) diff --git a/bda/tests/testcases.py b/bda/tests/testcases.py new file mode 100644 index 00000000..f5ac7f83 --- /dev/null +++ b/bda/tests/testcases.py @@ -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, + ) diff --git a/bda/tests/utils.py b/bda/tests/utils.py new file mode 100644 index 00000000..5b486dd0 --- /dev/null +++ b/bda/tests/utils.py @@ -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