diff --git a/.travis.yml b/.travis.yml index 54b756b6d..54eef0c44 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,12 @@ install: - "node_modules/.bin/bower install" - "node_modules/.bin/gulp --production" script: - - "DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test" - - "coverage report -m --fail-under=80" - "flake8 --max-line-length=150 --statistics openslides tests" + + - "DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test tests.unit" + - "coverage report --show-missing --fail-under=35" + + - "DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test tests.integration" + - "coverage report --show-missing --fail-under=45" + + - "DJANGO_SETTINGS_MODULE='tests.old.settings' ./manage.py test tests.old" diff --git a/make/commands.py b/make/commands.py index 01772ecfa..2676a6ff8 100644 --- a/make/commands.py +++ b/make/commands.py @@ -2,6 +2,10 @@ import re from parser import command, argument, call +FAIL = '\033[91m' +SUCCESS = '\033[92m' +RESET = '\033[0m' + @argument('module', nargs='?', default='') @command('test', help='runs the tests') @@ -10,8 +14,8 @@ def test(args=None): Runs the tests. """ module = getattr(args, 'module', '') - return call("DJANGO_SETTINGS_MODULE='tests.settings' coverage run " - "./manage.py test %s" % module) + return call("DJANGO_SETTINGS_MODULE='tests.integration.settings' coverage run " + "./manage.py test tests.%s" % module) @argument('--plain', action='store_true') @@ -51,11 +55,17 @@ def travis(args=None): if line == 'script:': script_lines = True continue - if not script_lines: + if not script_lines or not line: continue match = re.search(r'"(.*)"', line) - return_codes.append(call(match.group(1))) + print('Run: %s' % match.group(1)) + return_code = call(match.group(1)) + return_codes.append(return_code) + if return_code: + print(FAIL + 'fail!\n' + RESET) + else: + print(SUCCESS + 'success!\n' + RESET) # Retuns True if one command exited with a different statuscode then 1 return bool(list(filter(bool, return_codes))) @@ -81,3 +91,14 @@ def min_requirements(args=None): yield '%s==%s' % (line.req.key, line.req.specs[0][1]) print('pip install %s' % ' '.join(get_lowest_versions(args.requirements))) + + +@command('clear', + help='Deletes unneeded files and folders') +def clear(args=None): + """ + Deletes all .pyc and .orig files and empty folders. + """ + call('find -name "*.pyc" -delete') + call('find -name "*.orig" -delete') + call('find -type d -empty -delete') diff --git a/openslides/agenda/templates/agenda/view.html b/openslides/agenda/templates/agenda/view.html index 800f17825..d41c66ce2 100644 --- a/openslides/agenda/templates/agenda/view.html +++ b/openslides/agenda/templates/agenda/view.html @@ -159,7 +159,7 @@ {{ field }} {% if perms.users.can_see and perms.users.can_manage %} - + {% endif %} {% if field.errors %} {{ field.errors }} diff --git a/openslides/assignment/templates/assignment/assignment_detail.html b/openslides/assignment/templates/assignment/assignment_detail.html index e1a251461..51fff465e 100644 --- a/openslides/assignment/templates/assignment/assignment_detail.html +++ b/openslides/assignment/templates/assignment/assignment_detail.html @@ -149,7 +149,7 @@ {% if perms.users.can_see and perms.users.can_manage %} - diff --git a/openslides/global_settings.py b/openslides/global_settings.py index 39b22fc20..50a8f229a 100644 --- a/openslides/global_settings.py +++ b/openslides/global_settings.py @@ -173,3 +173,5 @@ CKEDITOR_CONFIGS = { # Use small alternative with tornado as frontend or big alternative with a # webserver as wsgi server. USE_TORNADO_AS_WSGI_SERVER = True + +TEST_RUNNER = 'openslides.utils.test.OpenSlidesDiscoverRunner' diff --git a/openslides/users/api.py b/openslides/users/api.py index 21b0ca0c4..ac299b692 100644 --- a/openslides/users/api.py +++ b/openslides/users/api.py @@ -162,6 +162,5 @@ def get_protected_perm(): Returns the permission to manage users. This function is a helper function used to protect manager users from locking out themselves. """ - return Permission.objects.get( - content_type=ContentType.objects.get(app_label='users', model='user'), - codename='can_manage') + return Permission.objects.get_by_natural_key( + app_label='users', model='user', codename='can_manage') diff --git a/openslides/users/models.py b/openslides/users/models.py index 295f5fa9f..fd4c01c81 100644 --- a/openslides/users/models.py +++ b/openslides/users/models.py @@ -9,12 +9,17 @@ from django.core.urlresolvers import reverse from django.db import models from django.utils.translation import ugettext_lazy, ugettext_noop +from openslides.config.api import config from openslides.projector.models import SlideMixin from openslides.utils.models import AbsoluteUrlMixin from openslides.utils.rest_api import RESTModelMixin class UserManager(BaseUserManager): + """ + UserManager that creates new users only with a password and a username. + """ + def create_user(self, username, password, **kwargs): user = self.model(username=username, **kwargs) user.set_password(password) @@ -87,9 +92,9 @@ class User(RESTModelMixin, SlideMixin, AbsoluteUrlMixin, PermissionsMixin, Abstr Returns the URL to the user. """ if link == 'detail': - url = reverse('user_view', args=[str(self.pk)]) + url = reverse('user_detail', args=[str(self.pk)]) elif link == 'update': - url = reverse('user_edit', args=[str(self.pk)]) + url = reverse('user_update', args=[str(self.pk)]) elif link == 'delete': url = reverse('user_delete', args=[str(self.pk)]) else: @@ -111,10 +116,7 @@ class User(RESTModelMixin, SlideMixin, AbsoluteUrlMixin, PermissionsMixin, Abstr E. g.: * Dr. Max Mustermann (Villingen) * Professor Dr. Enders, Christoph (Leipzig) """ - if self.structure_level: - structure = '(%s)' % self.structure_level - else: - structure = '' + structure = '(%s)' % self.structure_level if self.structure_level else '' return ' '.join((self.title, self.get_short_name(), structure)).strip() @@ -125,9 +127,21 @@ class User(RESTModelMixin, SlideMixin, AbsoluteUrlMixin, PermissionsMixin, Abstr E. g.: * Max Mustermann * Enders, Christoph """ - # TODO: Order of name. See config. - name = ('%s %s' % (self.first_name, self.last_name)).strip() - return name or self.username + # Strip white spaces from the name parts + first_name = self.first_name.strip() + last_name = self.last_name.strip() + + # The user has a last_name and a first_name + if first_name and last_name: + if config['users_sort_users_by_first_name']: + name = ' '.join((first_name, last_name)) + else: + name = ', '.join((last_name, first_name)) + + # The user has only a first_name or a last_name or no name + else: + name = first_name or last_name or self.username + return name def reset_password(self, password=None): """ diff --git a/openslides/users/templates/users/user_detail.html b/openslides/users/templates/users/user_detail.html index f1f38a33b..985862df5 100644 --- a/openslides/users/templates/users/user_detail.html +++ b/openslides/users/templates/users/user_detail.html @@ -1,6 +1,7 @@ {% extends "base.html" %} {% load i18n %} +{% load tags %} {% block title %}{{ shown_user }} – {{ block.super }}{% endblock %} @@ -29,7 +30,7 @@