Skip to content

Conversation

hjanott
Copy link
Member

@hjanott hjanott commented Aug 27, 2025

Everything related to migrations and organization import was left out or still won't work.
In equal fields tests generic relation lists to generic relations lists cannot be checked as this is not yet implemented by the backend/meta.
Two tests treating locked fields behaviour were unclear to me if they are still needed that way. I require feedback on that.
Needs OpenSlides/openslides-meta#306

@hjanott hjanott added this to the 4.x milestone Aug 27, 2025
@hjanott hjanott added the tests label Aug 27, 2025
Copy link
Member

@luisa-beerboom luisa-beerboom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't reviewed everything yet, but here's a start

Comment on lines 37 to 38
self.execute_other_action(TopicDelete, [{"id": topic_fqid}])
return instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary? Shouldn't topics be cascade deleted?

Copy link
Member Author

@hjanott hjanott Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are cascade deleted but the problem lies in the fact that the list_of_speakers content_object_id will be set to None if not deleted as one of the first models. That leads later to the topics list_of_speakers_id to also be set to None by the relation handling, which is not legal as it is a required field. By first deleting the topic this is no problem any longer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the fact that the content_object_id will be set to None if not deleted as one of the first models but the content object will not be deleted before that.

I don't understand what this is supposed to refer to. Please rephrase it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rephrased it. I'm currently thinking if this would better be solved in the los delete action. But there also seems to be a problem with the other referenced collections like motion_block.

this_fqid = fqid_from_collection_and_id(self.model.collection, instance["id"])

# Have been here. Seen it all.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@@ -118,6 +120,14 @@ def apply_changed_model(
if "id" not in self._changed_models[collection][id_]:
self._changed_models[collection][id_]["id"] = id_

def apply_to_be_deleted(self, fqid: FullQualifiedId) -> None:
"""Meaning both: to be deleted in the future and the past."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this comment mean? (The same question also concerns the other three below it that have a similar format)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The model will be marked as to be deleted. This will not be undone when it is marked as deleted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then write that.
Please also do the same for the three other places where you used the same formulation.

Copy link
Member

@luisa-beerboom luisa-beerboom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the rest of the review


from .base import BaseActionTestCase


class GeneralActionCommandFormat(BaseActionTestCase):
# TODO later: either delete commented out code or implement locked fields
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to write this TODO above the commented-out code to avoid misunderstandings in case something else is also commented out later for a different reason

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 187 to 216
@classmethod
def setUpClass(cls) -> None:
super().setUpClass()
create_table_view(yml)

@classmethod
def tearDownClass(cls) -> None:
super().tearDownClass()
with get_new_os_conn() as conn:
with conn.cursor() as curs:
curs.execute(
f"""
DROP TABLE {collection_a}_t CASCADE;
DROP TABLE {collection_b}_t CASCADE;
DROP TABLE {collection_c}_t CASCADE;
DROP TABLE {collection_d}_t CASCADE;
"""
)

def tearDown(self) -> None:
super().tearDown()
with self.connection.cursor() as curs:
curs.execute(
f"""
TRUNCATE TABLE {collection_a}_t RESTART IDENTITY CASCADE;
TRUNCATE TABLE {collection_b}_t RESTART IDENTITY CASCADE;
TRUNCATE TABLE {collection_c}_t RESTART IDENTITY CASCADE;
TRUNCATE TABLE {collection_d}_t RESTART IDENTITY CASCADE;
"""
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this exact code in test_create_relation and test_equal_fields_check as well. Perhaps you could reduce boilerplate by creating a new class that does this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Will do.

Comment on lines 170 to 199
@classmethod
def setUpClass(cls) -> None:
super().setUpClass()
create_table_view(yml)

@classmethod
def tearDownClass(cls) -> None:
super().tearDownClass()
with get_new_os_conn() as conn:
with conn.cursor() as curs:
curs.execute(
f"""
DROP TABLE nm_fake_model_ef_b_c_ids_fake_model_ef_c_t CASCADE;
DROP TABLE {collection_a}_t CASCADE;
DROP TABLE {collection_b}_t CASCADE;
DROP TABLE {collection_c}_t CASCADE;
"""
)

def tearDown(self) -> None:
super().tearDown()
with self.connection.cursor() as curs:
curs.execute(
f"""
TRUNCATE TABLE nm_fake_model_ef_b_c_ids_fake_model_ef_c_t RESTART IDENTITY CASCADE;
TRUNCATE TABLE {collection_a}_t RESTART IDENTITY CASCADE;
TRUNCATE TABLE {collection_b}_t RESTART IDENTITY CASCADE;
TRUNCATE TABLE {collection_c}_t RESTART IDENTITY CASCADE;
"""
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here as what I already said in test_delete_cascade

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -42,13 +76,46 @@ class FakeModelURAUpdateAction(UpdateAction):


class TestUpdateRelation(BaseActionTestCase):
def test_set_to_null(self) -> None:
@classmethod
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same kind of setUpClass, tearDownClass and tearDown functions as in test_delete_cascade

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

self.datastore.apply_changed_model(this_fqid, DeletedModel())
for field in self.model.get_relation_fields():
delete_actions: list[tuple[type[Action], ActionData]] = []
for field_name in sorted(db_instance):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why these fields have to be sorted?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no reason anymore. So I removed that.

Comment on lines 50 to 67
self.assertCountEqual(
write_requests[0].locked_fields.keys(),
[
"group/weight",
"meeting/1/group_ids",
],
)
# self.assertCountEqual(
# write_requests[0].locked_fields.keys(),
# [
# "group/weight",
# "meeting/1/group_ids",
# ],
# )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are this and next 3 commented asserts not needed anymore or you were planning to replace them? If it's something we want to observe in the future, maybe it's worth adding a comment about the reasons of commenting in this file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* error handling on 1_1 not null constraint
* improve deletion logic
* type handling for organization import
* try_get_field as class method
* type handling for Checker
* add list_of_speakers to create_motion
* various improvements
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants