gestioCOF/bda/tests/test_views.py

234 lines
7.9 KiB
Python
Raw Normal View History

2018-01-06 12:13:15 +01:00
import json
from datetime import timedelta
from unittest import mock
2018-09-30 13:22:22 +02:00
from urllib.parse import urlencode
2018-01-06 12:13:15 +01:00
from django.contrib.auth.models import User
from django.test import TestCase, Client
from django.utils import timezone
from ..models import Tirage, Spectacle, Salle, CategorieSpectacle
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
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)
member = create_user(username="bda_member", is_cof=True)
member_c = Client()
member_c.force_login(member)
other = create_user(username="bda_other")
other_c = Client()
other_c.force_login(other)
self.client_matrix = [
(staff, staff_c),
(member, member_c),
(other, other_c),
(None, Client())
]
2018-01-07 14:30:33 +01:00
def require_custommails(self):
2018-02-05 22:35:35 +01:00
from django.core.management import call_command
call_command("syncmails")
2018-01-07 14:30:33 +01:00
2018-02-05 22:35:35 +01:00
def check_restricted_access(self, url,
validate_user=user_is_cof,
redirect_url=None):
2018-01-06 12:13:15 +01:00
def craft_redirect_url(user):
if redirect_url:
return redirect_url
elif user is None:
# client is not logged in
2018-09-30 13:22:22 +02:00
login_url = "/login"
if url:
login_url += "?{}".format(urlencode({"next": url},
safe="/"))
return login_url
2018-01-06 12:13:15 +01:00
else:
return "/"
for (user, client) in self.client_matrix:
resp = client.get(url, follow=True)
if validate_user(user):
self.assertEqual(200, resp.status_code)
else:
self.assertRedirects(resp, craft_redirect_url(user))
class TestBdAViews(BdATestHelpers, TestCase):
def setUp(self):
2018-02-05 22:35:35 +01:00
# Signals handlers on login/logout send messages.
2018-01-06 12:13:15 +01:00
# 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
2018-02-05 22:35:35 +01:00
super().setUp()
2018-01-06 12:13:15 +01:00
# 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
self.tirage.enable_do_tirage = False
self.tirage.save()
resp = staff_c.get(url)
self.assertTemplateUsed(resp, "tirage-failed.html")
# 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)
self.assertTemplateUsed(resp, "tirage-failed.html")
# Otherwise, perform the tirage
self.tirage.fermeture = timezone.now()
self.tirage.save()
resp = staff_c.get(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)
def test_tirage_unpaid(self):
url = "/bda/spectacles/unpaid/{}".format(self.tirage.id)
self.check_restricted_access(url, validate_user=user_is_staff)
def test_send_reminders(self):
2018-01-07 14:30:33 +01:00
self.require_custommails()
2018-01-06 12:13:15 +01:00
# Just get the page
2018-01-07 14:43:54 +01:00
show = self.tirage.spectacle_set.first()
url = "/bda/mails-rappel/{}".format(show.id)
2018-01-06 12:13:15 +01:00
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)
# TODO: check that emails are sent
def test_catalogue_api(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)
self.assertJSONEqual(
resp.content.decode("utf-8"),
[{"id": self.tirage.id, "title": self.tirage.title}]
)
# Details
resp = client.get(url_details)
self.assertJSONEqual(
resp.content.decode("utf-8"),
{
"categories": [{
"id": self.category.id,
"name": self.category.name
}],
"locations": [{
"id": self.location.id,
"name": self.location.name
}],
}
)
# Descriptions
resp = client.get(url_descriptions)
raw = resp.content.decode("utf-8")
try:
results = json.loads(raw)
except ValueError:
self.fail("Not valid JSON: {}".format(raw))
self.assertEqual(len(results), 3)
self.assertEqual(
{(s["title"], s["price"], s["slots"]) for s in results},
{("foo", 0, 42), ("bar", 1, 142), ("baz", 2, 242)}
)
class TestBdaRevente:
pass
# TODO