forked from DGNum/gestioCOF
cof -- Add tests for registration views
This commit is contained in:
parent
776ff28141
commit
7160a9c954
3 changed files with 378 additions and 0 deletions
|
@ -21,6 +21,13 @@ class Clipper(object):
|
||||||
self.clipper = clipper
|
self.clipper = clipper
|
||||||
self.fullname = fullname
|
self.fullname = fullname
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} ({})'.format(self.clipper, self.fullname)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return (
|
||||||
|
self.clipper == other.clipper and self.fullname == other.fullname)
|
||||||
|
|
||||||
|
|
||||||
@buro_required
|
@buro_required
|
||||||
def autocomplete(request):
|
def autocomplete(request):
|
||||||
|
|
339
gestioncof/tests/test_views.py
Normal file
339
gestioncof/tests/test_views.py
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
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 TestCase, override_settings
|
||||||
|
|
||||||
|
from gestioncof.autocomplete import Clipper
|
||||||
|
from gestioncof.models import Event
|
||||||
|
from gestioncof.tests.testcases import ViewTestCaseMixin
|
||||||
|
|
||||||
|
from custommail.models import CustomMail
|
||||||
|
|
||||||
|
from .utils import create_user, create_member
|
||||||
|
|
||||||
|
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):
|
||||||
|
call_command('syncmails', 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')
|
||||||
|
oc2 = o1.choices.create(value='O1 - Choice 2')
|
||||||
|
oc3 = o2.choices.create(value='O2 - Choice 1')
|
||||||
|
oc4 = 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 get_initial(self, form, name):
|
||||||
|
return form.get_initial_for_field(form.fields[name], name)
|
||||||
|
|
||||||
|
def test_empty(self):
|
||||||
|
r = self.client.get(self.t_urls[0])
|
||||||
|
|
||||||
|
user_form = r.context['user_form']
|
||||||
|
profile_form = r.context['profile_form']
|
||||||
|
events_form = r.context['event_formset']
|
||||||
|
clubs_form = r.context['clubs_form']
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
user_form = r.context['user_form']
|
||||||
|
profile_form = r.context['profile_form']
|
||||||
|
events_form = r.context['event_formset']
|
||||||
|
clubs_form = r.context['clubs_form']
|
||||||
|
|
||||||
|
self.assertEqual(self.get_initial(user_form, 'username'), 'user')
|
||||||
|
self.assertEqual(self.get_initial(user_form, 'first_name'), 'first')
|
||||||
|
self.assertEqual(self.get_initial(user_form, 'last_name'), 'last')
|
||||||
|
|
||||||
|
def test_clipper(self):
|
||||||
|
r = self.client.get(self.t_urls[2])
|
||||||
|
|
||||||
|
user_form = r.context['user_form']
|
||||||
|
profile_form = r.context['profile_form']
|
||||||
|
events_form = r.context['event_formset']
|
||||||
|
clubs_form = r.context['clubs_form']
|
||||||
|
|
||||||
|
self.assertEqual(self.get_initial(user_form, 'first_name'), 'First')
|
||||||
|
self.assertEqual(
|
||||||
|
self.get_initial(user_form, 'last_name'), 'Last1 Last2')
|
||||||
|
self.assertEqual(
|
||||||
|
self.get_initial(user_form, 'email'), 'uid@clipper.ens.fr')
|
||||||
|
self.assertEqual(
|
||||||
|
self.get_initial(profile_form, 'login_clipper'), '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], [], [])
|
|
@ -92,6 +92,38 @@ class TestCaseMixin:
|
||||||
else:
|
else:
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def mockLDAP(self, results):
|
||||||
|
class Elt:
|
||||||
|
def __init__(self, value):
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
class Entry:
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
setattr(self, k, Elt(v))
|
||||||
|
|
||||||
|
results_as_ldap = [
|
||||||
|
Entry(uid=uid, cn=name) for uid, name in results
|
||||||
|
]
|
||||||
|
|
||||||
|
mock_connection = mock.MagicMock()
|
||||||
|
mock_connection.entries = results_as_ldap
|
||||||
|
|
||||||
|
# Connection is used as a context manager.
|
||||||
|
mock_context_manager = mock.MagicMock()
|
||||||
|
mock_context_manager.return_value.__enter__.return_value = (
|
||||||
|
mock_connection
|
||||||
|
)
|
||||||
|
|
||||||
|
patcher = mock.patch(
|
||||||
|
'gestioncof.autocomplete.Connection',
|
||||||
|
new=mock_context_manager,
|
||||||
|
)
|
||||||
|
patcher.start()
|
||||||
|
self.addCleanup(patcher.stop)
|
||||||
|
|
||||||
|
return mock_connection
|
||||||
|
|
||||||
|
|
||||||
class ViewTestCaseMixin(TestCaseMixin):
|
class ViewTestCaseMixin(TestCaseMixin):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue