From f2b369a65e799eb496d8a138b97bf41f16bc0725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lie=20Bouttier?= Date: Tue, 21 Nov 2017 21:28:55 +0100 Subject: [PATCH] more tests and small fixes --- cfp/tests.py | 233 +++++++++++++++++++++++++++++++++++++++++++--- cfp/urls.py | 24 ++--- cfp/views.py | 5 +- ponyconf/utils.py | 11 --- 4 files changed, 233 insertions(+), 40 deletions(-) diff --git a/cfp/tests.py b/cfp/tests.py index 13a0f49..27c042e 100644 --- a/cfp/tests.py +++ b/cfp/tests.py @@ -3,6 +3,7 @@ from django.contrib.sites.models import Site from django.core.urlresolvers import reverse from django.test import TestCase from django.utils import timezone +from django.contrib import messages from datetime import datetime, timedelta from xml.etree import ElementTree as ET @@ -15,6 +16,9 @@ from .models import * class VolunteersTests(TestCase): def setUp(self): site = Site.objects.first() + conf = site.conference + conf.name = 'PonyConf' + conf.save() a, b, c = (User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) for guy in 'abc') Volunteer.objects.create(site=site, name='A', email=a.email) Activity.objects.create(site=site, name='Everythings') @@ -37,7 +41,7 @@ class VolunteersTests(TestCase): conf.volunteers_opening_date = None self.assertFalse(conf.volunteers_enrollment_is_open()) - def test_enrole(self): + def test_enrole_logged_out(self): self.assertEqual(self.client.get(reverse('volunteer-enrole')).status_code, 403) conf = Conference.objects.first() conf.volunteers_opening_date = timezone.now() - timedelta(hours=1) @@ -95,17 +99,59 @@ class VolunteersTests(TestCase): def test_volunteer_mail_token(self): v = Volunteer.objects.get(name='A') self.assertEqual(self.client.get(reverse('volunteer-mail-token')).status_code, 200) + response = self.client.post(reverse('volunteer-mail-token'), {'email': 'notfound@example.org'}) + self.assertEqual(response.status_code, 200) + self.assertTrue(any(map(lambda m: m.level == messages.ERROR and 'do not know this email' in m.message, response.context['messages']))) + response = self.client.post(reverse('volunteer-mail-token'), {'email': 'a@example.org'}) + self.assertRedirects(response, reverse('volunteer-mail-token')) def test_volunteer_list(self): + url = reverse('volunteer-list') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) self.client.login(username='c', password='c') - self.assertEqual(self.client.get(reverse('volunteer-list')).status_code, 200) - response = self.client.get(reverse('volunteer-list') + '?format=csv') + self.assertEqual(self.client.get(url).status_code, 200) + response = self.client.get(url + '?format=csv') self.assertEqual(response.status_code, 200) self.assertEqual(response.get('Content-Disposition'), 'attachment; filename="volunteers.csv"') + def test_volunteer_details(self): + v = Volunteer.objects.get(name='A') + url = reverse('volunteer-details', kwargs=dict(volunteer_id=v.pk)) + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='c', password='c') + self.assertEqual(self.client.get(url).status_code, 200) + + def test_activity_list(self): + url = reverse('activity-list') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='c', password='c') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_activity_add(self): + url = reverse('activity-list') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='c', password='c') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_activity_edit(self): + conf = Conference.objects.get(name='PonyConf') + activity = Activity.objects.filter(site=conf.site).first() + url = reverse('activity-edit', kwargs={'slug': activity.slug}) + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='c', password='c') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_activity_remove(self): + pass + class ProposalTest(TestCase): def setUp(self): + user = User.objects.create_user('jean-mi', email='jean-mi@example.org', password='jean-mi', first_name='Jean', last_name='Mi') + admin = User.objects.create_user('admin', email='admin@example.org', password='admin', is_superuser=True) site = Site.objects.first() conf = Conference.objects.get(site=site) conf.name = 'PonyConf' @@ -114,9 +160,12 @@ class ProposalTest(TestCase): category_ws = TalkCategory.objects.create(site=site, name='Workshop', label='workshop') speaker1 = Participant.objects.create(site=site, name='Speaker 1', email='1@example.org') speaker2 = Participant.objects.create(site=site, name='Speaker 2', email='2@example.org') - talk = Talk.objects.create(site=site, category=category_conf, title='Talk', description='This is a talk.') - talk.speakers.add(speaker1) - talk.speakers.add(speaker2) + speaker3 = Participant.objects.create(site=site, name='Speaker 3', email='3@example.org') + talk1 = Talk.objects.create(site=site, category=category_conf, title='Talk 1', description='This is a 1st talk.') + talk1.speakers.add(speaker1) + talk1.speakers.add(speaker2) + talk2 = Talk.objects.create(site=site, category=category_conf, title='Talk 2', description='This is a 2nd talk.') + talk2.speakers.add(speaker3) def test_home(self): self.assertRedirects(self.client.get(reverse('home')), reverse('proposal-home'), status_code=302) @@ -134,7 +183,14 @@ class ProposalTest(TestCase): all_categories_pk = TalkCategory.objects.filter(site=conf.site).values_list('pk', flat=True) self.assertQuerysetEqual(conf.opened_categories, all_categories_pk, transform=lambda category: category.pk, ordered=False) - def test_proposal_home(self): + def test_proposal_closed(self): + conf = Conference.objects.get(name='PonyConf') + TalkCategory.objects.filter(site=conf.site).all().delete() + response = self.client.get(reverse('proposal-home')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'cfp/closed.html') + + def test_proposal_logged_out(self): conf = Conference.objects.get(name='PonyConf') site = conf.site self.assertEqual(self.client.get(reverse('proposal-home')).status_code, 200) @@ -151,6 +207,28 @@ class ProposalTest(TestCase): self.assertRedirects(response, reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk)), 302) self.assertTrue(speaker in talk.speakers.all()) + def test_proposal_logged_in(self): + self.client.login(username='jean-mi', password='jean-mi') + conf = Conference.objects.get(name='PonyConf') + site = conf.site + response = self.client.get(reverse('proposal-home')) + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Jean Mi') + response = self.client.post(reverse('proposal-home'), { + 'name': 'Jean-Mi', + 'biography': 'I am Jean-Mi!', + 'category': conf.opened_categories.first().pk, + 'title': 'PonyConf', + 'description': 'PonyConf is cool.', + }) + speaker = Participant.objects.get(site=site, name='Jean-Mi') + self.assertEquals(speaker.email, 'jean-mi@example.org') + talk = Talk.objects.get(site=site, title='PonyConf') + self.assertRedirects(response, reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk)), 302) + self.assertTrue(speaker in talk.speakers.all()) + response = self.client.get(reverse('proposal-home')) + self.assertRedirects(response, reverse('proposal-dashboard')) + def test_proposal_dashboard(self): speaker = Participant.objects.get(name='Speaker 1') self.assertEqual(self.client.get(reverse('proposal-dashboard', kwargs=dict(speaker_token=speaker.token))).status_code, 200) @@ -160,37 +238,166 @@ class ProposalTest(TestCase): self.assertEqual(self.client.get(reverse('proposal-profile-edit', kwargs=dict(speaker_token=speaker.token))).status_code, 200) def test_proposal_talk_details(self): + speaker1 = Participant.objects.get(name='Speaker 1') + speaker2 = Participant.objects.get(name='Speaker 2') + talk1 = Talk.objects.get(title='Talk 1') + talk2 = Talk.objects.get(title='Talk 2') + self.assertEqual(self.client.get(reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker1.token, talk_id=talk1.pk))).status_code, 200) + self.assertEqual(self.client.get(reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker2.token, talk_id=talk1.pk))).status_code, 200) + self.assertEqual(self.client.get(reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker1.token, talk_id=talk2.pk))).status_code, 404) + + def test_proposal_talk_add(self): speaker = Participant.objects.get(name='Speaker 1') - talk = Talk.objects.get(title='Talk') - self.assertEqual(self.client.get(reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk))).status_code, 200) + self.assertEqual(self.client.get(reverse('proposal-talk-add', kwargs=dict(speaker_token=speaker.token))).status_code, 200) def test_proposal_talk_edit(self): speaker = Participant.objects.get(name='Speaker 1') - talk = Talk.objects.get(title='Talk') + talk = Talk.objects.get(title='Talk 1') self.assertEqual(self.client.get(reverse('proposal-talk-edit', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk))).status_code, 200) def test_proposal_speaker_add(self): speaker = Participant.objects.get(name='Speaker 1') - talk = Talk.objects.get(title='Talk') + talk = Talk.objects.get(title='Talk 1') self.assertEqual(self.client.get(reverse('proposal-speaker-add', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk))).status_code, 200) def test_proposal_speaker_edit(self): speaker = Participant.objects.get(name='Speaker 1') co_speaker = Participant.objects.get(name='Speaker 2') - talk = Talk.objects.get(title='Talk') + talk = Talk.objects.get(title='Talk 1') self.assertEqual(self.client.get(reverse('proposal-speaker-edit', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk, co_speaker_id=speaker.pk))).status_code, 200) self.assertEqual(self.client.get(reverse('proposal-speaker-edit', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk, co_speaker_id=co_speaker.pk))).status_code, 200) def test_proposal_speaker_remove(self): speaker = Participant.objects.get(name='Speaker 1') co_speaker = Participant.objects.get(name='Speaker 2') - talk = Talk.objects.get(title='Talk') + talk = Talk.objects.get(title='Talk 1') self.assertEqual(self.client.get(reverse('proposal-speaker-remove', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk, co_speaker_id=speaker.pk))).status_code, 403) self.assertRedirects( self.client.get(reverse('proposal-speaker-remove', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk, co_speaker_id=co_speaker.pk))), reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk)), status_code=302) + def test_proposal_mail_token(self): + p = Participant.objects.get(name='Speaker 1') + self.assertEqual(self.client.get(reverse('proposal-mail-token')).status_code, 200) + response = self.client.post(reverse('proposal-mail-token'), {'email': 'notfound@example.org'}) + self.assertEqual(response.status_code, 200) + self.assertTrue(any(map(lambda m: m.level == messages.ERROR and 'do not know this email' in m.message, response.context['messages']))) + response = self.client.post(reverse('proposal-mail-token'), {'email': p.email}) + self.assertRedirects(response, reverse('proposal-mail-token')) + + def test_speaker_list(self): + url = reverse('participant-list') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + self.assertContains(response, 'Speaker 1') + self.assertContains(response, 'Speaker 2') + response = self.client.get(url + '?format=csv') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.get('Content-Disposition'), 'attachment; filename="participants.csv"') + + def test_speaker_details(self): + speaker1 = Participant.objects.get(name='Speaker 1') + speaker2 = Participant.objects.get(name='Speaker 2') + url = reverse('participant-details', kwargs={'participant_id': speaker1.token}) + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + self.assertContains(response, 'Speaker 1') + self.assertContains(response, 'Speaker 2') + self.assertNotContains(response, 'Speaker 3') + self.assertContains(response, 'Talk 1') + self.assertNotContains(response, 'Talk 3') + + def test_speaker_edit(self): + speaker = Participant.objects.get(name='Speaker 1') + url = reverse('participant-edit', kwargs={'participant_id': speaker.token}) + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_speaker_add_talk(self): + speaker = Participant.objects.get(name='Speaker 1') + url = reverse('participant-add-talk', kwargs={'participant_id': speaker.pk}) + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_talk_list(self): + url = reverse('talk-list') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + self.assertContains(response, 'Talk 1') + response = self.client.get(url + '?format=csv') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.get('Content-Disposition'), 'attachment; filename="talks.csv"') + + def test_talk_details(self): + talk = Talk.objects.get(title='Talk 1') + url = reverse('talk-details', kwargs=dict(talk_id=talk.token)) + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + self.assertContains(response, talk.title) + + def test_talk_speaker_remove(self): + talk = Talk.objects.get(title='Talk 1') + count = talk.speakers.count() + to_remove = talk.speakers.first() + self.assertTrue(to_remove in talk.speakers.all()) + url = reverse('talk-speaker-remove', kwargs={'talk_id': talk.pk, 'participant_id': to_remove.pk}) + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertRedirects(response, reverse('talk-details', kwargs={'talk_id': talk.token})) + talk = Talk.objects.get(title='Talk 1') + self.assertEquals(talk.speakers.count() + 1, count) + self.assertFalse(to_remove in talk.speakers.all()) + + def test_conference(self): + conf = Conference.objects.get(name='PonyConf') + url = reverse('conference') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_category_list(self): + url = reverse('category-list') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_category_add(self): + url = reverse('category-add') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_tag_list(self): + url = reverse('tag-list') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_tag_add(self): + url = reverse('tag-add') + self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url) + self.client.login(username='admin', password='admin') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + class ScheduleTest(TestCase): def setUp(self): diff --git a/cfp/urls.py b/cfp/urls.py index 343dc0a..0c10cab 100644 --- a/cfp/urls.py +++ b/cfp/urls.py @@ -43,12 +43,12 @@ urlpatterns = [ url(r'^staff/talks/(?P[\w\-]+)/confirm/$', views.talk_acknowledgment, {'confirm': True}, name='talk-confirm-by-staff'), url(r'^staff/talks/(?P[\w\-]+)/desist/$', views.talk_acknowledgment, {'confirm': False}, name='talk-desist-by-staff'), url(r'^staff/talks/(?P[\w\-]+)/edit/$', views.TalkUpdate.as_view(), name='talk-edit'), - # url(r'^staff/talks/(?P[\w\-]+)/speaker/add/$', views.talk_speaker_add, name='talk-speaker-add'), TODO WIP - url(r'^staff/talks/(?P[\w\-]+)/speaker/remove/(?P[\w\-]+)/$', views.talk_speaker_remove, name='talk-speaker-remove'), + # url(r'^staff/talks/(?P[0-9]+)/speaker/add/$', views.talk_speaker_add, name='talk-speaker-add'), TODO WIP + url(r'^staff/talks/(?P[0-9]+)/speaker/remove/(?P[0-9]+)/$', views.talk_speaker_remove, name='talk-speaker-remove'), url(r'^staff/speakers/$', views.participant_list, name='participant-list'), url(r'^staff/speakers/add/$', views.ParticipantCreate.as_view(), name='participant-add'), url(r'^staff/speakers/(?P[\w\-]+)/$', views.participant_details, name='participant-details'), - url(r'^staff/speakers/(?P[\w\-]+)/add-talk/$', views.participant_add_talk, name='participant-add-talk'), + url(r'^staff/speakers/(?P[0-9]+)/add-talk/$', views.participant_add_talk, name='participant-add-talk'), url(r'^staff/speakers/(?P[\w\-]+)/edit/$', views.ParticipantUpdate.as_view(), name='participant-edit'), url(r'^staff/tracks/$', views.TrackList.as_view(), name='track-list'), url(r'^staff/tracks/add/$', views.TrackCreate.as_view(), name='track-add'), @@ -64,15 +64,15 @@ urlpatterns = [ url(r'^staff/select2/$', views.Select2View.as_view(), name='django_select2-json'), url(r'^admin/$', views.admin, name='admin'), url(r'^admin/conference/$', views.conference_edit, name='conference'), - url(r'^staff/categories/$', views.TalkCategoryList.as_view(), name='category-list'), - url(r'^staff/categories/add/$', views.TalkCategoryCreate.as_view(), name='category-add'), - url(r'^staff/categories/(?P[0-9]+)/edit/$', views.TalkCategoryUpdate.as_view(), name='category-edit'), - url(r'^staff/tags/$', views.TagList.as_view(), name='tag-list'), - url(r'^staff/tags/add/$', views.TagCreate.as_view(), name='tag-add'), - url(r'^staff/tags/(?P[-\w]+)/edit/$', views.TagUpdate.as_view(), name='tag-edit'), - url(r'^staff/activities/$', views.ActivityList.as_view(), name='activity-list'), - url(r'^staff/activities/add/$', views.ActivityCreate.as_view(), name='activity-add'), - url(r'^staff/activities/(?P[-\w]+)/edit/$', views.ActivityUpdate.as_view(), name='activity-edit'), + url(r'^admin/categories/$', views.TalkCategoryList.as_view(), name='category-list'), + url(r'^admin/categories/add/$', views.TalkCategoryCreate.as_view(), name='category-add'), + url(r'^admin/categories/(?P[0-9]+)/edit/$', views.TalkCategoryUpdate.as_view(), name='category-edit'), + url(r'^admin/tags/$', views.TagList.as_view(), name='tag-list'), + url(r'^admin/tags/add/$', views.TagCreate.as_view(), name='tag-add'), + url(r'^admin/tags/(?P[-\w]+)/edit/$', views.TagUpdate.as_view(), name='tag-edit'), + url(r'^admin/activities/$', views.ActivityList.as_view(), name='activity-list'), + url(r'^admin/activities/add/$', views.ActivityCreate.as_view(), name='activity-add'), + url(r'^admin/activities/(?P[-\w]+)/edit/$', views.ActivityUpdate.as_view(), name='activity-edit'), url(r'^schedule/((?P[\w]+)/)?$', views.public_schedule, name='public-schedule'), #url(r'^markdown/$', views.markdown_preview, name='markdown'), ] diff --git a/cfp/views.py b/cfp/views.py index 62b11e0..bf102eb 100644 --- a/cfp/views.py +++ b/cfp/views.py @@ -331,10 +331,7 @@ def proposal_talk_edit(request, speaker, talk_id=None): talk = get_object_or_404(Talk, site=request.conference.site, speakers__pk=speaker.pk, pk=talk_id) else: talk = None - if is_staff(request, request.user): - categories = TalkCategory.objects.filter(site=request.conference.site) - else: - categories = request.conference.opened_categories + categories = request.conference.opened_categories form = TalkForm(request.POST or None, request.FILES or None, categories=categories, instance=talk) if request.method == 'POST' and form.is_valid(): talk = form.save(commit=False) diff --git a/ponyconf/utils.py b/ponyconf/utils.py index 09d7c73..151033b 100644 --- a/ponyconf/utils.py +++ b/ponyconf/utils.py @@ -6,10 +6,6 @@ from markdown import markdown import bleach -def enum_to_choices(enum): - return ((item.value, item.name.replace('_', ' ')) for item in list(enum)) - - class PonyConfModel(models.Model): created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) @@ -17,13 +13,6 @@ class PonyConfModel(models.Model): class Meta: abstract = True - def full_link(self, request=None): - protocol = 'https' if request is None or request.is_secure() else 'http' - return '%s://%s%s' % (protocol, get_current_site(request), self.get_absolute_url()) - - def get_link(self): - return mark_safe('%s' % (self.get_absolute_url(), self)) - def markdown_to_html(md): html = markdown(md)