05eeb6a25c
Refer to allauth doc for an accurate features list: http://django-allauth.readthedocs.io/en/latest/ Users can now change their password, ask for a password reset, or set one if they don't have one. In particular, it allows users whose account has been created via a clipper authentication to configure a password before losing their clipper. Even if they have already lost it, they are able to get one using the "Reset password" functionality. Allauth multiple emails management is deactivated. Requests to the related url redirect to the home page. All the login and logout views are replaced by the allauth' ones. It also concerns the Django and Wagtail admin sites. Note that users are no longer logged out of the clipper CAS server when they authenticated via this server. Instead a message suggests the user to disconnect. Clipper connections and `login_clipper` --------------------------------------- - Non-empty `login_clipper` are now unique among `CofProfile` instances. - They are created once for users with a non-empty 'login_clipper' (with the data migration 0014_create_clipper_connections). - The `login_clipper` of CofProfile instances are sync with their clipper connections: * `CofProfile.sync_clipper_connections` method updates the connections based on `login_clipper`. * Signals receivers `sync_clipper…` update `login_clipper` based on connections creations/updates/deletions. Misc ---- - Add NullCharField (model field) which allows to use `unique=True` on CharField (even with empty strings). - Parts of kfet mixins for TestCase are now in shared.tests.testcase, as they are used elsewhere than in the kfet app.
1242 lines
37 KiB
Python
1242 lines
37 KiB
Python
import csv
|
|
import os
|
|
import uuid
|
|
from datetime import timedelta
|
|
|
|
from custommail.models import CustomMail
|
|
from django.conf import settings
|
|
from django.contrib import messages
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.messages.api import get_messages
|
|
from django.contrib.messages.storage.base import Message
|
|
from django.core import mail
|
|
from django.core.management import call_command
|
|
from django.test import Client, TestCase, override_settings
|
|
from django.urls import reverse
|
|
|
|
from bda.models import Salle, Tirage
|
|
from gestioncof.autocomplete import Clipper
|
|
from gestioncof.models import CalendarSubscription, Club, Event, Survey, SurveyAnswer
|
|
from gestioncof.tests.testcases import ViewTestCaseMixin
|
|
|
|
from .utils import create_member, create_root, create_user
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class RegistrationViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "registration"
|
|
url_expected = "/registration"
|
|
|
|
http_methods = ["GET", "POST"]
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def requires_mails(self):
|
|
data_file = os.path.join(
|
|
settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json"
|
|
)
|
|
call_command("syncmails", data_file, verbosity=0)
|
|
|
|
def test_get(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
@property
|
|
def _minimal_data(self):
|
|
return {
|
|
"first_name": "",
|
|
"last_name": "",
|
|
"email": "",
|
|
# 'is_cof': '1',
|
|
"login_clipper": "",
|
|
"phone": "",
|
|
"occupation": "1A",
|
|
"departement": "",
|
|
"type_cotiz": "normalien",
|
|
"comments": "",
|
|
# 'user_exists': '1',
|
|
"events-TOTAL_FORMS": "0",
|
|
"events-INITIAL_FORMS": "0",
|
|
"events-MIN_NUM_FORMS": "0",
|
|
"events-MAX_NUM_FORMS": "1000",
|
|
}
|
|
|
|
def test_post_new(self):
|
|
self.requires_mails()
|
|
|
|
r = self.client.post(
|
|
self.url,
|
|
dict(
|
|
self._minimal_data,
|
|
**{
|
|
"username": "username",
|
|
"first_name": "first",
|
|
"last_name": "last",
|
|
"email": "username@mail.net",
|
|
"is_cof": "1",
|
|
}
|
|
),
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
u = User.objects.get(username="username")
|
|
expected_message = Message(
|
|
messages.SUCCESS,
|
|
(
|
|
"L'inscription de first last (<tt>username@mail.net</tt>) a été "
|
|
"enregistrée avec succès.\n"
|
|
"Il est désormais membre du COF n°{} !".format(u.pk)
|
|
),
|
|
)
|
|
self.assertIn(expected_message, get_messages(r.wsgi_request))
|
|
|
|
self.assertEqual(u.first_name, "first")
|
|
self.assertEqual(u.last_name, "last")
|
|
self.assertEqual(u.email, "username@mail.net")
|
|
|
|
def test_post_edit(self):
|
|
self.requires_mails()
|
|
u = self.users["user"]
|
|
|
|
r = self.client.post(
|
|
self.url,
|
|
dict(
|
|
self._minimal_data,
|
|
**{
|
|
"username": "user",
|
|
"first_name": "first",
|
|
"last_name": "last",
|
|
"email": "user@mail.net",
|
|
"is_cof": "1",
|
|
"user_exists": "1",
|
|
}
|
|
),
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
u.refresh_from_db()
|
|
expected_message = Message(
|
|
messages.SUCCESS,
|
|
(
|
|
"L'inscription de first last (<tt>user@mail.net</tt>) a été "
|
|
"enregistrée avec succès.\n"
|
|
"Il est désormais membre du COF n°{} !".format(u.pk)
|
|
),
|
|
)
|
|
self.assertIn(expected_message, get_messages(r.wsgi_request))
|
|
|
|
self.assertEqual(u.first_name, "first")
|
|
self.assertEqual(u.last_name, "last")
|
|
self.assertEqual(u.email, "user@mail.net")
|
|
|
|
def _test_mail_welcome(self, was_cof, is_cof, expect_mail):
|
|
self.requires_mails()
|
|
u = self.users["member"] if was_cof else self.users["user"]
|
|
|
|
data = dict(
|
|
self._minimal_data,
|
|
**{"username": u.username, "email": "user@mail.net", "user_exists": "1"}
|
|
)
|
|
if is_cof:
|
|
data["is_cof"] = "1"
|
|
self.client.post(self.url, data)
|
|
|
|
u.refresh_from_db()
|
|
|
|
def _is_sent():
|
|
cm = CustomMail.objects.get(shortname="welcome")
|
|
welcome_msg = cm.get_message({"member": u})
|
|
for m in mail.outbox:
|
|
if m.subject == welcome_msg.subject:
|
|
return True
|
|
return False
|
|
|
|
self.assertEqual(_is_sent(), expect_mail)
|
|
|
|
def test_mail_welcome_0(self):
|
|
self._test_mail_welcome(was_cof=False, is_cof=False, expect_mail=False)
|
|
|
|
def test_mail_welcome_1(self):
|
|
self._test_mail_welcome(was_cof=False, is_cof=True, expect_mail=True)
|
|
|
|
def test_mail_welcome_2(self):
|
|
self._test_mail_welcome(was_cof=True, is_cof=False, expect_mail=False)
|
|
|
|
def test_mail_welcome_3(self):
|
|
self._test_mail_welcome(was_cof=True, is_cof=True, expect_mail=False)
|
|
|
|
def test_events(self):
|
|
e = Event.objects.create()
|
|
|
|
cf1 = e.commentfields.create(name="Comment Field 1")
|
|
cf2 = e.commentfields.create(name="Comment Field 2", fieldtype="char")
|
|
|
|
o1 = e.options.create(name="Option 1")
|
|
o2 = e.options.create(name="Option 2", multi_choices=True)
|
|
|
|
oc1 = o1.choices.create(value="O1 - Choice 1")
|
|
o1.choices.create(value="O1 - Choice 2")
|
|
oc3 = o2.choices.create(value="O2 - Choice 1")
|
|
o2.choices.create(value="O2 - Choice 2")
|
|
|
|
self.client.post(
|
|
self.url,
|
|
dict(
|
|
self._minimal_data,
|
|
**{
|
|
"username": "user",
|
|
"user_exists": "1",
|
|
"events-TOTAL_FORMS": "1",
|
|
"events-INITIAL_FORMS": "0",
|
|
"events-MIN_NUM_FORMS": "0",
|
|
"events-MAX_NUM_FORMS": "1000",
|
|
"events-0-status": "paid",
|
|
"events-0-option_{}".format(o1.pk): [str(oc1.pk)],
|
|
"events-0-option_{}".format(o2.pk): [str(oc3.pk)],
|
|
"events-0-comment_{}".format(cf1.pk): "comment 1",
|
|
"events-0-comment_{}".format(cf2.pk): "",
|
|
}
|
|
),
|
|
)
|
|
|
|
er = e.eventregistration_set.get(user=self.users["user"])
|
|
self.assertQuerysetEqual(er.options.all(), map(repr, [oc1, oc3]), ordered=False)
|
|
self.assertCountEqual(
|
|
er.comments.values_list("content", flat=True), ["comment 1"]
|
|
)
|
|
|
|
|
|
class RegistrationFormViewTests(ViewTestCaseMixin, TestCase):
|
|
urls_conf = [
|
|
{"name": "empty-registration", "expected": "/registration/empty"},
|
|
{
|
|
"name": "user-registration",
|
|
"kwargs": {"username": "user"},
|
|
"expected": "/registration/user/user",
|
|
},
|
|
{
|
|
"name": "clipper-registration",
|
|
"kwargs": {"login_clipper": "uid", "fullname": "First Last1 Last2"},
|
|
"expected": "/registration/clipper/uid/First%20Last1%20Last2",
|
|
},
|
|
]
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test_empty(self):
|
|
r = self.client.get(self.t_urls[0])
|
|
|
|
self.assertIn("user_form", r.context)
|
|
self.assertIn("profile_form", r.context)
|
|
self.assertIn("event_formset", r.context)
|
|
self.assertIn("clubs_form", r.context)
|
|
|
|
def test_username(self):
|
|
u = self.users["user"]
|
|
u.first_name = "first"
|
|
u.last_name = "last"
|
|
u.save()
|
|
|
|
r = self.client.get(self.t_urls[1])
|
|
|
|
self.assertIn("user_form", r.context)
|
|
self.assertIn("profile_form", r.context)
|
|
self.assertIn("event_formset", r.context)
|
|
self.assertIn("clubs_form", r.context)
|
|
user_form = r.context["user_form"]
|
|
self.assertEqual(user_form["username"].initial, "user")
|
|
self.assertEqual(user_form["first_name"].initial, "first")
|
|
self.assertEqual(user_form["last_name"].initial, "last")
|
|
|
|
def test_clipper(self):
|
|
r = self.client.get(self.t_urls[2])
|
|
|
|
self.assertIn("user_form", r.context)
|
|
self.assertIn("profile_form", r.context)
|
|
self.assertIn("event_formset", r.context)
|
|
self.assertIn("clubs_form", r.context)
|
|
user_form = r.context["user_form"]
|
|
profile_form = r.context["profile_form"]
|
|
self.assertEqual(user_form["first_name"].initial, "First")
|
|
self.assertEqual(user_form["last_name"].initial, "Last1 Last2")
|
|
self.assertEqual(user_form["email"].initial, "uid@clipper.ens.fr")
|
|
self.assertEqual(profile_form["login_clipper"].initial, "uid")
|
|
|
|
|
|
@override_settings(LDAP_SERVER_URL="ldap_url")
|
|
class RegistrationAutocompleteViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "cof.registration.autocomplete"
|
|
url_expected = "/autocomplete/registration"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.u1 = create_user("uu_u1", attrs={"first_name": "abc", "last_name": "xyz"})
|
|
self.u2 = create_user("uu_u2", attrs={"first_name": "wyz", "last_name": "abd"})
|
|
self.m1 = create_member(
|
|
"uu_m1", attrs={"first_name": "ebd", "last_name": "wyv"}
|
|
)
|
|
|
|
self.mockLDAP([])
|
|
|
|
def _test(self, query, expected_users, expected_members, expected_clippers):
|
|
r = self.client.get(self.url, {"q": query})
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
self.assertQuerysetEqual(
|
|
r.context["users"], map(repr, expected_users), ordered=False
|
|
)
|
|
self.assertQuerysetEqual(
|
|
r.context["members"],
|
|
map(lambda u: repr(u.profile), expected_members),
|
|
ordered=False,
|
|
)
|
|
self.assertCountEqual(
|
|
map(str, r.context.get("clippers", [])), map(str, expected_clippers)
|
|
)
|
|
|
|
def test_username(self):
|
|
self._test("uu", [self.u1, self.u2], [self.m1], [])
|
|
|
|
def test_firstname(self):
|
|
self._test("ab", [self.u1, self.u2], [], [])
|
|
|
|
def test_lastname(self):
|
|
self._test("wy", [self.u2], [self.m1], [])
|
|
|
|
def test_multi_query(self):
|
|
self._test("wy bd", [self.u2], [self.m1], [])
|
|
|
|
def test_clipper(self):
|
|
mock_ldap = self.mockLDAP([("uid", "first last")])
|
|
|
|
self._test("aa bb", [], [], [Clipper("uid", "first last")])
|
|
|
|
mock_ldap.search.assert_called_once_with(
|
|
"dc=spi,dc=ens,dc=fr",
|
|
"(&(|(cn=*aa*)(uid=*aa*))(|(cn=*bb*)(uid=*bb*)))",
|
|
attributes=["uid", "cn"],
|
|
)
|
|
|
|
def test_clipper_escaped(self):
|
|
mock_ldap = self.mockLDAP([])
|
|
|
|
self._test("; & | (", [], [], [])
|
|
|
|
mock_ldap.search.assert_not_called()
|
|
|
|
def test_clipper_no_duplicate(self):
|
|
self.mockLDAP([("uid", "uu_u1")])
|
|
|
|
self._test("uu u1", [self.u1], [], [Clipper("uid", "uu_u1")])
|
|
|
|
self.u1.profile.login_clipper = "uid"
|
|
self.u1.profile.save()
|
|
|
|
self._test("uu u1", [self.u1], [], [])
|
|
|
|
|
|
class HomeViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "home"
|
|
url_expected = "/"
|
|
|
|
auth_user = "user"
|
|
auth_forbidden = [None]
|
|
|
|
def test(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
|
|
class ProfileEditViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "profile.edit"
|
|
url_expected = "/profil/edition/"
|
|
|
|
http_methods = ["GET", "POST"]
|
|
|
|
auth_user = "user"
|
|
auth_forbidden = [None]
|
|
|
|
def test_get(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
def test_post(self):
|
|
u = self.users["user"]
|
|
|
|
r = self.client.post(
|
|
self.url,
|
|
{
|
|
"u-first_name": "First",
|
|
"u-last_name": "Last",
|
|
"u-phone": "",
|
|
# "p-mailing_cof": "1",
|
|
# "p-mailing_bda": "1",
|
|
# "p-mailing_bda_revente': "1",
|
|
},
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
expected_message = Message(
|
|
messages.SUCCESS, ("Votre profil a été mis à jour avec succès !")
|
|
)
|
|
self.assertIn(expected_message, get_messages(r.wsgi_request))
|
|
u.refresh_from_db()
|
|
self.assertEqual(u.first_name, "First")
|
|
self.assertEqual(u.last_name, "Last")
|
|
self.assertFalse(u.profile.mailing_cof)
|
|
self.assertFalse(u.profile.mailing_bda)
|
|
self.assertFalse(u.profile.mailing_bda_revente)
|
|
|
|
|
|
class UtilsViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "utile_cof"
|
|
url_expected = "/utile_cof"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
|
|
class MailingListDiffCof(ViewTestCaseMixin, TestCase):
|
|
url_name = "ml_diffcof"
|
|
url_expected = "/utile_cof/diff_cof"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.u1 = create_member("u1", attrs={"mailing_cof": True})
|
|
self.u2 = create_member("u2", attrs={"mailing_cof": False})
|
|
self.u3 = create_user("u3", attrs={"mailing_cof": True})
|
|
|
|
def test(self):
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(r.context["personnes"].get(), self.u1.profile)
|
|
|
|
|
|
class ConfigUpdateViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "config.edit"
|
|
url_expected = "/config"
|
|
|
|
http_methods = ["GET", "POST"]
|
|
|
|
auth_user = "root"
|
|
auth_forbidden = [None, "user", "member", "staff"]
|
|
|
|
def get_users_extra(self):
|
|
return {"root": create_root("root")}
|
|
|
|
def test_get(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
def test_post(self):
|
|
r = self.client.post(self.url, {"gestion_banner": "Announcement !"})
|
|
|
|
self.assertRedirects(r, reverse("home"))
|
|
|
|
|
|
class UserAutocompleteViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "cof-user-autocomplete"
|
|
url_expected = "/user/autocomplete"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test(self):
|
|
r = self.client.get(self.url, {"q": "user"})
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
|
|
class ExportMembersViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "cof.membres_export"
|
|
url_expected = "/export/members"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test(self):
|
|
u1, u2 = self.users["member"], self.users["staff"]
|
|
u1.first_name = "first"
|
|
u1.last_name = "last"
|
|
u1.email = "user@mail.net"
|
|
u1.save()
|
|
u1.profile.phone = "0123456789"
|
|
u1.profile.departement = "Dept"
|
|
u1.profile.save()
|
|
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
data = list(csv.reader(r.content.decode("utf-8").split("\n")[:-1]))
|
|
expected = [
|
|
[
|
|
str(u1.pk),
|
|
"member",
|
|
"first",
|
|
"last",
|
|
"user@mail.net",
|
|
"0123456789",
|
|
"1A",
|
|
"Dept",
|
|
"normalien",
|
|
],
|
|
[str(u2.pk), "staff", "", "", "", "", "1A", "", "normalien"],
|
|
]
|
|
# Sort before checking equality, the order of the output of csv.reader
|
|
# does not seem deterministic
|
|
expected.sort(key=lambda row: int(row[0]))
|
|
data.sort(key=lambda row: int(row[0]))
|
|
self.assertListEqual(data, expected)
|
|
|
|
|
|
class MegaHelpers:
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
u1 = create_user("u1")
|
|
u1.first_name = "first"
|
|
u1.last_name = "last"
|
|
u1.email = "user@mail.net"
|
|
u1.save()
|
|
u1.profile.phone = "0123456789"
|
|
u1.profile.departement = "Dept"
|
|
u1.profile.comments = "profile.comments"
|
|
u1.profile.save()
|
|
|
|
u2 = create_user("u2")
|
|
u2.profile.save()
|
|
|
|
m = Event.objects.create(title="MEGA 2018")
|
|
|
|
cf1 = m.commentfields.create(name="Commentaires")
|
|
cf2 = m.commentfields.create(name="Comment Field 2", fieldtype="char")
|
|
|
|
option_type = m.options.create(name="Orga ? Conscrit ?")
|
|
choice_orga = option_type.choices.create(value="Orga")
|
|
choice_conscrit = option_type.choices.create(value="Conscrit")
|
|
|
|
mr1 = m.eventregistration_set.create(user=u1)
|
|
mr1.options.add(choice_orga)
|
|
mr1.comments.create(commentfield=cf1, content="Comment 1")
|
|
mr1.comments.create(commentfield=cf2, content="Comment 2")
|
|
|
|
mr2 = m.eventregistration_set.create(user=u2)
|
|
mr2.options.add(choice_conscrit)
|
|
|
|
self.u1 = u1
|
|
self.u2 = u2
|
|
self.m = m
|
|
self.choice_orga = choice_orga
|
|
self.choice_conscrit = choice_conscrit
|
|
|
|
|
|
class ExportMegaViewTests(MegaHelpers, ViewTestCaseMixin, TestCase):
|
|
url_name = "cof.mega_export"
|
|
url_expected = "/export/mega"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test(self):
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertListEqual(
|
|
self.load_from_csv_response(r),
|
|
[
|
|
[
|
|
"u1",
|
|
"first",
|
|
"last",
|
|
"user@mail.net",
|
|
"0123456789",
|
|
str(self.u1.pk),
|
|
"profile.comments",
|
|
"Comment 1---Comment 2",
|
|
],
|
|
["u2", "", "", "", "", str(self.u2.pk), "", ""],
|
|
],
|
|
)
|
|
|
|
|
|
class ExportMegaOrgasViewTests(MegaHelpers, ViewTestCaseMixin, TestCase):
|
|
url_name = "cof.mega_export_orgas"
|
|
url_expected = "/export/mega/orgas"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test(self):
|
|
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertListEqual(
|
|
self.load_from_csv_response(r),
|
|
[
|
|
[
|
|
"u1",
|
|
"first",
|
|
"last",
|
|
"user@mail.net",
|
|
"0123456789",
|
|
str(self.u1.pk),
|
|
"profile.comments",
|
|
"Comment 1---Comment 2",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
class ExportMegaParticipantsViewTests(MegaHelpers, ViewTestCaseMixin, TestCase):
|
|
url_name = "cof.mega_export_participants"
|
|
url_expected = "/export/mega/participants"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test(self):
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertListEqual(
|
|
self.load_from_csv_response(r),
|
|
[["u2", "", "", "", "", str(self.u2.pk), "", ""]],
|
|
)
|
|
|
|
|
|
class ExportMegaRemarksViewTests(MegaHelpers, ViewTestCaseMixin, TestCase):
|
|
url_name = "cof.mega_export_remarks"
|
|
url_expected = "/export/mega/avecremarques"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
def test(self):
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertListEqual(
|
|
self.load_from_csv_response(r),
|
|
[
|
|
[
|
|
"u1",
|
|
"first",
|
|
"last",
|
|
"user@mail.net",
|
|
"0123456789",
|
|
str(self.u1.pk),
|
|
"profile.comments",
|
|
"Comment 1",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
class ClubListViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "liste-clubs"
|
|
url_expected = "/clubs/liste"
|
|
|
|
auth_user = "member"
|
|
auth_forbidden = [None, "user"]
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.c1 = Club.objects.create(name="Club1")
|
|
self.c2 = Club.objects.create(name="Club2")
|
|
|
|
m = self.users["member"]
|
|
self.c1.membres.add(m)
|
|
self.c1.respos.add(m)
|
|
|
|
def test_as_member(self):
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(r.context["owned_clubs"].get(), self.c1)
|
|
self.assertEqual(r.context["other_clubs"].get(), self.c2)
|
|
|
|
def test_as_staff(self):
|
|
u = self.users["staff"]
|
|
c = Client()
|
|
c.force_login(u)
|
|
|
|
r = c.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertQuerysetEqual(
|
|
r.context["owned_clubs"], map(repr, [self.c1, self.c2]), ordered=False
|
|
)
|
|
|
|
|
|
class ClubMembersViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "membres-club"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
@property
|
|
def url_kwargs(self):
|
|
return {"name": self.c.name}
|
|
|
|
@property
|
|
def url_expected(self):
|
|
return "/clubs/membres/{}".format(self.c.name)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.u1 = create_user("u1")
|
|
self.u2 = create_user("u2")
|
|
|
|
self.c = Club.objects.create(name="Club")
|
|
self.c.membres.add(self.u1, self.u2)
|
|
self.c.respos.add(self.u1)
|
|
|
|
def test_as_staff(self):
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(r.context["members_no_respo"].get(), self.u2)
|
|
|
|
def test_as_respo(self):
|
|
u = self.users["user"]
|
|
self.c.respos.add(u)
|
|
|
|
c = Client()
|
|
c.force_login(u)
|
|
r = c.get(self.url)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
|
|
class ClubChangeRespoViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "change-respo"
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
@property
|
|
def url_kwargs(self):
|
|
return {"club_name": self.c.name, "user_id": self.users["user"].pk}
|
|
|
|
@property
|
|
def url_expected(self):
|
|
return "/clubs/change_respo/{}/{}".format(self.c.name, self.users["user"].pk)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.c = Club.objects.create(name="Club")
|
|
|
|
def test(self):
|
|
u = self.users["user"]
|
|
expected_redirect = reverse("membres-club", kwargs={"name": self.c.name})
|
|
self.c.membres.add(u)
|
|
|
|
r = self.client.get(self.url)
|
|
self.assertRedirects(r, expected_redirect)
|
|
self.assertIn(u, self.c.respos.all())
|
|
|
|
self.client.get(self.url)
|
|
self.assertNotIn(u, self.c.respos.all())
|
|
|
|
|
|
class CalendarViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "calendar"
|
|
url_expected = "/calendar/subscription"
|
|
|
|
auth_user = "member"
|
|
auth_forbidden = [None, "user"]
|
|
|
|
post_expected_message = Message(
|
|
messages.SUCCESS, "Calendrier mis à jour avec succès."
|
|
)
|
|
|
|
def test_get(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
def test_post_new(self):
|
|
r = self.client.post(
|
|
self.url,
|
|
{
|
|
"subscribe_to_events": True,
|
|
"subscribe_to_my_shows": True,
|
|
"other_shows": [],
|
|
},
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertIn(self.post_expected_message, get_messages(r.wsgi_request))
|
|
cs = self.users["member"].calendarsubscription
|
|
self.assertTrue(cs.subscribe_to_events)
|
|
self.assertTrue(cs.subscribe_to_my_shows)
|
|
|
|
def test_post_edit(self):
|
|
u = self.users["member"]
|
|
token = uuid.uuid4()
|
|
cs = CalendarSubscription.objects.create(token=token, user=u)
|
|
|
|
r = self.client.post(self.url, {"other_shows": []})
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertIn(self.post_expected_message, get_messages(r.wsgi_request))
|
|
cs.refresh_from_db()
|
|
self.assertEqual(cs.token, token)
|
|
self.assertFalse(cs.subscribe_to_events)
|
|
self.assertFalse(cs.subscribe_to_my_shows)
|
|
|
|
def test_post_other_shows(self):
|
|
t = Tirage.objects.create(ouverture=self.now, fermeture=self.now, active=True)
|
|
location = Salle.objects.create()
|
|
s = t.spectacle_set.create(
|
|
date=self.now, price=3.5, slots=20, location=location, listing=True
|
|
)
|
|
|
|
r = self.client.post(self.url, {"other_shows": [str(s.pk)]})
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
|
|
class CalendarICSViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "calendar.ics"
|
|
|
|
auth_user = None
|
|
auth_forbidden = []
|
|
|
|
@property
|
|
def url_kwargs(self):
|
|
return {"token": self.token}
|
|
|
|
@property
|
|
def url_expected(self):
|
|
return "/calendar/{}/calendar.ics".format(self.token)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.token = uuid.uuid4()
|
|
|
|
self.t = Tirage.objects.create(
|
|
ouverture=self.now, fermeture=self.now, active=True
|
|
)
|
|
location = Salle.objects.create(name="Location")
|
|
self.s1 = self.t.spectacle_set.create(
|
|
price=1,
|
|
slots=10,
|
|
location=location,
|
|
listing=True,
|
|
title="Spectacle 1",
|
|
date=self.now + timedelta(days=1),
|
|
)
|
|
self.s2 = self.t.spectacle_set.create(
|
|
price=2,
|
|
slots=20,
|
|
location=location,
|
|
listing=True,
|
|
title="Spectacle 2",
|
|
date=self.now + timedelta(days=2),
|
|
)
|
|
self.s3 = self.t.spectacle_set.create(
|
|
price=3,
|
|
slots=30,
|
|
location=location,
|
|
listing=True,
|
|
title="Spectacle 3",
|
|
date=self.now + timedelta(days=3),
|
|
)
|
|
|
|
def test(self):
|
|
u = self.users["user"]
|
|
p = u.participant_set.create(tirage=self.t)
|
|
p.attribution_set.create(spectacle=self.s1)
|
|
|
|
self.cs = CalendarSubscription.objects.create(
|
|
user=u,
|
|
token=self.token,
|
|
subscribe_to_my_shows=True,
|
|
subscribe_to_events=True,
|
|
)
|
|
self.cs.other_shows.add(self.s2)
|
|
|
|
r = self.client.get(self.url)
|
|
|
|
def get_dt_from_ical(v):
|
|
return v.dt
|
|
|
|
self.assertCalEqual(
|
|
r.content.decode("utf-8"),
|
|
[
|
|
{
|
|
"summary": "Spectacle 1",
|
|
"dtstart": (
|
|
get_dt_from_ical,
|
|
((self.now + timedelta(days=1)).replace(microsecond=0)),
|
|
),
|
|
"dtend": (
|
|
get_dt_from_ical,
|
|
(
|
|
(self.now + timedelta(days=1, hours=2)).replace(
|
|
microsecond=0
|
|
)
|
|
),
|
|
),
|
|
"location": "Location",
|
|
"uid": "show-{}-{}@example.com".format(self.s1.pk, self.t.pk),
|
|
},
|
|
{
|
|
"summary": "Spectacle 2",
|
|
"dtstart": (
|
|
get_dt_from_ical,
|
|
((self.now + timedelta(days=2)).replace(microsecond=0)),
|
|
),
|
|
"dtend": (
|
|
get_dt_from_ical,
|
|
(
|
|
(self.now + timedelta(days=2, hours=2)).replace(
|
|
microsecond=0
|
|
)
|
|
),
|
|
),
|
|
"location": "Location",
|
|
"uid": "show-{}-{}@example.com".format(self.s2.pk, self.t.pk),
|
|
},
|
|
],
|
|
)
|
|
|
|
|
|
class EventViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "event.details"
|
|
http_methods = ["GET", "POST"]
|
|
|
|
auth_user = "user"
|
|
auth_forbidden = [None]
|
|
|
|
post_expected_message = Message(
|
|
messages.SUCCESS,
|
|
(
|
|
"Votre inscription a bien été enregistrée ! Vous pouvez cependant la "
|
|
"modifier jusqu'à la fin des inscriptions."
|
|
),
|
|
)
|
|
|
|
@property
|
|
def url_kwargs(self):
|
|
return {"event_id": self.e.pk}
|
|
|
|
@property
|
|
def url_expected(self):
|
|
return "/event/{}".format(self.e.pk)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.e = Event.objects.create()
|
|
|
|
self.ecf1 = self.e.commentfields.create(name="Comment Field 1")
|
|
self.ecf2 = self.e.commentfields.create(
|
|
name="Comment Field 2", fieldtype="char"
|
|
)
|
|
|
|
self.o1 = self.e.options.create(name="Option 1")
|
|
self.o2 = self.e.options.create(name="Option 2", multi_choices=True)
|
|
|
|
self.oc1 = self.o1.choices.create(value="O1 - Choice 1")
|
|
self.oc2 = self.o1.choices.create(value="O1 - Choice 2")
|
|
self.oc3 = self.o2.choices.create(value="O2 - Choice 1")
|
|
self.oc4 = self.o2.choices.create(value="O2 - Choice 2")
|
|
|
|
def test_get(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
def test_post_new(self):
|
|
r = self.client.post(
|
|
self.url,
|
|
{
|
|
"option_{}".format(self.o1.pk): [str(self.oc1.pk)],
|
|
"option_{}".format(self.o2.pk): [str(self.oc3.pk), str(self.oc4.pk)],
|
|
},
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertIn(self.post_expected_message, get_messages(r.wsgi_request))
|
|
|
|
er = self.e.eventregistration_set.get(user=self.users["user"])
|
|
self.assertQuerysetEqual(
|
|
er.options.all(), map(repr, [self.oc1, self.oc3, self.oc4]), ordered=False
|
|
)
|
|
# TODO: Make the view care about comments.
|
|
# self.assertQuerysetEqual(
|
|
# er.comments.all(), map(repr, []),
|
|
# ordered=False,
|
|
# )
|
|
|
|
def test_post_edit(self):
|
|
er = self.e.eventregistration_set.create(user=self.users["user"])
|
|
er.options.add(self.oc1, self.oc3, self.oc4)
|
|
er.comments.create(commentfield=self.ecf1, content="Comment 1")
|
|
|
|
r = self.client.post(
|
|
self.url,
|
|
{
|
|
"option_{}".format(self.o1.pk): [],
|
|
"option_{}".format(self.o2.pk): [str(self.oc3.pk)],
|
|
},
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertIn(self.post_expected_message, get_messages(r.wsgi_request))
|
|
|
|
er.refresh_from_db()
|
|
self.assertQuerysetEqual(er.options.all(), map(repr, [self.oc3]), ordered=False)
|
|
# TODO: Make the view care about comments.
|
|
# self.assertQuerysetEqual(
|
|
# er.comments.all(), map(repr, []),
|
|
# ordered=False,
|
|
# )
|
|
|
|
|
|
class EventStatusViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "event.details.status"
|
|
|
|
http_methods = ["GET", "POST"]
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
@property
|
|
def url_kwargs(self):
|
|
return {"event_id": self.e.pk}
|
|
|
|
@property
|
|
def url_expected(self):
|
|
return "/event/{}/status".format(self.e.pk)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.e = Event.objects.create()
|
|
|
|
self.cf1 = self.e.commentfields.create(name="Comment Field 1")
|
|
self.cf2 = self.e.commentfields.create(name="Comment Field 2", fieldtype="char")
|
|
|
|
self.o1 = self.e.options.create(name="Option 1")
|
|
self.o2 = self.e.options.create(name="Option 2", multi_choices=True)
|
|
|
|
self.oc1 = self.o1.choices.create(value="O1 - Choice 1")
|
|
self.oc2 = self.o1.choices.create(value="O1 - Choice 2")
|
|
self.oc3 = self.o2.choices.create(value="O2 - Choice 1")
|
|
self.oc4 = self.o2.choices.create(value="O2 - Choice 2")
|
|
|
|
self.er1 = self.e.eventregistration_set.create(user=self.users["user"])
|
|
self.er1.options.add(self.oc1)
|
|
self.er2 = self.e.eventregistration_set.create(user=self.users["member"])
|
|
|
|
def _get_oc_filter_name(self, oc):
|
|
return "option_{}_choice_{}".format(oc.event_option.pk, oc.pk)
|
|
|
|
def _test_filters(self, filters, expected):
|
|
r = self.client.post(
|
|
self.url, {self._get_oc_filter_name(oc): v for oc, v in filters}
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertQuerysetEqual(
|
|
r.context["user_choices"], map(repr, expected), ordered=False
|
|
)
|
|
|
|
def test_filter_none(self):
|
|
self._test_filters([(self.oc1, "none")], [self.er1, self.er2])
|
|
|
|
def test_filter_yes(self):
|
|
self._test_filters([(self.oc1, "yes")], [self.er1])
|
|
|
|
def test_filter_no(self):
|
|
self._test_filters([(self.oc1, "no")], [self.er2])
|
|
|
|
|
|
class SurveyViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "survey.details"
|
|
http_methods = ["GET", "POST"]
|
|
|
|
auth_user = "user"
|
|
auth_forbidden = [None]
|
|
|
|
post_expected_message = Message(
|
|
messages.SUCCESS,
|
|
(
|
|
"Votre réponse a bien été enregistrée ! Vous pouvez cependant la "
|
|
"modifier jusqu'à la fin du sondage."
|
|
),
|
|
)
|
|
|
|
@property
|
|
def url_kwargs(self):
|
|
return {"survey_id": self.s.pk}
|
|
|
|
@property
|
|
def url_expected(self):
|
|
return "/survey/{}".format(self.s.pk)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.s = Survey.objects.create(title="Title")
|
|
|
|
self.q1 = self.s.questions.create(question="Question 1 ?")
|
|
self.q2 = self.s.questions.create(question="Question 2 ?", multi_answers=True)
|
|
|
|
self.qa1 = self.q1.answers.create(answer="Q1 - Answer 1")
|
|
self.qa2 = self.q1.answers.create(answer="Q1 - Answer 2")
|
|
self.qa3 = self.q2.answers.create(answer="Q2 - Answer 1")
|
|
self.qa4 = self.q2.answers.create(answer="Q2 - Answer 2")
|
|
|
|
def test_get(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
def test_post_new(self):
|
|
r = self.client.post(
|
|
self.url,
|
|
{
|
|
"question_{}".format(self.q1.pk): [str(self.qa1.pk)],
|
|
"question_{}".format(self.q2.pk): [str(self.qa3.pk), str(self.qa4.pk)],
|
|
},
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertIn(self.post_expected_message, get_messages(r.wsgi_request))
|
|
|
|
a = self.s.surveyanswer_set.get(user=self.users["user"])
|
|
self.assertQuerysetEqual(
|
|
a.answers.all(), map(repr, [self.qa1, self.qa3, self.qa4]), ordered=False
|
|
)
|
|
|
|
def test_post_edit(self):
|
|
a = self.s.surveyanswer_set.create(user=self.users["user"])
|
|
a.answers.add(self.qa1, self.qa1, self.qa4)
|
|
|
|
r = self.client.post(
|
|
self.url,
|
|
{
|
|
"question_{}".format(self.q1.pk): [],
|
|
"question_{}".format(self.q2.pk): [str(self.qa3.pk)],
|
|
},
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertIn(self.post_expected_message, get_messages(r.wsgi_request))
|
|
|
|
a.refresh_from_db()
|
|
self.assertQuerysetEqual(a.answers.all(), map(repr, [self.qa3]), ordered=False)
|
|
|
|
def test_post_delete(self):
|
|
a = self.s.surveyanswer_set.create(user=self.users["user"])
|
|
a.answers.add(self.qa1, self.qa4)
|
|
|
|
r = self.client.post(self.url, {"delete": "1"})
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
expected_message = Message(
|
|
messages.SUCCESS, "Votre réponse a bien été supprimée"
|
|
)
|
|
self.assertIn(expected_message, get_messages(r.wsgi_request))
|
|
|
|
with self.assertRaises(SurveyAnswer.DoesNotExist):
|
|
a.refresh_from_db()
|
|
|
|
def test_forbidden_closed(self):
|
|
self.s.survey_open = False
|
|
self.s.save()
|
|
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertNotEqual(r.status_code, 200)
|
|
|
|
def test_forbidden_old(self):
|
|
self.s.old = True
|
|
self.s.save()
|
|
|
|
r = self.client.get(self.url)
|
|
|
|
self.assertNotEqual(r.status_code, 200)
|
|
|
|
|
|
class SurveyStatusViewTests(ViewTestCaseMixin, TestCase):
|
|
url_name = "survey.details.status"
|
|
|
|
http_methods = ["GET", "POST"]
|
|
|
|
auth_user = "staff"
|
|
auth_forbidden = [None, "user", "member"]
|
|
|
|
@property
|
|
def url_kwargs(self):
|
|
return {"survey_id": self.s.pk}
|
|
|
|
@property
|
|
def url_expected(self):
|
|
return "/survey/{}/status".format(self.s.pk)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.s = Survey.objects.create(title="Title")
|
|
|
|
self.q1 = self.s.questions.create(question="Question 1 ?")
|
|
self.q2 = self.s.questions.create(question="Question 2 ?", multi_answers=True)
|
|
|
|
self.qa1 = self.q1.answers.create(answer="Q1 - Answer 1")
|
|
self.qa2 = self.q1.answers.create(answer="Q1 - Answer 2")
|
|
self.qa3 = self.q2.answers.create(answer="Q2 - Answer 1")
|
|
self.qa4 = self.q2.answers.create(answer="Q2 - Answer 2")
|
|
|
|
self.a1 = self.s.surveyanswer_set.create(user=self.users["user"])
|
|
self.a1.answers.add(self.qa1)
|
|
self.a2 = self.s.surveyanswer_set.create(user=self.users["member"])
|
|
|
|
def test_get(self):
|
|
r = self.client.get(self.url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
def _get_qa_filter_name(self, qa):
|
|
return "question_{}_answer_{}".format(qa.survey_question.pk, qa.pk)
|
|
|
|
def _test_filters(self, filters, expected):
|
|
r = self.client.post(
|
|
self.url, {self._get_qa_filter_name(qa): v for qa, v in filters}
|
|
)
|
|
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertQuerysetEqual(
|
|
r.context["user_answers"], map(repr, expected), ordered=False
|
|
)
|
|
|
|
def test_filter_none(self):
|
|
self._test_filters([(self.qa1, "none")], [self.a1, self.a2])
|
|
|
|
def test_filter_yes(self):
|
|
self._test_filters([(self.qa1, "yes")], [self.a1])
|
|
|
|
def test_filter_no(self):
|
|
self._test_filters([(self.qa1, "no")], [self.a2])
|