from unittest import mock from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission from django.test import Client, TestCase from django.urls import reverse from events.models import ( Event, ExtraField, ExtraFieldContent, Option, OptionChoice, Registration, ) from shared.tests.mixins import CSVResponseMixin User = get_user_model() def make_user(name): return User.objects.create_user(username=name, password=name) def make_staff_user(name): view_event_perm = Permission.objects.get( codename="view_event", content_type__app_label="events", ) user = make_user(name) user.user_permissions.add(view_event_perm) return user class MessagePatch: 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) class CSVExportAccessTest(MessagePatch, TestCase): def setUp(self): super().setUp() self.staff = make_staff_user("staff") self.u1 = make_user("toto") self.event = Event.objects.create(title="test_event", location="somewhere") self.url = reverse("events:csv-participants", args=[self.event.id]) def test_get(self): client = Client() client.force_login(self.staff) r = client.get(self.url) self.assertEqual(r.status_code, 200) def test_anonymous(self): client = Client() r = client.get(self.url) self.assertRedirects( r, "/login?next={}".format(self.url), fetch_redirect_response=False ) def test_unauthorised(self): client = Client() client.force_login(self.u1) r = client.get(self.url) self.assertEqual(r.status_code, 403) class CSVExportContentTest(MessagePatch, CSVResponseMixin, TestCase): def setUp(self): super().setUp() self.event = Event.objects.create(title="test_event", location="somewhere") self.url = reverse("events:csv-participants", args=[self.event.id]) self.u1 = User.objects.create_user( username="toto_foo", first_name="toto", last_name="foo", email="toto@a.b" ) self.u2 = User.objects.create_user( username="titi_bar", first_name="titi", last_name="bar", email="titi@a.b" ) self.staff = make_staff_user("staff") self.client = Client() self.client.force_login(self.staff) def test_simple_event(self): self.event.subscribers.set([self.u1, self.u2]) response = self.client.get(self.url) content = self.load_from_csv_response(response, as_dict=True) self.assertListEqual( content, [ { "username": "toto_foo", "prénom": "toto", "nom de famille": "foo", "email": "toto@a.b", }, { "username": "titi_bar", "prénom": "titi", "nom de famille": "bar", "email": "titi@a.b", }, ], ) def test_complex_event(self): registration = Registration.objects.create(event=self.event, user=self.u1) # Set up some options option1 = Option.objects.create( event=self.event, name="abc", multi_choices=False ) option2 = Option.objects.create( event=self.event, name="def", multi_choices=True ) OptionChoice.objects.bulk_create( [ OptionChoice(option=option1, choice="a"), OptionChoice(option=option1, choice="b"), OptionChoice(option=option1, choice="c"), OptionChoice(option=option2, choice="d"), OptionChoice(option=option2, choice="e"), OptionChoice(option=option2, choice="f"), ] ) registration.options_choices.set( OptionChoice.objects.filter(choice__in=["d", "f"]) ) registration.options_choices.add(OptionChoice.objects.get(choice="a")) # And an extra field field = ExtraField.objects.create(event=self.event, name="remarks") ExtraFieldContent.objects.create( field=field, registration=registration, content="hello" ) response = self.client.get(self.url) content = self.load_from_csv_response(response, as_dict=True) toto_dict = dict(content[0]) # This is not super nice, but it makes the test deterministic. toto_dict["def"] = set(x.strip() for x in toto_dict["def"].split("&")) self.assertDictEqual( toto_dict, { "username": "toto_foo", "prénom": "toto", "nom de famille": "foo", "email": "toto@a.b", "abc": "a", "def": {"d", "f"}, "remarks": "hello", }, )