Projector V

* Changed wording: element is one element on the projector. A slide is a functoin to render one element
* Use AllData as first argument all the time
* Render username on server
* Add exceptions for erros on projector
* Fix motion recommendation
* Only show state extension, if it is allowed by the state
* Add motion_change_recommendations to motion full_data
This commit is contained in:
Oskar Hahn 2019-01-27 13:17:17 +01:00
parent 0d8cbbaab9
commit 1a709a59a9
22 changed files with 142 additions and 116 deletions

View File

@ -13,7 +13,7 @@ class AgendaAppConfig(AppConfig):
from django.db.models.signals import pre_delete, post_save from django.db.models.signals import pre_delete, post_save
from ..core.signals import permission_change from ..core.signals import permission_change
from ..utils.rest_api import router from ..utils.rest_api import router
from .projector import register_projector_elements from .projector import register_projector_slides
from .signals import ( from .signals import (
get_permission_change_data, get_permission_change_data,
listen_to_related_object_post_delete, listen_to_related_object_post_delete,
@ -24,7 +24,7 @@ class AgendaAppConfig(AppConfig):
from ..utils.access_permissions import required_user from ..utils.access_permissions import required_user
# Define projector elements. # Define projector elements.
register_projector_elements() register_projector_slides()
# Connect signals. # Connect signals.
post_save.connect( post_save.connect(

View File

@ -1,7 +1,11 @@
from collections import defaultdict from collections import defaultdict
from typing import Any, Dict, List, Tuple from typing import Any, Dict, List, Tuple
from ..utils.projector import AllData, register_projector_element from ..utils.projector import (
AllData,
ProjectorElementException,
register_projector_slide,
)
# Important: All functions have to be prune. This means, that thay can only # Important: All functions have to be prune. This means, that thay can only
@ -41,7 +45,7 @@ def get_tree(
return get_children(children[parent_id]) return get_children(children[parent_id])
def items(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]: def items_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
""" """
Item list slide. Item list slide.
@ -63,7 +67,9 @@ def items(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
return {"items": agenda_items} return {"items": agenda_items}
def list_of_speakers(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]: def list_of_speakers_slide(
all_data: AllData, element: Dict[str, Any]
) -> Dict[str, Any]:
""" """
List of speakers slide. List of speakers slide.
@ -76,7 +82,7 @@ def list_of_speakers(element: Dict[str, Any], all_data: AllData) -> Dict[str, An
try: try:
item = all_data["agenda/item"][item_id] item = all_data["agenda/item"][item_id]
except KeyError: except KeyError:
return {"error": f"Item {item_id} does not exist"} raise ProjectorElementException(f"Item {item_id} does not exist")
user_ids = [] user_ids = []
for speaker in item["speakers"]: for speaker in item["speakers"]:
@ -84,6 +90,6 @@ def list_of_speakers(element: Dict[str, Any], all_data: AllData) -> Dict[str, An
return {"user_ids": user_ids} return {"user_ids": user_ids}
def register_projector_elements() -> None: def register_projector_slides() -> None:
register_projector_element("agenda/item-list", items) register_projector_slide("agenda/item-list", items_slide)
register_projector_element("agenda/list-of-speakers", list_of_speakers) register_projector_slide("agenda/list-of-speakers", list_of_speakers_slide)

View File

@ -15,12 +15,12 @@ class AssignmentsAppConfig(AppConfig):
from ..utils.access_permissions import required_user from ..utils.access_permissions import required_user
from ..utils.rest_api import router from ..utils.rest_api import router
from . import serializers # noqa from . import serializers # noqa
from .projector import register_projector_elements from .projector import register_projector_slides
from .signals import get_permission_change_data from .signals import get_permission_change_data
from .views import AssignmentViewSet, AssignmentPollViewSet from .views import AssignmentViewSet, AssignmentPollViewSet
# Define projector elements. # Define projector elements.
register_projector_elements() register_projector_slides()
# Connect signals. # Connect signals.
permission_change.connect( permission_change.connect(

View File

@ -1,6 +1,6 @@
from typing import Any, Dict from typing import Any, Dict
from ..utils.projector import register_projector_element from ..utils.projector import AllData, register_projector_slide
# Important: All functions have to be prune. This means, that thay can only # Important: All functions have to be prune. This means, that thay can only
@ -9,9 +9,7 @@ from ..utils.projector import register_projector_element
# to be fast! # to be fast!
def assignment( def assignment_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
""" """
Assignment slide. Assignment slide.
""" """
@ -19,5 +17,5 @@ def assignment(
return {"error": "TODO"} return {"error": "TODO"}
def register_projector_elements() -> None: def register_projector_slides() -> None:
register_projector_element("assignments/assignment", assignment) register_projector_slide("assignments/assignment", assignment_slide)

View File

@ -17,7 +17,7 @@ class CoreAppConfig(AppConfig):
def ready(self): def ready(self):
# Import all required stuff. # Import all required stuff.
from .config import config from .config import config
from .projector import register_projector_elements from .projector import register_projector_slides
from . import serializers # noqa from . import serializers # noqa
from .signals import ( from .signals import (
delete_django_app_permissions, delete_django_app_permissions,
@ -49,7 +49,7 @@ class CoreAppConfig(AppConfig):
config.collect_config_variables_from_apps() config.collect_config_variables_from_apps()
# Define projector elements. # Define projector elements.
register_projector_elements() register_projector_slides()
# Connect signals. # Connect signals.
post_permission_creation.connect( post_permission_creation.connect(

View File

@ -1,6 +1,6 @@
from typing import Any, Dict from typing import Any, Dict
from ..utils.projector import register_projector_element from ..utils.projector import AllData, register_projector_slide
# Important: All functions have to be prune. This means, that thay can only # Important: All functions have to be prune. This means, that thay can only
@ -9,9 +9,7 @@ from ..utils.projector import register_projector_element
# to be fast! # to be fast!
def countdown( def countdown_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
""" """
Countdown slide. Countdown slide.
@ -30,9 +28,7 @@ def countdown(
return {"error": f"Countdown {countdown_id} does not exist"} return {"error": f"Countdown {countdown_id} does not exist"}
def message( def message_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
""" """
Message slide. Message slide.
@ -51,7 +47,7 @@ def message(
return {"error": f"Message {message_id} does not exist"} return {"error": f"Message {message_id} does not exist"}
def register_projector_elements() -> None: def register_projector_slides() -> None:
register_projector_element("core/countdown", countdown) register_projector_slide("core/countdown", countdown_slide)
register_projector_element("core/projector-message", message) register_projector_slide("core/projector-message", message_slide)
# TODO: Add clock slide # TODO: Add clock slide

View File

@ -1,6 +1,6 @@
from typing import Any from typing import Any
from ..utils.projector import projector_elements from ..utils.projector import projector_slides
from ..utils.rest_api import Field, IntegerField, ModelSerializer, ValidationError from ..utils.rest_api import Field, IntegerField, ModelSerializer, ValidationError
from ..utils.validate import validate_html from ..utils.validate import validate_html
from .models import ( from .models import (
@ -56,7 +56,7 @@ def elements_validator(value: Any) -> None:
raise ValidationError( raise ValidationError(
{"detail": "Every dictionary must have a key 'name'."} {"detail": "Every dictionary must have a key 'name'."}
) )
if element["name"] not in projector_elements: if element["name"] not in projector_slides:
raise ValidationError( raise ValidationError(
{"detail": f"Unknown projector element {element['name']},"} {"detail": f"Unknown projector element {element['name']},"}
) )

View File

@ -12,14 +12,14 @@ class MediafilesAppConfig(AppConfig):
# Import all required stuff. # Import all required stuff.
from openslides.core.signals import permission_change from openslides.core.signals import permission_change
from openslides.utils.rest_api import router from openslides.utils.rest_api import router
from .projector import register_projector_elements from .projector import register_projector_slides
from .signals import get_permission_change_data from .signals import get_permission_change_data
from .views import MediafileViewSet from .views import MediafileViewSet
from . import serializers # noqa from . import serializers # noqa
from ..utils.access_permissions import required_user from ..utils.access_permissions import required_user
# Define projector elements. # Define projector elements.
register_projector_elements() register_projector_slides()
# Connect signals. # Connect signals.
permission_change.connect( permission_change.connect(

View File

@ -1,6 +1,6 @@
from typing import Any, Dict from typing import Any, Dict
from ..utils.projector import register_projector_element from ..utils.projector import AllData, register_projector_slide
# Important: All functions have to be prune. This means, that thay can only # Important: All functions have to be prune. This means, that thay can only
@ -9,14 +9,12 @@ from ..utils.projector import register_projector_element
# to be fast! # to be fast!
def mediafile( def mediafile_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
""" """
Slide for Mediafile. Slide for Mediafile.
""" """
return {"error": "TODO"} return {"error": "TODO"}
def register_projector_elements() -> None: def register_projector_slides() -> None:
register_projector_element("mediafiles/mediafile", mediafile) register_projector_slide("mediafiles/mediafile", mediafile_slide)

View File

@ -13,7 +13,7 @@ class MotionsAppConfig(AppConfig):
# Import all required stuff. # Import all required stuff.
from openslides.core.signals import permission_change from openslides.core.signals import permission_change
from openslides.utils.rest_api import router from openslides.utils.rest_api import router
from .projector import register_projector_elements from .projector import register_projector_slides
from .signals import create_builtin_workflows, get_permission_change_data from .signals import create_builtin_workflows, get_permission_change_data
from . import serializers # noqa from . import serializers # noqa
from .views import ( from .views import (
@ -30,7 +30,7 @@ class MotionsAppConfig(AppConfig):
from ..utils.access_permissions import required_user from ..utils.access_permissions import required_user
# Define projector elements. # Define projector elements.
register_projector_elements() register_projector_slides()
# Connect signals. # Connect signals.
post_migrate.connect( post_migrate.connect(

View File

@ -87,6 +87,7 @@ class MotionManager(models.Manager):
"tags", "tags",
"submitters", "submitters",
"supporters", "supporters",
"change_recommendations",
) )
) )

View File

@ -1,6 +1,12 @@
from typing import Any, Dict from typing import Any, Dict
from ..utils.projector import AllData, get_config, get_user, register_projector_element from ..users.projector import get_user_name
from ..utils.projector import (
AllData,
ProjectorElementException,
get_config,
register_projector_slide,
)
# Important: All functions have to be prune. This means, that thay can only # Important: All functions have to be prune. This means, that thay can only
@ -21,10 +27,12 @@ def get_state(
for state in states: for state in states:
if state["id"] == state_id: if state["id"] == state_id:
return state return state
return {"error": f"motion {motion['id']} can not have to id {state_id}"} raise ProjectorElementException(
f"motion {motion['id']} can not be on the state with id {state_id}"
)
def motion_slide(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]: def motion_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
""" """
Motion slide. Motion slide.
@ -53,7 +61,7 @@ def motion_slide(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
try: try:
motion = all_data["motions/motion"][motion_id] motion = all_data["motions/motion"][motion_id]
except KeyError: except KeyError:
return {"error": f"motion with id {motion_id} does not exist"} raise ProjectorElementException(f"motion with id {motion_id} does not exist")
show_meta_box = not get_config(all_data, "motions_disable_sidebox_on_projector") show_meta_box = not get_config(all_data, "motions_disable_sidebox_on_projector")
@ -68,31 +76,38 @@ def motion_slide(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
if not get_config(all_data, "motions_disable_reason_on_projector"): if not get_config(all_data, "motions_disable_reason_on_projector"):
return_value["reason"] = motion["reason"] return_value["reason"] = motion["reason"]
if mode == "final": if mode == "final":
return_value["modified_final_version"] = motion["modified_final_version"] return_value["modified_final_version"] = motion["modified_final_version"]
if show_meta_box: if show_meta_box:
state = get_state(all_data, motion, motion["state_id"]) state = get_state(all_data, motion, motion["state_id"])
if state.get("error"):
return state
return_value["state"] = state["name"] return_value["state"] = state["name"]
if state["show_state_extension_field"]:
return_value["state_extension"] = motion["state_extension"] return_value["state_extension"] = motion["state_extension"]
if ( if (
not get_config(all_data, "motions_disable_recommendation_on_projector") not get_config(all_data, "motions_disable_recommendation_on_projector")
and motion["recommendation_id"] and motion["recommendation_id"]
): ):
return_value["recommendation"] = all_data[ recommendation_state = get_state(
"motions/motion-change-recommendation" all_data, motion, motion["recommendation_id"]
][motion["recommendation_id"]]["text"] )
return_value["recommendation"] = recommendation_state[
"recommendation_label"
]
if recommendation_state["show_recommendation_extension_field"]:
return_value["recommendation_extension"] = motion[ return_value["recommendation_extension"] = motion[
"recommendation_extension" "recommendation_extension"
] ]
return_value["change_recommendations"] = motion["change_recommendations"]
return_value["submitter"] = [ return_value["submitter"] = [
get_user(all_data, submitter["user_id"]) get_user_name(all_data, submitter["user_id"])
for submitter in motion["submitters"] for submitter in sorted(
motion["submitters"], key=lambda submitter: submitter["weight"]
)
] ]
for poll in motion["polls"][::-1]: for poll in motion["polls"][::-1]:
@ -107,13 +122,13 @@ def motion_slide(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
return return_value return return_value
def motion_block(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]: def motion_block_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
""" """
Motion slide. Motion slide.
""" """
return {"error": "TODO"} return {"error": "TODO"}
def register_projector_elements() -> None: def register_projector_slides() -> None:
register_projector_element("motions/motion", motion_slide) register_projector_slide("motions/motion", motion_slide)
register_projector_element("motions/motion-block", motion_block) register_projector_slide("motions/motion-block", motion_block_slide)

View File

@ -400,6 +400,9 @@ class MotionSerializer(ModelSerializer):
) )
agenda_parent_id = IntegerField(write_only=True, required=False, min_value=1) agenda_parent_id = IntegerField(write_only=True, required=False, min_value=1)
submitters = SubmitterSerializer(many=True, read_only=True) submitters = SubmitterSerializer(many=True, read_only=True)
change_recommendations = MotionChangeRecommendationSerializer(
many=True, read_only=True
)
class Meta: class Meta:
model = Motion model = Motion
@ -436,6 +439,7 @@ class MotionSerializer(ModelSerializer):
"weight", "weight",
"created", "created",
"last_modified", "last_modified",
"change_recommendations",
) )
read_only_fields = ( read_only_fields = (
"state", "state",

View File

@ -10,13 +10,13 @@ class TopicsAppConfig(AppConfig):
# Import all required stuff. # Import all required stuff.
from openslides.core.signals import permission_change from openslides.core.signals import permission_change
from ..utils.rest_api import router from ..utils.rest_api import router
from .projector import register_projector_elements from .projector import register_projector_slides
from .signals import get_permission_change_data from .signals import get_permission_change_data
from .views import TopicViewSet from .views import TopicViewSet
from . import serializers # noqa from . import serializers # noqa
# Define projector elements. # Define projector elements.
register_projector_elements() register_projector_slides()
# Connect signals. # Connect signals.
permission_change.connect( permission_change.connect(

View File

@ -1,6 +1,6 @@
from typing import Any, Dict from typing import Any, Dict
from ..utils.projector import register_projector_element from ..utils.projector import AllData, register_projector_slide
# Important: All functions have to be prune. This means, that thay can only # Important: All functions have to be prune. This means, that thay can only
@ -9,14 +9,12 @@ from ..utils.projector import register_projector_element
# to be fast! # to be fast!
def topic( def topic_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
""" """
Topic slide. Topic slide.
""" """
return {"error": "TODO"} return {"error": "TODO"}
def register_projector_elements() -> None: def register_projector_slides() -> None:
register_projector_element("topics/topic", topic) register_projector_slide("topics/topic", topic_slide)

View File

@ -13,12 +13,12 @@ class UsersAppConfig(AppConfig):
from . import serializers # noqa from . import serializers # noqa
from ..core.signals import post_permission_creation, permission_change from ..core.signals import post_permission_creation, permission_change
from ..utils.rest_api import router from ..utils.rest_api import router
from .projector import register_projector_elements from .projector import register_projector_slides
from .signals import create_builtin_groups_and_admin, get_permission_change_data from .signals import create_builtin_groups_and_admin, get_permission_change_data
from .views import GroupViewSet, PersonalNoteViewSet, UserViewSet from .views import GroupViewSet, PersonalNoteViewSet, UserViewSet
# Define projector elements. # Define projector elements.
register_projector_elements() register_projector_slides()
# Connect signals. # Connect signals.
post_permission_creation.connect( post_permission_creation.connect(

View File

@ -1,6 +1,6 @@
from typing import Any, Dict from typing import Any, Dict, List
from ..utils.projector import register_projector_element from ..utils.projector import AllData, register_projector_slide
# Important: All functions have to be prune. This means, that thay can only # Important: All functions have to be prune. This means, that thay can only
@ -9,14 +9,28 @@ from ..utils.projector import register_projector_element
# to be fast! # to be fast!
def user( def user_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
""" """
User slide. User slide.
""" """
return {"error": "TODO"} return {"error": "TODO"}
def register_projector_elements() -> None: def get_user_name(all_data: AllData, user_id: int) -> str:
register_projector_element("users/user", user) """
Returns the short name for an user_id.
"""
user = all_data["users/user"][user_id]
name_parts: List[str] = []
for name_part in ("title", "first_name", "last_name"):
if user[name_part]:
name_parts.append(user[name_part])
if not name_part:
name_parts.append(user["username"])
if user["structure_level"]:
name_parts.append(f"({user['structure_level']})")
return " ".join(name_parts)
def register_projector_slides() -> None:
register_projector_slide("users/user", user_slide)

View File

@ -11,19 +11,25 @@ from .cache import element_cache
AllData = Dict[str, Dict[int, Dict[str, Any]]] AllData = Dict[str, Dict[int, Dict[str, Any]]]
ProjectorElementCallable = Callable[[Dict[str, Any], AllData], Dict[str, Any]] ProjectorSlide = Callable[[AllData, Dict[str, Any]], Dict[str, Any]]
projector_elements: Dict[str, ProjectorElementCallable] = {} projector_slides: Dict[str, ProjectorSlide] = {}
def register_projector_element(name: str, element: ProjectorElementCallable) -> None: class ProjectorElementException(Exception):
""" """
Registers a projector element. Exception for errors in one element on the projector.
"""
def register_projector_slide(name: str, slide: ProjectorSlide) -> None:
"""
Registers a projector slide.
Has to be called in the app.ready method. Has to be called in the app.ready method.
""" """
projector_elements[name] = element projector_slides[name] = slide
async def get_projector_data( async def get_projector_data(
@ -75,10 +81,12 @@ async def get_projector_data(
projector_data[projector_id] = [] projector_data[projector_id] = []
for element in projector["elements"]: for element in projector["elements"]:
projector_element = projector_elements[element["name"]] projector_slide = projector_slides[element["name"]]
projector_data[projector_id].append( try:
{"data": projector_element(element, all_data), "element": element} data = projector_slide(all_data, element)
) except ProjectorElementException as err:
data = {"error": err}
projector_data[projector_id].append({"data": data, "element": element})
return projector_data return projector_data
@ -92,15 +100,3 @@ def get_config(all_data: AllData, key: str) -> Any:
return all_data[config.get_collection_string()][config.get_key_to_id()[key]][ return all_data[config.get_collection_string()][config.get_key_to_id()[key]][
"value" "value"
] ]
def get_user(all_data: AllData, user_id: int) -> Dict[str, Any]:
"""
Returns the value of a user to show his name.
"""
user = all_data["users/user"][user_id]
return {
"title": user["title"],
"first_name": user["first_name"],
"last_name": user["last_name"],
}

View File

@ -6,7 +6,7 @@ from django.test.utils import CaptureQueriesContext
from openslides.core.config import config from openslides.core.config import config
from openslides.core.models import Projector from openslides.core.models import Projector
from openslides.users.models import User from openslides.users.models import User
from openslides.utils.projector import AllData, get_config, register_projector_element from openslides.utils.projector import AllData, get_config, register_projector_slide
class TConfig: class TConfig:
@ -90,19 +90,19 @@ class TProjector:
return elements return elements
def slide1(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]: def slide1(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
""" """
Slide that shows the general_event_name. Slide that shows the general_event_name.
""" """
return {"name": "slide1", "event_name": get_config(all_data, "general_event_name")} return {"name": "slide1", "event_name": get_config(all_data, "general_event_name")}
def slide2(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]: def slide2(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
return {"name": "slide2"} return {"name": "slide2"}
register_projector_element("test/slide1", slide1) register_projector_slide("test/slide1", slide1)
register_projector_element("test/slide2", slide2) register_projector_slide("test/slide2", slide2)
def count_queries(func, *args, **kwargs) -> int: def count_queries(func, *args, **kwargs) -> int:

View File

@ -48,7 +48,8 @@ def test_motion_db_queries():
* 1 request to get the polls, * 1 request to get the polls,
* 1 request to get the attachments, * 1 request to get the attachments,
* 1 request to get the tags, * 1 request to get the tags,
* 2 requests to get the submitters and supporters. * 2 requests to get the submitters and supporters,
* 1 request for change_recommendations.
Two comment sections are created and for each motions two comments. Two comment sections are created and for each motions two comments.
""" """
@ -70,7 +71,7 @@ def test_motion_db_queries():
) )
# TODO: Create some polls etc. # TODO: Create some polls etc.
assert count_queries(Motion.get_elements) == 12 assert count_queries(Motion.get_elements) == 13
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)

View File

@ -86,32 +86,32 @@ def all_data():
def test_items(all_data): def test_items(all_data):
config: Dict[str, Any] = {} element: Dict[str, Any] = {}
data = projector.items(config, all_data) data = projector.items_slide(all_data, element)
assert data == {"items": ["Item1", "item2"]} assert data == {"items": ["Item1", "item2"]}
def test_items_parent(all_data): def test_items_parent(all_data):
config: Dict[str, Any] = {"id": 1} element: Dict[str, Any] = {"id": 1}
data = projector.items(config, all_data) data = projector.items_slide(all_data, element)
assert data == {"items": ["item4"]} assert data == {"items": ["item4"]}
def test_items_tree(all_data): def test_items_tree(all_data):
config: Dict[str, Any] = {"tree": True} element: Dict[str, Any] = {"tree": True}
data = projector.items(config, all_data) data = projector.items_slide(all_data, element)
assert data == {"items": [("Item1", [("item4", [])]), ("item2", [])]} assert data == {"items": [("Item1", [("item4", [])]), ("item2", [])]}
def test_items_tree_parent(all_data): def test_items_tree_parent(all_data):
config: Dict[str, Any] = {"tree": True, "id": 1} element: Dict[str, Any] = {"tree": True, "id": 1}
data = projector.items(config, all_data) data = projector.items_slide(all_data, element)
assert data == {"items": [("item4", [])]} assert data == {"items": [("item4", [])]}

View File

@ -156,7 +156,7 @@ def all_data():
def test_motion_slide(all_data): def test_motion_slide(all_data):
element: Dict[str, Any] = {"id": 1} element: Dict[str, Any] = {"id": 1}
data = projector.motion_slide(element, all_data) data = projector.motion_slide(all_data, element)
assert data == { assert data == {
"identifier": "4", "identifier": "4",
@ -167,7 +167,6 @@ def test_motion_slide(all_data):
"show_meta_box": True, "show_meta_box": True,
"reason": "", "reason": "",
"state": "submitted", "state": "submitted",
"state_extension": None, "submitter": ["Administrator"],
"submitter": [{"first_name": "", "last_name": "Administrator", "title": ""}],
"poll": {"yes": "10.000000", "no": "-1.000000", "abstain": "20.000000"}, "poll": {"yes": "10.000000", "no": "-1.000000", "abstain": "20.000000"},
} }