forked from DGNum/gestioCOF
[WIP] Tests for kfet views
This commit is contained in:
parent
878c617cc7
commit
c9aac8a49d
3 changed files with 585 additions and 22 deletions
|
@ -1,26 +1,243 @@
|
|||
import json
|
||||
from decimal import Decimal
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.test import TestCase, Client
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test import Client, TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
from ..models import Account, OperationGroup, Checkout, Operation
|
||||
from ..models import Account, Checkout, Operation, OperationGroup
|
||||
|
||||
from .testcases import ViewTestCaseMixin
|
||||
from .utils import create_team, create_user
|
||||
|
||||
|
||||
class AccountTests(TestCase):
|
||||
"""Account related views"""
|
||||
class LoginGenericTeamViewTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.login.genericteam'
|
||||
url_expected = '/k-fet/login/genericteam'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
def test_ok(self):
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
logged_in_username = r.wsgi_request.user.username
|
||||
self.assertEqual(logged_in_username, 'kfet_genericteam')
|
||||
|
||||
|
||||
class AccountListViewTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.account'
|
||||
url_expected = '/k-fet/accounts/'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
def test_ok(self):
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
|
||||
class AccountValidFreeTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.account.is_validandfree.ajax'
|
||||
url_expected = '/k-fet/accounts/is_validandfree'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
def test_ok_isvalid_isfree(self):
|
||||
"""Upper case trigramme not taken is valid and free."""
|
||||
r = self.client.get(self.url, {'trigramme': 'AAA'})
|
||||
self.assertDictEqual(json.loads(r.content.decode('utf-8')), {
|
||||
'is_valid': True,
|
||||
'is_free': True,
|
||||
})
|
||||
|
||||
def test_ok_isvalid_notfree(self):
|
||||
"""Already taken trigramme is not free, but valid."""
|
||||
r = self.client.get(self.url, {'trigramme': '000'})
|
||||
self.assertDictEqual(json.loads(r.content.decode('utf-8')), {
|
||||
'is_valid': True,
|
||||
'is_free': False,
|
||||
})
|
||||
|
||||
def test_ok_notvalid_isfree(self):
|
||||
"""Lower case if forbidden but free."""
|
||||
r = self.client.get(self.url, {'trigramme': 'aaa'})
|
||||
self.assertDictEqual(json.loads(r.content.decode('utf-8')), {
|
||||
'is_valid': False,
|
||||
'is_free': True,
|
||||
})
|
||||
|
||||
|
||||
class AccountCreateViewTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.account.create'
|
||||
url_expected = '/k-fet/accounts/new'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
@property
|
||||
def users_extra(self):
|
||||
return {
|
||||
'team__add_account': create_team(
|
||||
'team__add_account', '101',
|
||||
perms=['kfet.add_account'],
|
||||
),
|
||||
}
|
||||
|
||||
def test_get_ok(self):
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def test_post_ok(self):
|
||||
post_data = {
|
||||
'trigramme': 'AAA',
|
||||
'username': 'plopplopplop',
|
||||
'first_name': 'first',
|
||||
'last_name': 'last',
|
||||
'email': 'email@domain.net',
|
||||
}
|
||||
|
||||
client = Client()
|
||||
client.login(
|
||||
username='team__add_account',
|
||||
password='team__add_account',
|
||||
)
|
||||
r = client.post(self.url, post_data)
|
||||
|
||||
self.assertRedirects(r, self.url)
|
||||
a = Account.objects.get(trigramme='AAA')
|
||||
self.assertEqual(a.username, 'plopplopplop')
|
||||
|
||||
def test_post_forbidden(self):
|
||||
post_data = {
|
||||
'trigramme': 'AAA',
|
||||
'username': 'plopplopplop',
|
||||
'first_name': 'first',
|
||||
'last_name': 'last',
|
||||
'email': 'email@domain.net',
|
||||
}
|
||||
|
||||
# A team member (without kfet.add_account) is authenticated with
|
||||
# self.client.
|
||||
r = self.client.post(self.url, post_data)
|
||||
|
||||
self.assertEqual(r.status_code, 200)
|
||||
with self.assertRaises(Account.DoesNotExist):
|
||||
Account.objects.get(trigramme='AAA')
|
||||
|
||||
|
||||
class AccountCreateAjaxViewTests(ViewTestCaseMixin, TestCase):
|
||||
urls_conf = [
|
||||
{
|
||||
'name': 'kfet.account.create.fromuser',
|
||||
'kwargs': {'username': 'user'},
|
||||
'expected': '/k-fet/accounts/new/user/user',
|
||||
},
|
||||
{
|
||||
'name': 'kfet.account.create.fromclipper',
|
||||
'kwargs': {
|
||||
'login_clipper': 'myclipper',
|
||||
'fullname': 'first last1 last2',
|
||||
},
|
||||
'expected': (
|
||||
'/k-fet/accounts/new/clipper/myclipper/first%20last1%20last2'
|
||||
),
|
||||
},
|
||||
{
|
||||
'name': 'kfet.account.create.empty',
|
||||
'expected': '/k-fet/accounts/new/empty',
|
||||
},
|
||||
]
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
def test_fromuser(self):
|
||||
r = self.client.get(self.t_urls[0])
|
||||
|
||||
user = self.users['user']
|
||||
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.context['user_form'].instance, user)
|
||||
self.assertEqual(r.context['cof_form'].instance, user.profile)
|
||||
self.assertIn('account_form', r.context)
|
||||
|
||||
def test_fromclipper(self):
|
||||
r = self.client.get(self.t_urls[1])
|
||||
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertIn('user_form', r.context)
|
||||
self.assertIn('cof_form', r.context)
|
||||
self.assertIn('account_form', r.context)
|
||||
|
||||
def test_empty(self):
|
||||
r = self.client.get(self.t_urls[0])
|
||||
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertIn('user_form', r.context)
|
||||
self.assertIn('cof_form', r.context)
|
||||
self.assertIn('account_form', r.context)
|
||||
|
||||
|
||||
class AccountCreateAutocompleteViewTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.account.create.autocomplete'
|
||||
url_expected = '/k-fet/autocomplete/account_new'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
def test_ok(self):
|
||||
r = self.client.get(self.url, {'q': 'first'})
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertListEqual(list(r.context['users_notcof']), [])
|
||||
self.assertListEqual(list(r.context['users_cof']), [])
|
||||
self.assertListEqual(
|
||||
list(r.context['kfet']),
|
||||
[(self.accounts['user'], self.users['user'])],
|
||||
)
|
||||
|
||||
|
||||
class AccountSearchViewTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.account.search.autocomplete'
|
||||
url_expected = '/k-fet/autocomplete/account_search'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
def test_ok(self):
|
||||
r = self.client.get(self.url, {'q': 'first'})
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertListEqual(
|
||||
list(r.context['accounts']),
|
||||
[('000', 'first last')],
|
||||
)
|
||||
|
||||
|
||||
class AccountReadViewTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.account.read'
|
||||
url_kwargs = {'trigramme': '001'}
|
||||
url_expected = '/k-fet/accounts/001'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
@property
|
||||
def users_extra(self):
|
||||
return {
|
||||
'user1': create_user('user1', '001'),
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
# A user and its account
|
||||
self.user = User.objects.create_user(username="foobar", password="foo")
|
||||
acc = Account.objects.create(
|
||||
trigramme="FOO", cofprofile=self.user.profile
|
||||
)
|
||||
super().setUp()
|
||||
|
||||
user1_acc = self.accounts['user1']
|
||||
team_acc = self.accounts['team']
|
||||
|
||||
# Dummy operations and operation groups
|
||||
checkout = Checkout.objects.create(
|
||||
created_by=acc, name="checkout",
|
||||
created_by=team_acc, name="checkout",
|
||||
valid_from=timezone.now(),
|
||||
valid_to=timezone.now() + timezone.timedelta(days=365)
|
||||
)
|
||||
|
@ -30,7 +247,7 @@ class AccountTests(TestCase):
|
|||
]
|
||||
OperationGroup.objects.bulk_create([
|
||||
OperationGroup(
|
||||
on_acc=acc, checkout=checkout, at=at, is_cof=False,
|
||||
on_acc=user1_acc, checkout=checkout, at=at, is_cof=False,
|
||||
amount=amount
|
||||
)
|
||||
for (at, amount) in opeg_data
|
||||
|
@ -47,13 +264,112 @@ class AccountTests(TestCase):
|
|||
amount=Decimal('3')
|
||||
)
|
||||
|
||||
@patch('gestioncof.signals.messages')
|
||||
def test_account_read(self, mock_messages):
|
||||
"""We can query the "Account - Read" page."""
|
||||
def test_ok(self):
|
||||
"""We can query the "Account - Read" page."""
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def test_ok_self(self):
|
||||
client = Client()
|
||||
self.assertTrue(client.login(
|
||||
username="foobar",
|
||||
password="foo"
|
||||
))
|
||||
resp = client.get("/k-fet/accounts/FOO")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
client.login(username='user1', password='user1')
|
||||
r = client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
|
||||
class AccountUpdateViewTests(ViewTestCaseMixin, TestCase):
|
||||
url_name = 'kfet.account.update'
|
||||
url_kwargs = {'trigramme': '001'}
|
||||
url_expected = '/k-fet/accounts/001/edit'
|
||||
|
||||
auth_user = 'team'
|
||||
auth_forbidden = [None, 'user']
|
||||
|
||||
@property
|
||||
def users_extra(self):
|
||||
return {
|
||||
'user1': create_user('user1', '001'),
|
||||
}
|
||||
|
||||
def test_ok(self):
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def test_ok_self(self):
|
||||
client = Client()
|
||||
client.login(username='user1', password='user1')
|
||||
r = client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
|
||||
class BaseAccountGroupViewTests(ViewTestCaseMixin):
|
||||
auth_user = 'team__manage_perms'
|
||||
auth_forbidden = [None, 'user', 'team']
|
||||
|
||||
@property
|
||||
def users_extra(self):
|
||||
return {
|
||||
'team__manage_perms': create_team(
|
||||
'team__manage_perms', '101',
|
||||
perms=['kfet.manage_perms'],
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class AccountGroupListViewTests(BaseAccountGroupViewTests, TestCase):
|
||||
url_name = 'kfet.account.group'
|
||||
url_expected = '/k-fet/accounts/groups'
|
||||
|
||||
def test_ok(self):
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
self.assertQuerysetEqual(
|
||||
r.context['groups'],
|
||||
Group.objects.filter(name__icontains='K-Fêt'),
|
||||
ordered=False,
|
||||
)
|
||||
|
||||
|
||||
class AccountGroupCreateViewTests(BaseAccountGroupViewTests, TestCase):
|
||||
url_name = 'kfet.account.group.create'
|
||||
url_expected = '/k-fet/accounts/groups/new'
|
||||
|
||||
def test_ok(self):
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
|
||||
class AccountGroupUpdateViewTests(BaseAccountGroupViewTests, TestCase):
|
||||
url_name = 'kfet.account.group.update'
|
||||
url_kwargs = {'pk': 42}
|
||||
url_expected = '/k-fet/accounts/groups/42/edit'
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group1 = Group.objects.create(pk=42, name='K-Fêt - Group')
|
||||
self.group1.permissions = [
|
||||
Permission.objects.get(
|
||||
content_type__app_label='kfet',
|
||||
codename='is_team',
|
||||
)
|
||||
]
|
||||
|
||||
def test_get_ok(self):
|
||||
r = self.client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def test_post_ok(self):
|
||||
post_data = {
|
||||
'name': 'Group42',
|
||||
'permissions': (
|
||||
self.group1.permissions
|
||||
.values_list('pk', flat=True)
|
||||
),
|
||||
}
|
||||
|
||||
r = self.client.post(self.url, post_data)
|
||||
|
||||
self.assertRedirects(r, reverse('kfet.account.group'))
|
||||
|
||||
self.group1.refresh_from_db()
|
||||
self.assertEqual(self.group1.name, 'K-Fêt Group42')
|
||||
|
|
142
kfet/tests/testcases.py
Normal file
142
kfet/tests/testcases.py
Normal file
|
@ -0,0 +1,142 @@
|
|||
from unittest import mock
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import QueryDict
|
||||
from django.test import Client
|
||||
|
||||
from .utils import create_root, create_team, create_user
|
||||
|
||||
|
||||
class ViewTestCaseMixin:
|
||||
url_name = None
|
||||
url_expected = None
|
||||
|
||||
auth_user = None
|
||||
auth_forbidden = []
|
||||
|
||||
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)
|
||||
|
||||
self.users = {}
|
||||
self.accounts = {}
|
||||
|
||||
for label, user in {**self.users_base, **self.users_extra}.items():
|
||||
self.register_user(label, user)
|
||||
|
||||
if self.auth_user:
|
||||
# The wrapper is a sanity check.
|
||||
self.assertTrue(
|
||||
self.client.login(
|
||||
username=self.auth_user,
|
||||
password=self.auth_user,
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def users_base(self):
|
||||
# Format desc: username, password, trigramme
|
||||
return {
|
||||
# user, user, 000
|
||||
'user': create_user(),
|
||||
# team, team, 100
|
||||
'team': create_team(),
|
||||
# root, root, 200
|
||||
'root': create_root(),
|
||||
}
|
||||
|
||||
@property
|
||||
def users_extra(self):
|
||||
return {}
|
||||
|
||||
def register_user(self, label, user):
|
||||
self.users[label] = user
|
||||
if hasattr(user.profile, 'account_kfet'):
|
||||
self.accounts[label] = user.profile.account_kfet
|
||||
|
||||
@property
|
||||
def urls_conf(self):
|
||||
return [{
|
||||
'name': self.url_name,
|
||||
'args': getattr(self, 'url_args', []),
|
||||
'kwargs': getattr(self, 'url_kwargs', {}),
|
||||
'expected': self.url_expected,
|
||||
}]
|
||||
|
||||
@property
|
||||
def t_urls(self):
|
||||
return [
|
||||
reverse(
|
||||
url_conf['name'],
|
||||
args=url_conf.get('args', []),
|
||||
kwargs=url_conf.get('kwargs', {}),
|
||||
)
|
||||
for url_conf in self.urls_conf]
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
return self.t_urls[0]
|
||||
|
||||
def assertForbidden(self, response):
|
||||
request = response.wsgi_request
|
||||
|
||||
try:
|
||||
try:
|
||||
# Is this an HTTP Forbidden response ?
|
||||
self.assertEqual(response.status_code, 403)
|
||||
except AssertionError:
|
||||
# A redirection to the login view is fine too.
|
||||
|
||||
# Let's build the login url with the 'next' param on current
|
||||
# page.
|
||||
full_path = request.get_full_path()
|
||||
|
||||
querystring = QueryDict(mutable=True)
|
||||
querystring['next'] = full_path
|
||||
|
||||
login_url = '/login?' + querystring.urlencode(safe='/')
|
||||
|
||||
# We don't focus on what the login view does.
|
||||
# So don't fetch the redirect.
|
||||
self.assertRedirects(
|
||||
response, login_url,
|
||||
fetch_redirect_response=False,
|
||||
)
|
||||
except AssertionError:
|
||||
raise AssertionError(
|
||||
"%(http_method)s request at %(path)s should be forbidden for "
|
||||
"%(username)s user.\n"
|
||||
"Response isn't 403, nor a redirect to login view. Instead, "
|
||||
"response code is %(code)d." % {
|
||||
'http_method': request.method,
|
||||
'path': request.get_full_path(),
|
||||
'username': (
|
||||
"'{}'".format(request.user.username)
|
||||
if request.user.username
|
||||
else 'anonymous'
|
||||
),
|
||||
'code': response.status_code,
|
||||
}
|
||||
)
|
||||
|
||||
def assertForbiddenKfet(self, response):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
form = response.context['form']
|
||||
self.assertIn("Permission refusée", form.non_field_errors)
|
||||
|
||||
def test_urls(self):
|
||||
for url, conf in zip(self.t_urls, self.urls_conf):
|
||||
self.assertEqual(url, conf['expected'])
|
||||
|
||||
def test_forbidden(self):
|
||||
for creds in self.auth_forbidden:
|
||||
for url in self.t_urls:
|
||||
client = Client()
|
||||
if creds is not None:
|
||||
client.login(username=creds, password=creds)
|
||||
r = client.get(url)
|
||||
self.assertForbidden(r)
|
105
kfet/tests/utils.py
Normal file
105
kfet/tests/utils.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
from ..models import Account
|
||||
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
def user_add_perms(user, perms_labels):
|
||||
"""
|
||||
Add perms to a user.
|
||||
|
||||
Args:
|
||||
user (User instance)
|
||||
perms (list of str 'app.perm_name')
|
||||
|
||||
Returns:
|
||||
The same user (refetched from DB to avoid missing perms)
|
||||
|
||||
"""
|
||||
u_labels = set(perms_labels)
|
||||
|
||||
perms = []
|
||||
for label in u_labels:
|
||||
app_label, codename = label.split('.', 1)
|
||||
perms.append(
|
||||
Permission.objects.get(
|
||||
content_type__app_label=app_label,
|
||||
codename=codename,
|
||||
)
|
||||
)
|
||||
|
||||
user.user_permissions.add(*perms)
|
||||
|
||||
# If permissions have already been fetched for this user, we need to reload
|
||||
# it to avoid using of the previous permissions cache.
|
||||
# https://docs.djangoproject.com/en/1.11/topics/auth/default/#permission-caching
|
||||
return User.objects.get(pk=user.pk)
|
||||
|
||||
|
||||
def _create_user_and_account(user_attrs, account_attrs, perms=None):
|
||||
user_attrs.setdefault('password', user_attrs['username'])
|
||||
user = User.objects.create_user(**user_attrs)
|
||||
|
||||
account_attrs['cofprofile'] = user.profile
|
||||
kfet_pwd = account_attrs.pop('password', None)
|
||||
|
||||
account = Account.objects.create(**account_attrs)
|
||||
|
||||
if perms is not None:
|
||||
user = user_add_perms(user, perms)
|
||||
|
||||
if 'kfet.is_team' in perms:
|
||||
if kfet_pwd is None:
|
||||
kfet_pwd = 'kfetpwd_{}'.format(user_attrs['password'])
|
||||
account.change_pwd(kfet_pwd)
|
||||
account.save()
|
||||
|
||||
return user
|
||||
|
||||
|
||||
def create_user(username='user', trigramme='000', **kwargs):
|
||||
user_attrs = kwargs.setdefault('user_attrs', {})
|
||||
|
||||
user_attrs.setdefault('username', username)
|
||||
user_attrs.setdefault('first_name', 'first')
|
||||
user_attrs.setdefault('last_name', 'last')
|
||||
user_attrs.setdefault('email', 'mail@user.net')
|
||||
|
||||
account_attrs = kwargs.setdefault('account_attrs', {})
|
||||
account_attrs.setdefault('trigramme', trigramme)
|
||||
|
||||
return _create_user_and_account(**kwargs)
|
||||
|
||||
|
||||
def create_team(username='team', trigramme='100', **kwargs):
|
||||
user_attrs = kwargs.setdefault('user_attrs', {})
|
||||
|
||||
user_attrs.setdefault('username', username)
|
||||
user_attrs.setdefault('first_name', 'team')
|
||||
user_attrs.setdefault('last_name', 'member')
|
||||
user_attrs.setdefault('email', 'mail@team.net')
|
||||
|
||||
account_attrs = kwargs.setdefault('account_attrs', {})
|
||||
account_attrs.setdefault('trigramme', trigramme)
|
||||
|
||||
perms = kwargs.setdefault('perms', [])
|
||||
perms.append('kfet.is_team')
|
||||
|
||||
return _create_user_and_account(**kwargs)
|
||||
|
||||
|
||||
def create_root(username='root', trigramme='200', **kwargs):
|
||||
user_attrs = kwargs.setdefault('user_attrs', {})
|
||||
|
||||
user_attrs.setdefault('username', username)
|
||||
user_attrs.setdefault('first_name', 'super')
|
||||
user_attrs.setdefault('last_name', 'user')
|
||||
user_attrs.setdefault('email', 'mail@root.net')
|
||||
|
||||
account_attrs = kwargs.setdefault('account_attrs', {})
|
||||
account_attrs.setdefault('trigramme', trigramme)
|
||||
|
||||
return _create_user_and_account(**kwargs)
|
Loading…
Reference in a new issue