Skip to content

Commit

Permalink
Fix meeting.clone list election behaviour (#2791) (#2802)
Browse files Browse the repository at this point in the history
Co-authored-by: luisa-beerboom <[email protected]>
  • Loading branch information
1 parent bc6e7e9 commit dba5e0c
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 4 deletions.
12 changes: 8 additions & 4 deletions openslides_backend/shared/export_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

FORBIDDEN_FIELDS = ["forwarded_motion_ids"]

NON_CASCADING_MEETING_RELATION_LISTS = ["poll_candidate_list_ids", "poll_candidate_ids"]


def export_meeting(
datastore: DatastoreService, meeting_id: int, internal_target: bool = False
Expand Down Expand Up @@ -200,10 +202,12 @@ def remove_meta_fields(res: dict[str, Any]) -> dict[str, Any]:

def get_relation_fields() -> Iterable[RelationListField]:
for field in Meeting().get_relation_fields():
if (
isinstance(field, RelationListField)
and field.on_delete == OnDelete.CASCADE
and field.get_own_field_name().endswith("_ids")
if isinstance(field, RelationListField) and (
(
field.on_delete == OnDelete.CASCADE
and field.get_own_field_name().endswith("_ids")
)
or field.get_own_field_name() in NON_CASCADING_MEETING_RELATION_LISTS
):
yield field

Expand Down
2 changes: 2 additions & 0 deletions tests/system/action/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ def create_meeting(self, base: int = 1) -> None:
"committee_id": committee_id,
"is_active_in_organization_id": 1,
"language": "en",
"motion_state_ids": [base],
"motion_workflow_ids": [base],
},
f"group/{base}": {
"meeting_id": base,
Expand Down
143 changes: 143 additions & 0 deletions tests/system/action/meeting/test_clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from unittest.mock import MagicMock

from openslides_backend.action.action_worker import ActionWorkerState
from openslides_backend.models.mixins import MeetingModelMixin
from openslides_backend.models.models import AgendaItem, Meeting
from openslides_backend.shared.util import (
ONE_ORGANIZATION_FQID,
Expand Down Expand Up @@ -2139,3 +2140,145 @@ def test_clone_non_template_and_committee_change_not_allowed(self) -> None:
response.json["message"]
== "Cannot clone meeting to a different committee if it is a non-template meeting."
)

def test_clone_with_list_election(self) -> None:
self.create_meeting()
self.set_user_groups(1, [2])
self.create_user("Huey", [3])
self.create_user("Dewey", [3])
self.create_user("Louie", [3])
self.set_models(
{
"user/2": {
"organization_id": 1,
"poll_candidate_ids": [1],
},
"user/3": {
"organization_id": 1,
"poll_candidate_ids": [2],
},
"user/4": {
"organization_id": 1,
"poll_candidate_ids": [3],
},
"organization/1": {
"user_ids": [1, 2, 3, 4],
},
"motion_workflow/1": {
"name": "Workflow",
"sequential_number": 1,
"default_amendment_workflow_meeting_id": 1,
},
"motion_state/1": {
"name": "State",
"weight": 1,
},
"projector/1": {
"name": "default",
"meeting_id": 1,
"used_as_reference_projector_meeting_id": 1,
"sequential_number": 1,
**{
key: 1 for key in MeetingModelMixin.reverse_default_projectors()
},
},
"list_of_speakers/1": {
"id": 1,
"closed": False,
"meeting_id": 1,
"content_object_id": "assignment/1",
"sequential_number": 1,
},
"meeting/1": {
"id": 1,
"name": "Duckburg town government",
"poll_ids": [1],
"option_ids": [1, 2],
"projector_ids": [1],
"assignment_ids": [1],
"poll_candidate_ids": [1, 2, 3],
"list_of_speakers_ids": [1],
"reference_projector_id": 1,
"poll_candidate_list_ids": [1],
**{key: [1] for key in MeetingModelMixin.all_default_projectors()},
"motions_default_amendment_workflow_id": 1,
},
"assignment/1": {
"id": 1,
"phase": "search",
"title": "Duckburg town council",
"poll_ids": [1],
"meeting_id": 1,
"open_posts": 0,
"sequential_number": 1,
"list_of_speakers_id": 1,
},
"poll_candidate/1": {
"id": 1,
"weight": 1,
"user_id": 2,
"meeting_id": 1,
"poll_candidate_list_id": 1,
},
"poll_candidate/2": {
"id": 2,
"weight": 2,
"user_id": 3,
"meeting_id": 1,
"poll_candidate_list_id": 1,
},
"poll_candidate/3": {
"id": 3,
"weight": 3,
"user_id": 4,
"meeting_id": 1,
"poll_candidate_list_id": 1,
},
"poll_candidate_list/1": {
"id": 1,
"option_id": 1,
"meeting_id": 1,
"poll_candidate_ids": [1, 2, 3],
},
"option/1": {
"id": 1,
"weight": 1,
"poll_id": 1,
"meeting_id": 1,
"content_object_id": "poll_candidate_list/1",
},
"option/2": {
"id": 2,
"text": "global option",
"weight": 1,
"meeting_id": 1,
"used_as_global_option_in_poll_id": 1,
},
"poll/1": {
"id": 1,
"type": "pseudoanonymous",
"state": "created",
"title": "First election",
"backend": "fast",
"global_no": False,
"votescast": "0.000000",
"global_yes": False,
"meeting_id": 1,
"option_ids": [1],
"pollmethod": "YNA",
"votesvalid": "0.000000",
"votesinvalid": "0.000000",
"global_abstain": False,
"global_option_id": 2,
"max_votes_amount": 1,
"min_votes_amount": 1,
"content_object_id": "assignment/1",
"sequential_number": 1,
"is_pseudoanonymized": True,
"max_votes_per_option": 1,
"onehundred_percent_base": "disabled",
},
}
)
response = self.request("meeting.clone", {"meeting_id": 1})
self.assert_status_code(response, 200)

0 comments on commit dba5e0c

Please sign in to comment.