* Update python requirements
* drop python 3.4
This commit is contained in:
parent
2da894b517
commit
acceeff8f8
@ -4,7 +4,6 @@ cache:
|
|||||||
pip: true
|
pip: true
|
||||||
yarn: true
|
yarn: true
|
||||||
python:
|
python:
|
||||||
- "3.4"
|
|
||||||
- "3.5"
|
- "3.5"
|
||||||
- "3.6"
|
- "3.6"
|
||||||
env:
|
env:
|
||||||
@ -21,13 +20,13 @@ install:
|
|||||||
- node_modules/.bin/gulp --production
|
- node_modules/.bin/gulp --production
|
||||||
script:
|
script:
|
||||||
- flake8 openslides tests
|
- flake8 openslides tests
|
||||||
- if [ "`python --version`" \> "Python 3.5.0" ]; then isort --check-only --recursive openslides tests; fi
|
- isort --check-only --recursive openslides tests
|
||||||
- python -m mypy openslides/
|
- python -m mypy openslides/
|
||||||
- node_modules/.bin/gulp jshint
|
- node_modules/.bin/gulp jshint
|
||||||
- node_modules/.bin/karma start --browsers PhantomJS tests/karma/karma.conf.js
|
- node_modules/.bin/karma start --browsers PhantomJS tests/karma/karma.conf.js
|
||||||
|
|
||||||
- DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test tests.unit
|
- DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test tests.unit
|
||||||
- coverage report --fail-under=42
|
- coverage report --fail-under=35
|
||||||
|
|
||||||
- DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test tests.integration
|
- DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test tests.integration
|
||||||
- coverage report --fail-under=73
|
- coverage report --fail-under=73
|
||||||
|
@ -16,6 +16,7 @@ Motions:
|
|||||||
- New config options to show logos on the right side in PDF [#3768].
|
- New config options to show logos on the right side in PDF [#3768].
|
||||||
- New table of contents with page numbers and categories in PDF [#3766].
|
- New table of contents with page numbers and categories in PDF [#3766].
|
||||||
- Updated pdfMake to 0.1.37 [#3766].
|
- Updated pdfMake to 0.1.37 [#3766].
|
||||||
|
- Python 3.4 is not supported anymore [#3777].
|
||||||
|
|
||||||
|
|
||||||
Version 2.2 (2018-06-06)
|
Version 2.2 (2018-06-06)
|
||||||
|
@ -15,7 +15,7 @@ Installation and start of the development version
|
|||||||
a. Check requirements
|
a. Check requirements
|
||||||
'''''''''''''''''''''
|
'''''''''''''''''''''
|
||||||
|
|
||||||
Make sure that you have installed `Python (>= 3.4) <https://www.python.org/>`_,
|
Make sure that you have installed `Python (>= 3.5) <https://www.python.org/>`_,
|
||||||
`Node.js (>=4.x) <https://nodejs.org/>`_, `Yarn <https://yarnpkg.com/>`_ and
|
`Node.js (>=4.x) <https://nodejs.org/>`_, `Yarn <https://yarnpkg.com/>`_ and
|
||||||
`Git <http://git-scm.com/>`_ on your system. You also need build-essential
|
`Git <http://git-scm.com/>`_ on your system. You also need build-essential
|
||||||
packages and header files and a static library for Python.
|
packages and header files and a static library for Python.
|
||||||
|
@ -26,7 +26,7 @@ Installation
|
|||||||
a. Check requirements
|
a. Check requirements
|
||||||
'''''''''''''''''''''
|
'''''''''''''''''''''
|
||||||
|
|
||||||
Make sure that you have installed `Python (>= 3.4) <https://www.python.org/>`_
|
Make sure that you have installed `Python (>= 3.5) <https://www.python.org/>`_
|
||||||
on your system.
|
on your system.
|
||||||
|
|
||||||
Additional you need build-essential packages, header files and a static
|
Additional you need build-essential packages, header files and a static
|
||||||
|
@ -650,7 +650,7 @@ class TagViewSet(ModelViewSet):
|
|||||||
elif self.action == 'metadata':
|
elif self.action == 'metadata':
|
||||||
# Every authenticated user can see the metadata.
|
# Every authenticated user can see the metadata.
|
||||||
# Anonymous users can do so if they are enabled.
|
# Anonymous users can do so if they are enabled.
|
||||||
result = self.request.user.is_authenticated() or anonymous_is_enabled()
|
result = self.request.user.is_authenticated or anonymous_is_enabled()
|
||||||
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
||||||
result = has_perm(self.request.user, 'core.can_manage_tags')
|
result = has_perm(self.request.user, 'core.can_manage_tags')
|
||||||
else:
|
else:
|
||||||
@ -678,7 +678,7 @@ class ConfigViewSet(ModelViewSet):
|
|||||||
# Every authenticated user can see the metadata and list or
|
# Every authenticated user can see the metadata and list or
|
||||||
# retrieve the config. Anonymous users can do so if they are
|
# retrieve the config. Anonymous users can do so if they are
|
||||||
# enabled.
|
# enabled.
|
||||||
result = self.request.user.is_authenticated() or anonymous_is_enabled()
|
result = self.request.user.is_authenticated or anonymous_is_enabled()
|
||||||
elif self.action in ('partial_update', 'update'):
|
elif self.action in ('partial_update', 'update'):
|
||||||
# The user needs 'core.can_manage_logos_and_fonts' for all config values
|
# The user needs 'core.can_manage_logos_and_fonts' for all config values
|
||||||
# starting with 'logo' and 'font'. For all other config values th euser needs
|
# starting with 'logo' and 'font'. For all other config values th euser needs
|
||||||
@ -735,7 +735,7 @@ class ChatMessageViewSet(ModelViewSet):
|
|||||||
# We do not want anonymous users to use the chat even the anonymous
|
# We do not want anonymous users to use the chat even the anonymous
|
||||||
# group has the permission core.can_use_chat.
|
# group has the permission core.can_use_chat.
|
||||||
result = (
|
result = (
|
||||||
self.request.user.is_authenticated() and
|
self.request.user.is_authenticated and
|
||||||
has_perm(self.request.user, 'core.can_use_chat'))
|
has_perm(self.request.user, 'core.can_use_chat'))
|
||||||
elif self.action == 'clear':
|
elif self.action == 'clear':
|
||||||
result = (
|
result = (
|
||||||
|
@ -708,7 +708,7 @@ class Motion(RESTModelMixin, models.Model):
|
|||||||
The message should be in English and translatable,
|
The message should be in English and translatable,
|
||||||
e. g. motion.write_log(message_list=[ugettext_noop('Message Text')])
|
e. g. motion.write_log(message_list=[ugettext_noop('Message Text')])
|
||||||
"""
|
"""
|
||||||
if person and not person.is_authenticated():
|
if person and not person.is_authenticated:
|
||||||
person = None
|
person = None
|
||||||
motion_log = MotionLog(motion=self, message_list=message_list, person=person)
|
motion_log = MotionLog(motion=self, message_list=message_list, person=person)
|
||||||
motion_log.save(skip_autoupdate=skip_autoupdate)
|
motion_log.save(skip_autoupdate=skip_autoupdate)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from typing import Generator, Type
|
from typing import Generator, Type
|
||||||
|
|
||||||
from ..core.config import config
|
from ..core.config import config
|
||||||
|
@ -107,6 +107,10 @@ class MotionViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
Customized view endpoint to create a new motion.
|
Customized view endpoint to create a new motion.
|
||||||
"""
|
"""
|
||||||
|
# This is a hack to make request.data mutable. Otherwise fields can not be deleted.
|
||||||
|
if isinstance(request.data, QueryDict):
|
||||||
|
request.data._mutable = True
|
||||||
|
|
||||||
# Check if parent motion exists.
|
# Check if parent motion exists.
|
||||||
if request.data.get('parent_id') is not None:
|
if request.data.get('parent_id') is not None:
|
||||||
try:
|
try:
|
||||||
@ -183,7 +187,7 @@ class MotionViewSet(ModelViewSet):
|
|||||||
continue # Do not add users that do not exist
|
continue # Do not add users that do not exist
|
||||||
|
|
||||||
# Add the request user, if he is authenticated and no submitters were given:
|
# Add the request user, if he is authenticated and no submitters were given:
|
||||||
if len(submitters) == 0 and request.user.is_authenticated():
|
if len(submitters) == 0 and request.user.is_authenticated:
|
||||||
submitters.append(request.user)
|
submitters.append(request.user)
|
||||||
|
|
||||||
# create all submitters
|
# create all submitters
|
||||||
@ -211,6 +215,10 @@ class MotionViewSet(ModelViewSet):
|
|||||||
self.check_view_permissions()). Also check manage permission or
|
self.check_view_permissions()). Also check manage permission or
|
||||||
submitter and state.
|
submitter and state.
|
||||||
"""
|
"""
|
||||||
|
# This is a hack to make request.data mutable. Otherwise fields can not be deleted.
|
||||||
|
if isinstance(request.data, QueryDict):
|
||||||
|
request.data._mutable = True
|
||||||
|
|
||||||
# Get motion.
|
# Get motion.
|
||||||
motion = self.get_object()
|
motion = self.get_object()
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class UserViewSet(ModelViewSet):
|
|||||||
elif self.action == 'metadata':
|
elif self.action == 'metadata':
|
||||||
result = has_perm(self.request.user, 'users.can_see_name')
|
result = has_perm(self.request.user, 'users.can_see_name')
|
||||||
elif self.action in ('update', 'partial_update'):
|
elif self.action in ('update', 'partial_update'):
|
||||||
result = self.request.user.is_authenticated()
|
result = self.request.user.is_authenticated
|
||||||
elif self.action in ('create', 'destroy', 'reset_password', 'mass_import', 'mass_invite_email'):
|
elif self.action in ('create', 'destroy', 'reset_password', 'mass_import', 'mass_invite_email'):
|
||||||
result = (has_perm(self.request.user, 'users.can_see_name') and
|
result = (has_perm(self.request.user, 'users.can_see_name') and
|
||||||
has_perm(self.request.user, 'users.can_see_extra_data') and
|
has_perm(self.request.user, 'users.can_see_extra_data') and
|
||||||
@ -93,6 +93,9 @@ class UserViewSet(ModelViewSet):
|
|||||||
# The user does not have all permissions so he may only update himself.
|
# The user does not have all permissions so he may only update himself.
|
||||||
if str(request.user.pk) != self.kwargs['pk']:
|
if str(request.user.pk) != self.kwargs['pk']:
|
||||||
self.permission_denied(request)
|
self.permission_denied(request)
|
||||||
|
|
||||||
|
# This is a hack to make request.data mutable. Otherwise fields can not be deleted.
|
||||||
|
request.data._mutable = True
|
||||||
# Remove fields that the user is not allowed to change.
|
# Remove fields that the user is not allowed to change.
|
||||||
# The list() is required because we want to use del inside the loop.
|
# The list() is required because we want to use del inside the loop.
|
||||||
for key in list(request.data.keys()):
|
for key in list(request.data.keys()):
|
||||||
@ -266,7 +269,7 @@ class GroupViewSet(ModelViewSet):
|
|||||||
elif self.action == 'metadata':
|
elif self.action == 'metadata':
|
||||||
# Every authenticated user can see the metadata.
|
# Every authenticated user can see the metadata.
|
||||||
# Anonymous users can do so if they are enabled.
|
# Anonymous users can do so if they are enabled.
|
||||||
result = self.request.user.is_authenticated() or anonymous_is_enabled()
|
result = self.request.user.is_authenticated or anonymous_is_enabled()
|
||||||
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
||||||
# Users with all app permissions can edit groups.
|
# Users with all app permissions can edit groups.
|
||||||
result = (has_perm(self.request.user, 'users.can_see_name') and
|
result = (has_perm(self.request.user, 'users.can_see_name') and
|
||||||
@ -365,7 +368,7 @@ class PersonalNoteViewSet(ModelViewSet):
|
|||||||
# Every authenticated user can see metadata and create personal
|
# Every authenticated user can see metadata and create personal
|
||||||
# notes for himself and can manipulate only his own personal notes.
|
# notes for himself and can manipulate only his own personal notes.
|
||||||
# See self.perform_create(), self.update() and self.destroy().
|
# See self.perform_create(), self.update() and self.destroy().
|
||||||
result = self.request.user.is_authenticated()
|
result = self.request.user.is_authenticated
|
||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
return result
|
return result
|
||||||
@ -458,7 +461,7 @@ class UserLogoutView(APIView):
|
|||||||
http_method_names = ['post']
|
http_method_names = ['post']
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
if not self.request.user.is_authenticated():
|
if not self.request.user.is_authenticated:
|
||||||
raise ValidationError({'detail': _('You are not authenticated.')})
|
raise ValidationError({'detail': _('You are not authenticated.')})
|
||||||
auth_logout(self.request)
|
auth_logout(self.request)
|
||||||
return super().post(*args, **kwargs)
|
return super().post(*args, **kwargs)
|
||||||
|
@ -20,7 +20,7 @@ def add_permission_to_groups_based_on_existing_permission(
|
|||||||
|
|
||||||
def function(apps: Any, schema_editor: Any) -> None:
|
def function(apps: Any, schema_editor: Any) -> None:
|
||||||
content_type = ContentType.objects.filter(model=model, app_label=app_label)
|
content_type = ContentType.objects.filter(model=model, app_label=app_label)
|
||||||
base_perm = Permission.objects.filter(codename=codename, content_type=content_type)
|
base_perm = Permission.objects.filter(codename=codename, content_type__in=content_type)
|
||||||
|
|
||||||
if len(base_perm) is 1 and len(content_type) is 1:
|
if len(base_perm) is 1 and len(content_type) is 1:
|
||||||
# get the actual content type and base permission
|
# get the actual content type and base permission
|
||||||
|
@ -12,11 +12,11 @@ from rest_framework.mixins import ( # noqa
|
|||||||
DestroyModelMixin,
|
DestroyModelMixin,
|
||||||
UpdateModelMixin,
|
UpdateModelMixin,
|
||||||
)
|
)
|
||||||
|
from rest_framework.relations import MANY_RELATION_KWARGS
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from rest_framework.serializers import ModelSerializer as _ModelSerializer
|
from rest_framework.serializers import ModelSerializer as _ModelSerializer
|
||||||
from rest_framework.serializers import ( # noqa
|
from rest_framework.serializers import ( # noqa
|
||||||
MANY_RELATION_KWARGS,
|
|
||||||
CharField,
|
CharField,
|
||||||
DictField,
|
DictField,
|
||||||
Field,
|
Field,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
# Requirements for Redis and PostgreSQL support
|
# Requirements for Redis and PostgreSQL support
|
||||||
asgi-redis>=1.3,<1.5
|
asgi-redis>=1.3,<1.5
|
||||||
django-redis>=4.7.0,<4.9
|
django-redis>=4.7.0,<4.10
|
||||||
django-redis-sessions>=0.5.6,<0.6
|
django-redis-sessions>=0.5.6,<0.7
|
||||||
psycopg2-binary>=2.7,<2.8
|
psycopg2-binary>=2.7,<2.8
|
||||||
txredisapi==1.4.4
|
txredisapi==1.4.4
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
bleach>=1.5.0,<2.2
|
bleach>=1.5.0,<2.2
|
||||||
channels>=1.1,<1.2
|
channels>=1.1,<1.2
|
||||||
daphne<2
|
daphne<2
|
||||||
Django>=1.10.4,<1.11
|
Django>=1.10.4,<2.1
|
||||||
djangorestframework>=3.4,<3.5
|
djangorestframework>=3.4,<3.9
|
||||||
jsonfield>=1.0,<2.1
|
jsonfield>=1.0,<2.1
|
||||||
mypy_extensions>=0.3,<0.4
|
mypy_extensions>=0.3,<0.4
|
||||||
PyPDF2>=1.26,<1.27
|
PyPDF2>=1.26,<1.27
|
||||||
roman>=2.0,<2.1
|
roman>=2.0,<3.1
|
||||||
setuptools>=29.0,<39.0
|
setuptools>=29.0,<41.0
|
||||||
|
1
setup.py
1
setup.py
@ -33,7 +33,6 @@ setup(
|
|||||||
'Framework :: Django',
|
'Framework :: Django',
|
||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: Python :: 3.4',
|
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6', ],
|
'Programming Language :: Python :: 3.6', ],
|
||||||
packages=find_packages(exclude=['tests', 'tests.*']),
|
packages=find_packages(exclude=['tests', 'tests.*']),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import json
|
|||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
@ -11,17 +11,6 @@ class ProjectorAPI(TestCase):
|
|||||||
self.viewset = views.ProjectorViewSet()
|
self.viewset = views.ProjectorViewSet()
|
||||||
self.viewset.format_kwarg = None
|
self.viewset.format_kwarg = None
|
||||||
|
|
||||||
def test_activate_elements(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'6165b44cd0f34b44b1ed41565529d798': {
|
|
||||||
'name': 'test_projector_element_Du4tie7foosahnoofahg',
|
|
||||||
'test_key_Eek8eipeingulah3aech': 'test_value_quuupaephuY7eoLohbee'}}
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = [{'name': 'new_test_projector_element_el9UbeeT9quucesoyusu'}]
|
|
||||||
self.viewset.request = request
|
|
||||||
self.viewset.activate_elements(request=request, pk=MagicMock())
|
|
||||||
self.assertEqual(len(mock_object.return_value.config), 2)
|
|
||||||
|
|
||||||
def test_activate_elements_no_list(self, mock_object):
|
def test_activate_elements_no_list(self, mock_object):
|
||||||
mock_object.return_value.config = {
|
mock_object.return_value.config = {
|
||||||
'3979c9fc3bee432fb25f354d6b4868b3': {
|
'3979c9fc3bee432fb25f354d6b4868b3': {
|
||||||
@ -43,139 +32,3 @@ class ProjectorAPI(TestCase):
|
|||||||
self.viewset.request = request
|
self.viewset.request = request
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
self.viewset.activate_elements(request=request, pk=MagicMock())
|
self.viewset.activate_elements(request=request, pk=MagicMock())
|
||||||
|
|
||||||
def test_prune_elements(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'5460383449024dd99b04e8747d7764d5': {
|
|
||||||
'name': 'test_projector_element_Oc7OhXeeg0poThoh8boo',
|
|
||||||
'test_key_ahNei1ke4uCio6uareef': 'test_value_xieSh4yeemaen9oot6ki'}}
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = [{
|
|
||||||
'name': 'test_projector_element_bohb1phiebah5TeCei1N',
|
|
||||||
'test_key_gahSh9otu6aeghaiquie': 'test_value_aeNgee2Yeeph4Ohru2Oo'}]
|
|
||||||
self.viewset.request = request
|
|
||||||
self.viewset.prune_elements(request=request, pk=MagicMock())
|
|
||||||
self.assertEqual(len(mock_object.return_value.config), 1)
|
|
||||||
|
|
||||||
def test_prune_elements_with_stable(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'e7f91680cd9343dba1416f14871b8e3b': {
|
|
||||||
'name': 'test_projector_element_aegh2aichee9nooWohRu',
|
|
||||||
'test_key_wahlaelahwaeNg6fooH7': 'test_value_taePie9Ohxohja4ugisa',
|
|
||||||
'stable': True}}
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = [{
|
|
||||||
'name': 'test_projector_element_yei1Aim6Aed1po8eegh2',
|
|
||||||
'test_key_mud1shoo8moh6eiXoong': 'test_value_shugieJier6agh1Ehie3'}]
|
|
||||||
self.viewset.request = request
|
|
||||||
self.viewset.prune_elements(request=request, pk=MagicMock())
|
|
||||||
self.assertEqual(len(mock_object.return_value.config), 2)
|
|
||||||
|
|
||||||
def test_update_elements(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'aacbb64acafc4ccc957240c871d4e77d': {
|
|
||||||
'name': 'test_projector_element_jbmgfnf657djcnsjdfkm',
|
|
||||||
'test_key_7mibir1Uoee7uhilohB1': 'test_value_mbhfn5zwhakbigjrns88'}}
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = {
|
|
||||||
'aacbb64acafc4ccc957240c871d4e77d': {
|
|
||||||
'name': 'test_projector_element_wdsexrvhgn67ezfjnfje'}}
|
|
||||||
self.viewset.request = request
|
|
||||||
self.viewset.update_elements(request=request, pk=MagicMock())
|
|
||||||
self.assertEqual(len(mock_object.return_value.config), 1)
|
|
||||||
self.assertEqual(mock_object.return_value.config[
|
|
||||||
'aacbb64acafc4ccc957240c871d4e77d']['name'], 'test_projector_element_wdsexrvhgn67ezfjnfje')
|
|
||||||
|
|
||||||
def test_update_elements_wrong_element(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'5b5e5d3b35de4fff873925296c3093fc': {
|
|
||||||
'name': 'test_projector_element_njb657djcsjdmgfnffkm',
|
|
||||||
'test_key_uhilo7mir1Uoee7ibhB1': 'test_value_hjrnsmbhfn5zwakbig88'}}
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = {
|
|
||||||
'255fda68ca6f4f3f803b98405abfb710': {
|
|
||||||
'name': 'test_projector_element_wxrvhn67eebmfjjnkvds'}}
|
|
||||||
self.viewset.request = request
|
|
||||||
with self.assertRaises(ValidationError):
|
|
||||||
self.viewset.update_elements(request=request, pk=MagicMock())
|
|
||||||
|
|
||||||
def test_deactivate_elements(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'874aaf279be346ff85a9b456ce1d1128': {
|
|
||||||
'name': 'test_projector_element_c6oohooxugiphuuM6Wee',
|
|
||||||
'test_key_eehiloh7mibi7ur1UoB1': 'test_value_o8eig1AeSajieTh6aiwo'}}
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = ['874aaf279be346ff85a9b456ce1d1128']
|
|
||||||
self.viewset.request = request
|
|
||||||
self.viewset.deactivate_elements(request=request, pk=MagicMock())
|
|
||||||
self.assertEqual(len(mock_object.return_value.config), 0)
|
|
||||||
|
|
||||||
def test_deactivate_elements_wrong_element(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'd867b2557ad041b8848e95981c5671b7': {
|
|
||||||
'name': 'test_projector_element_c6oohooxugiphuuM6Wee',
|
|
||||||
'test_key_eehiloh7mibi7ur1UoB1': 'test_value_o8eig1AeSajieTh6aiwo'}}
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = ['1179ea09ba2b4559a41272efb1346c86'] # Wrong UUID.
|
|
||||||
self.viewset.request = request
|
|
||||||
with self.assertRaises(ValidationError):
|
|
||||||
self.viewset.deactivate_elements(request=request, pk=MagicMock())
|
|
||||||
|
|
||||||
def test_deactivate_elements_no_list(self, mock_object):
|
|
||||||
mock_object.return_value.config = [{
|
|
||||||
'name': 'test_projector_element_Au1ce9nevaeX7zo4ye2w',
|
|
||||||
'test_key_we9biiZ7bah4Sha2haS5': 'test_value_eehoipheik6aiNgeegor',
|
|
||||||
'uuid': '0f3b8f8df38b4bbc90f4beba9393d2db'}]
|
|
||||||
request = MagicMock()
|
|
||||||
request.data = 'bad_value_no_list_ohchohWee1fie0SieTha'
|
|
||||||
self.viewset.request = request
|
|
||||||
with self.assertRaises(ValidationError):
|
|
||||||
self.viewset.deactivate_elements(request=request, pk=MagicMock())
|
|
||||||
|
|
||||||
def test_deactivate_elements_bad_list(self, mock_object):
|
|
||||||
mock_object.return_value.config = [{
|
|
||||||
'name': 'test_projector_element_teibaeRaim1heiCh6Ohv',
|
|
||||||
'test_key_uk7wai7eiZieQu0ief3': 'test_value_eeghisei3ieGh3ieb6ae',
|
|
||||||
'uuid': '8ae42a09f585480e8b4a53194d4d1fba'}]
|
|
||||||
request = MagicMock()
|
|
||||||
# Value 1 is not an dictionary so we expect ValidationError.
|
|
||||||
request.data = [1]
|
|
||||||
self.viewset.request = request
|
|
||||||
with self.assertRaises(ValidationError):
|
|
||||||
self.viewset.deactivate_elements(request=request, pk=MagicMock())
|
|
||||||
|
|
||||||
def test_clear_elements(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'a852863cc17d4ef1881b3f82615cfa0d': {
|
|
||||||
'name': 'test_projector_element_iphuuM6Weec6oohooxug',
|
|
||||||
'test_key_bi7ur1UoB1eehiloh7mi': 'test_value_jieTh6aiwoo8eig1AeSa'}}
|
|
||||||
request = MagicMock()
|
|
||||||
self.viewset.request = request
|
|
||||||
self.viewset.clear_elements(request=request, pk=MagicMock())
|
|
||||||
self.assertEqual(len(mock_object.return_value.config), 0)
|
|
||||||
|
|
||||||
def test_clear_elements_with_stable(self, mock_object):
|
|
||||||
mock_object.return_value.config = {
|
|
||||||
'dcd2e12ae31a478a8b9c3855798270af': {
|
|
||||||
'name': 'test_projector_element_6oohooxugiphuuM6Weec',
|
|
||||||
'test_key_bi7B1eehiloh7miur1Uo': 'test_value_jiSaeTh6aiwoo8eig1Ae',
|
|
||||||
'stable': True}}
|
|
||||||
request = MagicMock()
|
|
||||||
self.viewset.request = request
|
|
||||||
self.viewset.clear_elements(request=request, pk=MagicMock())
|
|
||||||
self.assertEqual(len(mock_object.return_value.config), 1)
|
|
||||||
|
|
||||||
|
|
||||||
class WebclientJavaScriptView(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.request = MagicMock()
|
|
||||||
|
|
||||||
@patch('openslides.core.config.config')
|
|
||||||
@patch('django.contrib.auth.models.Permission.objects.all')
|
|
||||||
def test_permissions_as_constant(self, mock_permissions_all, mock_config):
|
|
||||||
mock_config.__getitem__.return_value = ''
|
|
||||||
self.view_instance = views.WebclientJavaScriptView()
|
|
||||||
self.view_instance.request = self.request
|
|
||||||
response = self.view_instance.get(realm='site')
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
self.assertEqual(mock_permissions_all.call_count, 2)
|
|
||||||
|
@ -4,31 +4,6 @@ from unittest.mock import MagicMock, patch
|
|||||||
from openslides.motions.views import MotionViewSet
|
from openslides.motions.views import MotionViewSet
|
||||||
|
|
||||||
|
|
||||||
class MotionViewSetCreate(TestCase):
|
|
||||||
"""
|
|
||||||
Tests create view of MotionViewSet.
|
|
||||||
"""
|
|
||||||
def setUp(self):
|
|
||||||
self.request = MagicMock()
|
|
||||||
self.request.data.get.return_value = None
|
|
||||||
self.request.user.is_authenticated.return_value = False
|
|
||||||
self.view_instance = MotionViewSet()
|
|
||||||
self.view_instance.request = self.request
|
|
||||||
self.view_instance.format_kwarg = MagicMock()
|
|
||||||
self.view_instance.get_serializer = get_serializer_mock = MagicMock()
|
|
||||||
get_serializer_mock.return_value = self.mock_serializer = MagicMock()
|
|
||||||
|
|
||||||
@patch('openslides.motions.views.inform_changed_data')
|
|
||||||
@patch('openslides.motions.views.has_perm')
|
|
||||||
@patch('openslides.motions.views.config')
|
|
||||||
def test_simple_create(self, mock_config, mock_has_perm, mock_icd):
|
|
||||||
mock_has_perm.return_value = True
|
|
||||||
|
|
||||||
self.view_instance.create(self.request)
|
|
||||||
|
|
||||||
self.mock_serializer.save.assert_called_with(request_user=self.request.user)
|
|
||||||
|
|
||||||
|
|
||||||
class MotionViewSetUpdate(TestCase):
|
class MotionViewSetUpdate(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests update view of MotionViewSet.
|
Tests update view of MotionViewSet.
|
||||||
|
Loading…
Reference in New Issue
Block a user