From b80e95a321c348a1b0b8aaae5b0ee0a803ee5ec6 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 30 Aug 2017 00:07:54 +0200 Subject: [PATCH] Rewrite projector_element without dispatch --- openslides/agenda/apps.py | 15 +- openslides/agenda/projector.py | 8 + openslides/assignments/apps.py | 15 +- openslides/assignments/projector.py | 6 + openslides/core/apps.py | 9 +- openslides/core/models.py | 15 +- openslides/core/projector.py | 8 + openslides/mediafiles/apps.py | 9 +- openslides/mediafiles/projector.py | 6 + openslides/motions/apps.py | 9 +- openslides/motions/projector.py | 7 + openslides/topics/apps.py | 9 +- openslides/topics/projector.py | 6 + openslides/users/apps.py | 9 +- openslides/users/projector.py | 6 + openslides/utils/dispatch.py | 112 ----------- openslides/utils/projector.py | 55 +++--- setup.cfg | 3 - tests/integration/test_plugin/apps.py | 3 + tests/old/agenda/models.py | 28 --- tests/old/assignments/__init__.py | 0 tests/old/assignments/test_pdf.py | 26 --- tests/old/mediafiles/__init__.py | 0 tests/old/mediafiles/tests.py | 263 -------------------------- tests/old/utils/__init__.py | 1 - tests/old/utils/apps.py | 6 - tests/old/utils/test_dispatch.py | 76 -------- 27 files changed, 116 insertions(+), 594 deletions(-) delete mode 100644 openslides/utils/dispatch.py delete mode 100644 tests/old/agenda/models.py delete mode 100644 tests/old/assignments/__init__.py delete mode 100644 tests/old/assignments/test_pdf.py delete mode 100644 tests/old/mediafiles/__init__.py delete mode 100644 tests/old/mediafiles/tests.py delete mode 100644 tests/old/utils/apps.py delete mode 100644 tests/old/utils/test_dispatch.py diff --git a/openslides/agenda/apps.py b/openslides/agenda/apps.py index bad1d182f..a2550cbfa 100644 --- a/openslides/agenda/apps.py +++ b/openslides/agenda/apps.py @@ -1,6 +1,7 @@ from django.apps import AppConfig from ..utils.collection import Collection +from ..utils.projector import register_projector_elements class AgendaAppConfig(AppConfig): @@ -10,16 +11,13 @@ class AgendaAppConfig(AppConfig): angular_projector_module = True def ready(self): - # Load projector elements. - # Do this by just importing all from these files. - from . import projector # noqa - # Import all required stuff. from django.db.models.signals import pre_delete, post_save - from openslides.core.config import config - from openslides.core.signals import permission_change, user_data_required - from openslides.utils.rest_api import router + from ..core.config import config + from ..core.signals import permission_change, user_data_required + from ..utils.rest_api import router from .config_variables import get_config_variables + from .projector import get_projector_elements from .signals import ( get_permission_change_data, listen_to_related_object_post_delete, @@ -27,8 +25,9 @@ class AgendaAppConfig(AppConfig): required_users) from .views import ItemViewSet - # Define config variables + # Define config variables and projector elements. config.update_config_variables(get_config_variables()) + register_projector_elements(get_projector_elements()) # Connect signals. post_save.connect( diff --git a/openslides/agenda/projector.py b/openslides/agenda/projector.py index 23f55060f..0dd6df0ec 100644 --- a/openslides/agenda/projector.py +++ b/openslides/agenda/projector.py @@ -1,3 +1,5 @@ +from typing import Generator, Type + from ..core.config import config from ..core.exceptions import ProjectorException from ..core.models import Projector @@ -136,3 +138,9 @@ class CurrentListOfSpeakersSlide(ProjectorElement): output.extend(self.get_requirements_as_collection_elements(config_entry)) break return output + + +def get_projector_elements() -> Generator[Type[ProjectorElement], None, None]: + yield ItemListSlide + yield ListOfSpeakersSlide + yield CurrentListOfSpeakersSlide diff --git a/openslides/assignments/apps.py b/openslides/assignments/apps.py index 6bb4d2e00..41b9018d3 100644 --- a/openslides/assignments/apps.py +++ b/openslides/assignments/apps.py @@ -4,6 +4,7 @@ from django.apps import AppConfig from mypy_extensions import TypedDict from ..utils.collection import Collection +from ..utils.projector import register_projector_elements class AssignmentsAppConfig(AppConfig): @@ -13,20 +14,18 @@ class AssignmentsAppConfig(AppConfig): angular_projector_module = True def ready(self): - # Load projector elements. - # Do this by just importing all from these files. - from . import projector # noqa - # Import all required stuff. - from openslides.core.config import config - from openslides.core.signals import permission_change, user_data_required - from openslides.utils.rest_api import router + from ..core.config import config + from ..core.signals import permission_change, user_data_required + from ..utils.rest_api import router from .config_variables import get_config_variables + from .projector import get_projector_elements from .signals import get_permission_change_data, required_users from .views import AssignmentViewSet, AssignmentPollViewSet - # Define config variables + # Define config variables and projector elements. config.update_config_variables(get_config_variables()) + register_projector_elements(get_projector_elements()) # Connect signals. permission_change.connect( diff --git a/openslides/assignments/projector.py b/openslides/assignments/projector.py index f26600cff..f79de375f 100644 --- a/openslides/assignments/projector.py +++ b/openslides/assignments/projector.py @@ -1,3 +1,5 @@ +from typing import Generator, Type + from ..core.exceptions import ProjectorException from ..utils.projector import ProjectorElement from .models import Assignment, AssignmentPoll @@ -64,3 +66,7 @@ class AssignmentSlide(ProjectorElement): else: data = {'agenda_item_id': assignment.agenda_item_id} return data + + +def get_projector_elements() -> Generator[Type[ProjectorElement], None, None]: + yield AssignmentSlide diff --git a/openslides/core/apps.py b/openslides/core/apps.py index 04ddfa386..8f3c79f7e 100644 --- a/openslides/core/apps.py +++ b/openslides/core/apps.py @@ -3,6 +3,7 @@ from django.conf import settings from django.db.models.signals import post_migrate from ..utils.collection import Collection +from ..utils.projector import register_projector_elements class CoreAppConfig(AppConfig): @@ -12,15 +13,12 @@ class CoreAppConfig(AppConfig): angular_projector_module = True def ready(self): - # Load projector elements. - # Do this by just importing all from these files. - from . import projector # noqa - # Import all required stuff. from .config import config from .signals import post_permission_creation from ..utils.rest_api import router from .config_variables import get_config_variables + from .projector import get_projector_elements from .signals import ( delete_django_app_permissions, get_permission_change_data, @@ -36,8 +34,9 @@ class CoreAppConfig(AppConfig): TagViewSet, ) - # Define config variables + # Define config variables and projector elements. config.update_config_variables(get_config_variables()) + register_projector_elements(get_projector_elements()) # Connect signals. post_permission_creation.connect( diff --git a/openslides/core/models.py b/openslides/core/models.py index ce0c8f021..4ea1191e7 100644 --- a/openslides/core/models.py +++ b/openslides/core/models.py @@ -5,7 +5,7 @@ from jsonfield import JSONField from ..utils.collection import CollectionElement from ..utils.models import RESTModelMixin -from ..utils.projector import ProjectorElement +from ..utils.projector import get_all_projector_elements from .access_permissions import ( ChatMessageAccessPermissions, ConfigAccessPermissions, @@ -110,9 +110,7 @@ class Projector(RESTModelMixin, models.Model): result is also used. """ # Get all elements from all apps. - elements = {} - for element in ProjectorElement.get_all(): # type: ignore - elements[element.name] = element + elements = get_all_projector_elements() # Parse result result = {} @@ -137,9 +135,7 @@ class Projector(RESTModelMixin, models.Model): Generator which returns all instances that are shown on this projector. """ # Get all elements from all apps. - elements = {} - for element in ProjectorElement.get_all(): # type: ignore - elements[element.name] = element + elements = get_all_projector_elements() # Generator for key, value in self.config.items(): @@ -166,11 +162,8 @@ class Projector(RESTModelMixin, models.Model): # It is necessary to parse all active projector elements to check whether they require some data. this_projector = collection_element.collection_string == self.get_collection_string() and collection_element.id == self.pk collection_element.information['this_projector'] = this_projector - elements = {} - # Build projector elements. - for element in ProjectorElement.get_all(): # type: ignore - elements[element.name] = element + elements = get_all_projector_elements() # Iterate over all active projector elements. for key, value in self.config.items(): diff --git a/openslides/core/projector.py b/openslides/core/projector.py index 747ef222c..35a04311c 100644 --- a/openslides/core/projector.py +++ b/openslides/core/projector.py @@ -1,3 +1,5 @@ +from typing import Generator, Type + from ..utils.projector import ProjectorElement from .exceptions import ProjectorException from .models import Countdown, ProjectorMessage @@ -48,3 +50,9 @@ class ProjectorMessageElement(ProjectorElement): pass else: yield message + + +def get_projector_elements() -> Generator[Type[ProjectorElement], None, None]: + yield Clock + yield CountdownElement + yield ProjectorMessageElement diff --git a/openslides/mediafiles/apps.py b/openslides/mediafiles/apps.py index 8bf1696ea..fae0cf32b 100644 --- a/openslides/mediafiles/apps.py +++ b/openslides/mediafiles/apps.py @@ -1,6 +1,7 @@ from django.apps import AppConfig from ..utils.collection import Collection +from ..utils.projector import register_projector_elements class MediafilesAppConfig(AppConfig): @@ -10,16 +11,16 @@ class MediafilesAppConfig(AppConfig): angular_projector_module = True def ready(self): - # Load projector elements. - # Do this by just importing all from these files. - from . import projector # noqa - # Import all required stuff. from openslides.core.signals import permission_change, user_data_required from openslides.utils.rest_api import router + from .projector import get_projector_elements from .signals import get_permission_change_data, required_users from .views import MediafileViewSet + # Define projector elements. + register_projector_elements(get_projector_elements()) + # Connect signals. permission_change.connect( get_permission_change_data, diff --git a/openslides/mediafiles/projector.py b/openslides/mediafiles/projector.py index 6c6d5a70a..c4f4e6d1d 100644 --- a/openslides/mediafiles/projector.py +++ b/openslides/mediafiles/projector.py @@ -1,3 +1,5 @@ +from typing import Generator, Type + from ..core.exceptions import ProjectorException from ..utils.projector import ProjectorElement from .models import Mediafile @@ -21,3 +23,7 @@ class MediafileSlide(ProjectorElement): pass else: yield mediafile + + +def get_projector_elements() -> Generator[Type[ProjectorElement], None, None]: + yield MediafileSlide diff --git a/openslides/motions/apps.py b/openslides/motions/apps.py index a3cf8d11e..957ac746f 100644 --- a/openslides/motions/apps.py +++ b/openslides/motions/apps.py @@ -2,6 +2,7 @@ from django.apps import AppConfig from django.db.models.signals import post_migrate from ..utils.collection import Collection +from ..utils.projector import register_projector_elements class MotionsAppConfig(AppConfig): @@ -11,20 +12,18 @@ class MotionsAppConfig(AppConfig): angular_projector_module = True def ready(self): - # Load projector elements. - # Do this by just importing all from these files. - from . import projector # noqa - # Import all required stuff. from openslides.core.config import config from openslides.core.signals import permission_change, user_data_required from openslides.utils.rest_api import router from .config_variables import get_config_variables + from .projector import get_projector_elements from .signals import create_builtin_workflows, get_permission_change_data, required_users from .views import CategoryViewSet, MotionViewSet, MotionBlockViewSet, MotionPollViewSet, MotionChangeRecommendationViewSet, WorkflowViewSet - # Define config variables + # Define config variables and projector elements. config.update_config_variables(get_config_variables()) + register_projector_elements(get_projector_elements()) # Connect signals. post_migrate.connect(create_builtin_workflows, dispatch_uid='motion_create_builtin_workflows') diff --git a/openslides/motions/projector.py b/openslides/motions/projector.py index f3fed432d..391c1fcfd 100644 --- a/openslides/motions/projector.py +++ b/openslides/motions/projector.py @@ -1,3 +1,5 @@ +from typing import Generator, Type + from ..core.exceptions import ProjectorException from ..utils.projector import ProjectorElement from .models import Motion, MotionBlock, MotionChangeRecommendation, Workflow @@ -90,3 +92,8 @@ class MotionBlockSlide(ProjectorElement): else: data = {'agenda_item_id': motion_block.agenda_item_id} return data + + +def get_projector_elements() -> Generator[Type[ProjectorElement], None, None]: + yield MotionSlide + yield MotionBlockSlide diff --git a/openslides/topics/apps.py b/openslides/topics/apps.py index a48165464..6f4f0b075 100644 --- a/openslides/topics/apps.py +++ b/openslides/topics/apps.py @@ -1,6 +1,7 @@ from django.apps import AppConfig from ..utils.collection import Collection +from ..utils.projector import register_projector_elements class TopicsAppConfig(AppConfig): @@ -10,16 +11,16 @@ class TopicsAppConfig(AppConfig): angular_projector_module = True def ready(self): - # Load projector elements. - # Do this by just importing all from these files. - from . import projector # noqa - # Import all required stuff. from openslides.core.signals import permission_change from ..utils.rest_api import router + from .projector import get_projector_elements from .signals import get_permission_change_data from .views import TopicViewSet + # Define projector elements. + register_projector_elements(get_projector_elements()) + # Connect signals. permission_change.connect( get_permission_change_data, diff --git a/openslides/topics/projector.py b/openslides/topics/projector.py index 929b15ce1..793201de2 100644 --- a/openslides/topics/projector.py +++ b/openslides/topics/projector.py @@ -1,3 +1,5 @@ +from typing import Generator, Type + from ..core.exceptions import ProjectorException from ..utils.projector import ProjectorElement from .models import Topic @@ -33,3 +35,7 @@ class TopicSlide(ProjectorElement): else: data = {'agenda_item_id': topic.agenda_item_id} return data + + +def get_projector_elements() -> Generator[Type[ProjectorElement], None, None]: + yield TopicSlide diff --git a/openslides/users/apps.py b/openslides/users/apps.py index efaae509f..b50abc8db 100644 --- a/openslides/users/apps.py +++ b/openslides/users/apps.py @@ -1,6 +1,7 @@ from django.apps import AppConfig from ..utils.collection import Collection +from ..utils.projector import register_projector_elements class UsersAppConfig(AppConfig): @@ -10,20 +11,18 @@ class UsersAppConfig(AppConfig): angular_projector_module = True def ready(self): - # Load projector elements. - # Just import this file. - from . import projector # noqa - # Import all required stuff. from ..core.config import config from ..core.signals import post_permission_creation, permission_change from ..utils.rest_api import router from .config_variables import get_config_variables + from .projector import get_projector_elements from .signals import create_builtin_groups_and_admin, get_permission_change_data from .views import GroupViewSet, PersonalNoteViewSet, UserViewSet - # Define config variables + # Define config variables and projector elements. config.update_config_variables(get_config_variables()) + register_projector_elements(get_projector_elements()) # Connect signals. post_permission_creation.connect( diff --git a/openslides/users/projector.py b/openslides/users/projector.py index 0775000a3..d4907b13f 100644 --- a/openslides/users/projector.py +++ b/openslides/users/projector.py @@ -1,3 +1,5 @@ +from typing import Generator, Type + from ..core.exceptions import ProjectorException from ..utils.projector import ProjectorElement from .models import User @@ -21,3 +23,7 @@ class UserSlide(ProjectorElement): pass else: yield user + + +def get_projector_elements() -> Generator[Type[ProjectorElement], None, None]: + yield UserSlide diff --git a/openslides/utils/dispatch.py b/openslides/utils/dispatch.py deleted file mode 100644 index bee3aa866..000000000 --- a/openslides/utils/dispatch.py +++ /dev/null @@ -1,112 +0,0 @@ -class SignalConnectMetaClass(type): - """ - Metaclass to connect the children of a base class to a Django signal. - - Classes must have a signal argument and a get_dispatch_uid classmethod. - The signal argument must be the Django signal the class should be - connected to. The get_dispatch_uid classmethod must return a unique - value for each child class and None for base classes because they will - not be connected to the signal. - - The classmethod get_all is added to every class using this metaclass. - Calling this on a base class or on child classes will retrieve all - connected children, one instance for each child class. - - These instances will have a check_permission method which returns True - by default. You can override this method to return False on runtime if - you want to filter some children. - - They will also have a get_default_weight method which returns the value - of the default_weight attribute which is 0 by default. You can override - the attribute or the method to sort the children. - - Don't forget to set up the __init__ method so that it is able to receive - wildcard keyword arguments (see example below). This is necessary - because of Django's signal API. - - Example: - - class Base(object, metaclass=SignalConnectMetaClass): - signal = django.dispatch.Signal() - - def __init__(self, **kwargs): - pass - - @classmethod - def get_dispatch_uid(cls): - if not cls.__name__ == 'Base': - return cls.__name__ - - class Child(Base): - pass - - child = Base.get_all(request)[0] - assert Child == type(child) - """ - def __new__(metaclass, class_name, class_parents, class_attributes): - """ - Creates the class and connects it to the signal if so. Adds all - default attributes and methods. - """ - class_attributes['get_all'] = get_all - new_class = super().__new__( - metaclass, class_name, class_parents, class_attributes) - try: - dispatch_uid = new_class.get_dispatch_uid() - except AttributeError: - raise NotImplementedError('Your class %s must have a get_dispatch_uid classmethod.' % class_name) - if dispatch_uid is not None: - try: - signal = new_class.signal - except AttributeError: - raise NotImplementedError('Your class %s must have a signal argument, which must be a Django Signal instance.' % class_name) - else: - signal.connect(new_class, dispatch_uid=dispatch_uid) - attributes = {'check_permission': check_permission, - 'get_default_weight': get_default_weight, - 'default_weight': 0} - for name, attribute in attributes.items(): - if not hasattr(new_class, name): - setattr(new_class, name, attribute) - return new_class - - -@classmethod # type: ignore -def get_all(cls, request=None): - """ - Collects all objects of the class created by the SignalConnectMetaClass - from all apps via signal. They are sorted using the get_default_weight - method. Does not return objects where check_permission returns False. - - A django.http.HttpRequest object can optionally be given. - - This classmethod is added as get_all classmethod to every class using - the SignalConnectMetaClass. - """ - kwargs = {'sender': cls} - if request is not None: - kwargs['request'] = request - all_objects = [obj for __, obj in cls.signal.send(**kwargs) if obj.check_permission()] - all_objects.sort(key=lambda obj: obj.get_default_weight()) - return all_objects - - -def check_permission(self): - """ - Returns True by default. Override this to filter some children on runtime. - - This method is added to every instance of classes using the - SignalConnectMetaClass. - """ - return True - - -def get_default_weight(self): - """ - Returns the value of the default_weight attribute by default. Override - this to sort some children on runtime. - - This method is added to every instance of classes using the - SignalConnectMetaClass. - """ - return self.default_weight diff --git a/openslides/utils/projector.py b/openslides/utils/projector.py index 1244cbbe6..c46153d33 100644 --- a/openslides/utils/projector.py +++ b/openslides/utils/projector.py @@ -1,42 +1,17 @@ -from typing import Any, Dict, Iterable, List, Optional # noqa - -from django.dispatch import Signal +from typing import Any, Dict, Generator, Iterable, List, Type from .collection import CollectionElement -from .dispatch import SignalConnectMetaClass -class ProjectorElement(object, metaclass=SignalConnectMetaClass): +class ProjectorElement: """ Base class for an element on the projector. Every app which wants to add projector elements has to create classes subclassing from this base class with different names. The name attribute - has to be set. The metaclass (SignalConnectMetaClass) does the rest of the - magic. + has to be set. """ - signal = Signal() - name = None # type: Optional[str] - - def __init__(self, **kwargs: str) -> None: - """ - Initializes the projector element instance. This is done when the - signal is sent. - - Because of Django's signal API, we have to take wildcard keyword - arguments. But they are not used here. - """ - pass - - @classmethod - def get_dispatch_uid(cls) -> Optional[str]: - """ - Returns the classname as a unique string for each class. Returns None - for the base class so it will not be connected to the signal. - """ - if not cls.__name__ == 'ProjectorElement': - return cls.__name__ - return None + name = None # type: str def check_and_update_data(self, projector_object: Any, config_entry: Any) -> Any: """ @@ -107,3 +82,25 @@ class ProjectorElement(object, metaclass=SignalConnectMetaClass): else: output = [] return output + + +projector_elements = {} # type: Dict[str, ProjectorElement] + + +def register_projector_elements(elements: Generator[Type[ProjectorElement], None, None]) -> None: + """ + Registers projector elements for later use. + + Has to be called in the app.ready method. + """ + for Element in elements: + element = Element() + projector_elements[element.name] = element + + +def get_all_projector_elements() -> Dict[str, ProjectorElement]: + """ + Returns all projector elements that where registered with + register_projector_elements() + """ + return projector_elements diff --git a/setup.cfg b/setup.cfg index 962096d15..82060da0e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,9 +19,6 @@ ignore_missing_imports = true strict_optional = true check_untyped_defs = true -[mypy-openslides.utils.dispatch] -ignore_errors = true - [mypy-openslides.utils.*] disallow_any = unannotated diff --git a/tests/integration/test_plugin/apps.py b/tests/integration/test_plugin/apps.py index 633d6db79..dfaee9885 100644 --- a/tests/integration/test_plugin/apps.py +++ b/tests/integration/test_plugin/apps.py @@ -4,6 +4,9 @@ from . import __description__, __verbose_name__ class TestPluginAppConfig(AppConfig): + """ + Test Plugin for the test tests.integration.core.test_views.VersionView + """ name = 'tests.integration.test_plugin' label = 'tests.integration.test_plugin' verbose_name = __verbose_name__ diff --git a/tests/old/agenda/models.py b/tests/old/agenda/models.py deleted file mode 100644 index 1df6aec8b..000000000 --- a/tests/old/agenda/models.py +++ /dev/null @@ -1,28 +0,0 @@ -from django.db import models - -from openslides.projector.models import SlideMixin - - -class RelatedItem(SlideMixin, models.Model): - slide_callback_name = 'test_related_item' - name = models.CharField(max_length='255') - - class Meta: - verbose_name = 'Related Item CHFNGEJ5634DJ34F' - - def get_agenda_title(self): - return self.name - - def get_agenda_title_supplement(self): - return 'test item' - - def get_absolute_url(self, link=None): - if link is None: - value = '/absolute-url-here/' - else: - value = super(RelatedItem, self).get_absolute_url(link) - return value - - -class BadRelatedItem(models.Model): - name = models.CharField(max_length='255') diff --git a/tests/old/assignments/__init__.py b/tests/old/assignments/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/old/assignments/test_pdf.py b/tests/old/assignments/test_pdf.py deleted file mode 100644 index 1b84b1aa9..000000000 --- a/tests/old/assignments/test_pdf.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.test.client import Client - -from openslides.assignments.models import Assignment -from openslides.users.models import User -from openslides.utils.test import TestCase - - -class AssignmentPDFTest(TestCase): - """ - Tests for assignment PDF. - """ - def setUp(self): - # Admin - self.admin = User.objects.get(pk=1) - self.admin_client = Client() - self.admin_client.login(username='admin', password='admin') - - def test_render_pdf(self): - Assignment.objects.create(title='assignment_name_ith8qua1Eiferoqu5ju2', description="test", open_posts=1) - response = self.admin_client.get('/assignments/print/') - self.assertEqual(response.status_code, 200) - - def test_render_many_posts(self): - Assignment.objects.create(title='assignment_name_cohZ9shaipee3Phaing4', description="test", open_posts=20) - response = self.admin_client.get('/assignments/print/') - self.assertEqual(response.status_code, 200) diff --git a/tests/old/mediafiles/__init__.py b/tests/old/mediafiles/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/old/mediafiles/tests.py b/tests/old/mediafiles/tests.py deleted file mode 100644 index 96d2b1142..000000000 --- a/tests/old/mediafiles/tests.py +++ /dev/null @@ -1,263 +0,0 @@ -import os -import tempfile -from unittest import skip - -from django.conf import settings -from django.contrib.auth.models import Permission -from django.contrib.contenttypes.models import ContentType -from django.core.files.uploadedfile import SimpleUploadedFile -from django.test.client import Client - -from openslides.mediafiles.models import Mediafile -from openslides.users.models import User -from openslides.utils.test import TestCase - - -class MediafileTest(TestCase): - """ - Unit test for the mediafile model. - """ - def setUp(self): - # Setup the three permissions - ct = ContentType.objects.get(app_label='mediafiles', model='mediafile') - perm_1 = Permission.objects.get(content_type=ct, codename='can_see') - perm_2 = Permission.objects.get(content_type=ct, codename='can_upload') - - # Setup three different users - self.manager = User.objects.get(pk=1) - self.vip_user = User.objects.create_user('mediafile_test_vip_user', 'default') - self.vip_user.user_permissions.add(perm_1, perm_2) - self.normal_user = User.objects.create_user('mediafile_test_normal_user', 'default') - - # Setup a mediafile object - self.tmp_dir = settings.MEDIA_ROOT - tmpfile_no, mediafile_path = tempfile.mkstemp(prefix='tmp_openslides_test_', dir=self.tmp_dir) - self.object = Mediafile.objects.create(title='Title File 1', mediafile=mediafile_path, uploader=self.normal_user) - os.close(tmpfile_no) - - def tearDown(self): - self.object.mediafile.delete(save=False) - super().tearDown() - - def test_str(self): - self.assertEqual(str(self.object), 'Title File 1') - - @skip - def test_absolute_url(self): - self.assertEqual(self.object.get_absolute_url(), '/mediafiles/1/edit/') - self.assertEqual(self.object.get_absolute_url('update'), '/mediafiles/1/edit/') - self.assertEqual(self.object.get_absolute_url(link='delete'), '/mediafiles/1/del/') - - def login_clients(self): - """ - Helper function to login all three test users. - """ - client_manager = Client() - client_manager.login(username='admin', password='admin') - client_vip_user = Client() - client_vip_user.login(username='mediafile_test_vip_user', password='default') - client_normal_user = Client() - client_normal_user.login(username='mediafile_test_normal_user', password='default') - return {'client_manager': client_manager, - 'client_vip_user': client_vip_user, - 'client_normal_user': client_normal_user} - - @skip - def test_see_mediafilelist(self): - for client in self.login_clients().values(): - response = client.get('/mediafiles/') - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'mediafiles/mediafile_list.html') - - @skip - def test_upload_mediafile_get_request(self): - clients = self.login_clients() - response = clients['client_manager'].get('/mediafiles/new/') - self.assertContains(response, '---------', status_code=200) - self.assertContains(response, '', status_code=200) - self.assertTemplateUsed(response, 'mediafiles/mediafile_form.html') - - response = clients['client_vip_user'].get('/mediafiles/new/') - self.assertNotContains(response, '