A few tests for BdA views

This commit is contained in:
Martin Pépin 2018-01-06 12:13:15 +01:00
parent 433b3f4716
commit e9b901337e
3 changed files with 222 additions and 105 deletions

View file

@ -1,105 +0,0 @@
import json
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
class TestBdAViews(TestCase):
def setUp(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")
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
),
])
self.bda_user = User.objects.create_user(
username="bda_user", password="bda4ever"
)
self.bda_user.profile.is_cof = True
self.bda_user.profile.is_buro = True
self.bda_user.profile.save()
def bda_participants(self):
"""The BdA participants views can be queried"""
client = Client()
show = self.tirage.spectacle_set.first()
client.login(self.bda_user.username, "bda4ever")
tirage_resp = client.get("/bda/spectacles/{}".format(self.tirage.id))
show_resp = client.get(
"/bda/spectacles/{}/{}".format(self.tirage.id, show.id)
)
reminder_url = "/bda/mails-rappel/{}".format(show.id)
reminder_get_resp = client.get(reminder_url)
reminder_post_resp = client.post(reminder_url)
self.assertEqual(200, tirage_resp.status_code)
self.assertEqual(200, show_resp.status_code)
self.assertEqual(200, reminder_get_resp.status_code)
self.assertEqual(200, reminder_post_resp.status_code)
def test_catalogue(self):
"""Test the catalogue JSON API"""
client = Client()
# The `list` hook
resp = client.get("/bda/catalogue/list")
self.assertJSONEqual(
resp.content.decode("utf-8"),
[{"id": self.tirage.id, "title": self.tirage.title}]
)
# The `details` hook
resp = client.get(
"/bda/catalogue/details?id={}".format(self.tirage.id)
)
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
}],
}
)
# The `descriptions` hook
resp = client.get(
"/bda/catalogue/descriptions?id={}".format(self.tirage.id)
)
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)}
)

0
bda/tests/__init__.py Normal file
View file

222
bda/tests/test_views.py Normal file
View file

@ -0,0 +1,222 @@
import json
from datetime import timedelta
from unittest import mock
from django.contrib.auth.models import User
from django.template.defaultfilters import urlencode
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())
]
def check_restricted_access(self, url, validate_user=user_is_cof, redirect_url=None):
def craft_redirect_url(user):
if redirect_url:
return redirect_url
elif user is None:
# client is not logged in
return "/login?next={}".format(urlencode(urlencode(url)))
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):
# 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
BdATestHelpers.setUp(self)
# 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):
# Just get the page
url = "/bda/mails-rappel/{}".format(self.tirage.id)
self.check_restricted_access(url, validate_user=user_is_staff)
# Actually send the reminder emails
# TODO: first load the emails into the database
_, 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