Skip to content

Commit

Permalink
End interposed questions with their parents (#2139)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsangmeister authored Jan 22, 2024
1 parent e87945d commit 740dbbd
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
38 changes: 36 additions & 2 deletions openslides_backend/action/actions/speaker/end_speech.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from time import time
from typing import Any, Dict

from openslides_backend.action.actions.speaker.delete import SpeakerDeleteAction
from openslides_backend.action.actions.speaker.speech_state import SpeechState
from openslides_backend.action.mixins.singular_action_mixin import SingularActionMixin
from openslides_backend.action.util.typing import ActionData
from openslides_backend.shared.filters import And, FilterOperator

from ....models.models import Speaker
from ....permissions.permissions import Permissions
Expand All @@ -27,6 +31,36 @@ class SpeakerEndSpeach(SingularActionMixin, CountdownControl, UpdateAction):
)
permission = Permissions.ListOfSpeakers.CAN_MANAGE

def get_updated_instances(self, action_data: ActionData) -> ActionData:
self.end_time = round(time())
instance = next(iter(action_data))
yield instance
# additionally yield all child interposed questions
db_instance = self.datastore.get(
fqid_from_collection_and_id("speaker", instance["id"]),
["list_of_speakers_id", "meeting_id", "speech_state"],
)
if db_instance.get("speech_state") != SpeechState.INTERPOSED_QUESTION:
result = self.datastore.filter(
"speaker",
And(
FilterOperator("meeting_id", "=", db_instance["meeting_id"]),
FilterOperator(
"list_of_speakers_id", "=", db_instance["list_of_speakers_id"]
),
FilterOperator(
"speech_state", "=", SpeechState.INTERPOSED_QUESTION
),
FilterOperator("end_time", "=", None),
),
["begin_time"],
)
for id, speaker in result.items():
if speaker.get("begin_time") is not None:
yield {"id": id}
else:
self.execute_other_action(SpeakerDeleteAction, [{"id": id}])

def update_instance(self, instance: Dict[str, Any]) -> Dict[str, Any]:
instance = super().update_instance(instance)
speaker = self.datastore.get(
Expand All @@ -46,7 +80,7 @@ def update_instance(self, instance: Dict[str, Any]) -> Dict[str, Any]:
raise ActionException(
f"Speaker {instance['id']} is not speaking at the moment."
)
instance["end_time"] = now = round(time())
instance["end_time"] = self.end_time

if speaker.get("pause_time"):
instance["total_pause"] = (
Expand All @@ -56,7 +90,7 @@ def update_instance(self, instance: Dict[str, Any]) -> Dict[str, Any]:
)
instance["pause_time"] = None
else:
self.decrease_structure_level_countdown(now, speaker)
self.decrease_structure_level_countdown(self.end_time, speaker)

self.control_los_countdown(speaker["meeting_id"], CountdownCommand.RESET)
return instance
40 changes: 40 additions & 0 deletions tests/system/action/speaker/test_end_speech.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,46 @@ def test_interposed_question(self) -> None:
def test_intervention(self) -> None:
self.with_structure_level_and_speech_state(SpeechState.INTERVENTION)

def test_end_started_child_interposed_question(self) -> None:
self.set_models(
{
"meeting_user/7": {"speaker_ids": [890, 891]},
"list_of_speakers/23": {"speaker_ids": [890, 891], "meeting_id": 1},
"speaker/890": {
"pause_time": 11000,
},
"speaker/891": {
"meeting_user_id": 7,
"list_of_speakers_id": 23,
"begin_time": 10000,
"speech_state": SpeechState.INTERPOSED_QUESTION,
"meeting_id": 1,
},
}
)
response = self.request("speaker.end_speech", {"id": 890})
self.assert_status_code(response, 200)
speaker = self.get_model("speaker/891")
self.assertIsNotNone(speaker.get("end_time"))
self.assert_model_exists("speaker/890", {"end_time": speaker["end_time"]})

def test_end_waiting_child_interposed_question(self) -> None:
self.set_models(
{
"meeting_user/7": {"speaker_ids": [890, 891]},
"list_of_speakers/23": {"speaker_ids": [890, 891], "meeting_id": 1},
"speaker/891": {
"meeting_user_id": 7,
"list_of_speakers_id": 23,
"speech_state": SpeechState.INTERPOSED_QUESTION,
"meeting_id": 1,
},
}
)
response = self.request("speaker.end_speech", {"id": 890})
self.assert_status_code(response, 200)
self.assert_model_deleted("speaker/891")

def test_end_speech_no_permissions(self) -> None:
self.base_permission_test(self.models, "speaker.end_speech", {"id": 890})

Expand Down

0 comments on commit 740dbbd

Please sign in to comment.