Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement readding of interposed questions #2237

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/actions/list_of_speakers.re_add_last.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Readds the last finished speaker user (the highest `end_time`) to the list of waiting speakers. This fails, if
- There is no last finished speaker
- The last finished speaker is already a waiting speaker with the same point-of-order status
- The speech state of the last speaker is `interposed_question` and there is no unfinished speaker

The new waiting speaker gets the weight of `min-1` of all waiting speakers or 1, if there are no waiting speakers.

Expand Down
2 changes: 1 addition & 1 deletion global/meta
11 changes: 11 additions & 0 deletions openslides_backend/action/actions/list_of_speakers/re_add_last.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def update_instance(self, instance: dict[str, Any]) -> dict[str, Any]:
mapped_fields=[
"id",
"end_time",
"begin_time",
"meeting_user_id",
"weight",
"point_of_order",
Expand All @@ -53,6 +54,7 @@ def update_instance(self, instance: dict[str, Any]) -> dict[str, Any]:

# Get last speaker.
last_speaker, lowest_weight = None, None
has_current_speaker = False
for speaker in speakers.values():
speaker_weight = speaker.get("weight") or 0
if lowest_weight is None or speaker_weight < lowest_weight:
Expand All @@ -63,9 +65,18 @@ def update_instance(self, instance: dict[str, Any]) -> dict[str, Any]:
last_speaker
):
last_speaker = speaker
elif speaker.get("begin_time") is not None:
has_current_speaker = True
if last_speaker is None:
raise ActionException("There is no last speaker that can be re-added.")
assert isinstance(lowest_weight, int)
if (
last_speaker.get("speech_state") == "interposed_question"
and not has_current_speaker
):
raise ActionException(
"Can't re-add interposed question when there's no current speaker"
)

meeting = self.datastore.get(
fqid_from_collection_and_id("meeting", meeting_id),
Expand Down
85 changes: 85 additions & 0 deletions tests/system/action/list_of_speakers/test_re_add_last.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,89 @@ def test_last_speaker_also_in_waiting_list_allowed(self) -> None:
response = self.request("list_of_speakers.re_add_last", {"id": 111})
self.assert_status_code(response, 200)

def test_with_interposed_question(self) -> None:
self.set_models(
{
"meeting/1": {
"list_of_speakers_enable_interposed_question": True,
},
"list_of_speakers/222": {
"meeting_id": 1,
"speaker_ids": [333, 334, 335],
},
"speaker/333": {
"list_of_speakers_id": 222,
"meeting_user_id": 42,
"begin_time": 1000,
"total_pause": 1000,
"meeting_id": 1,
"weight": 1,
},
"speaker/334": {
"list_of_speakers_id": 222,
"meeting_user_id": 43,
"meeting_id": 1,
"weight": 2,
},
"speaker/335": {
"list_of_speakers_id": 222,
"meeting_user_id": 44,
"meeting_id": 1,
"weight": 1,
"begin_time": 1500,
"end_time": 2500,
"speech_state": "interposed_question",
},
}
)
response = self.request("list_of_speakers.re_add_last", {"id": 222})
self.assert_status_code(response, 200)
self.assert_model_exists("speaker/333", {"weight": 1})
self.assert_model_exists("speaker/334", {"weight": 2})
self.assert_model_exists("speaker/335", {"weight": 0})

def test_with_interposed_question_error(self) -> None:
self.set_models(
{
"meeting/1": {
"list_of_speakers_enable_interposed_question": True,
},
"list_of_speakers/222": {
"meeting_id": 1,
"speaker_ids": [333, 334, 335],
},
"speaker/333": {
"list_of_speakers_id": 222,
"meeting_user_id": 42,
"begin_time": 1000,
"end_time": 1500,
"meeting_id": 1,
"weight": 1,
},
"speaker/334": {
"list_of_speakers_id": 222,
"meeting_user_id": 43,
"meeting_id": 1,
"weight": 2,
},
"speaker/335": {
"list_of_speakers_id": 222,
"meeting_user_id": 44,
"meeting_id": 1,
"weight": 1,
"begin_time": 1500,
"end_time": 2500,
"speech_state": "interposed_question",
},
}
)
response = self.request("list_of_speakers.re_add_last", {"id": 222})
self.assert_status_code(response, 400)
assert (
"Can't re-add interposed question when there's no current speaker"
in response.json["message"]
)

def test_last_speaker_also_in_waiting_list_but_poos(self) -> None:
self.set_models(
{
Expand Down Expand Up @@ -252,6 +335,8 @@ def test_tie_breakers(self) -> None:
"end_time": None,
},
)
if i == 222:
self.request("speaker.speak", {"id": 222})

def test_re_add_last_no_permissions(self) -> None:
self.base_permission_test(
Expand Down
Loading