import pytest from django.contrib.auth import get_user_model from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient from openslides.core.config import config from openslides.motions.models import ( Category, Motion, MotionBlock, MotionChangeRecommendation, MotionComment, MotionCommentSection, State, StatuteParagraph, Workflow, ) from openslides.utils.auth import get_group_model from openslides.utils.autoupdate import inform_changed_data from tests.common_groups import GROUP_ADMIN_PK, GROUP_DELEGATE_PK, GROUP_STAFF_PK from tests.count_queries import count_queries from tests.test_case import TestCase @pytest.mark.django_db(transaction=False) def test_category_db_queries(): """ Tests that only the following db queries are done: * 1 requests to get the list of all categories. """ for index in range(10): Category.objects.create(name=f"category{index}") assert count_queries(Category.get_elements)() == 1 @pytest.mark.django_db(transaction=False) def test_statute_paragraph_db_queries(): """ Tests that only the following db queries are done: * 1 requests to get the list of all statute paragraphs. """ for index in range(10): StatuteParagraph.objects.create( title=f"statute_paragraph{index}", text=f"text{index}" ) assert count_queries(StatuteParagraph.get_elements)() == 1 @pytest.mark.django_db(transaction=False) def test_workflow_db_queries(): """ Tests that only the following db queries are done: * 1 requests to get the list of all workflows and * 1 request to get all states. """ assert count_queries(Workflow.get_elements)() == 2 class TestStatuteParagraphs(TestCase): """ Tests all CRUD operations of statute paragraphs. """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") def create_statute_paragraph(self): self.title = "test_title_fiWs82D0D)2kje3KDm2s" self.text = "test_text_3jfjoDqm,S;cmor3DJwk" self.cp = StatuteParagraph.objects.create(title=self.title, text=self.text) def test_create_simple(self): response = self.client.post( reverse("statuteparagraph-list"), { "title": "test_title_f3FM328cq)tzdU238df2", "text": "test_text_2fb)BEjwdI38=kfemiRkcOW", }, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) cp = StatuteParagraph.objects.get() self.assertEqual(cp.title, "test_title_f3FM328cq)tzdU238df2") self.assertEqual(cp.text, "test_text_2fb)BEjwdI38=kfemiRkcOW") def test_create_without_data(self): response = self.client.post(reverse("statuteparagraph-list"), {}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, {"title": ["This field is required."], "text": ["This field is required."]}, ) def test_create_non_admin(self): self.admin = get_user_model().objects.get(username="admin") self.admin.groups.add(GROUP_DELEGATE_PK) self.admin.groups.remove(GROUP_ADMIN_PK) inform_changed_data(self.admin) response = self.client.post( reverse("statuteparagraph-list"), { "title": "test_title_f3(Dj2jdP39fjW2kdcwe", "text": "test_text_vlC)=fwWmcwcpWMvnuw(", }, ) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_retrieve_simple(self): self.create_statute_paragraph() response = self.client.get( reverse("statuteparagraph-detail", args=[self.cp.pk]) ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(response.data.keys()), sorted(("id", "title", "text", "weight")) ) def test_update_simple(self): self.create_statute_paragraph() response = self.client.patch( reverse("statuteparagraph-detail", args=[self.cp.pk]), {"text": "test_text_ke(czr/cwk1Sl2seeFwE"}, ) self.assertEqual(response.status_code, status.HTTP_200_OK) cp = StatuteParagraph.objects.get() self.assertEqual(cp.title, self.title) self.assertEqual(cp.text, "test_text_ke(czr/cwk1Sl2seeFwE") def test_update_non_admin(self): self.admin = get_user_model().objects.get(username="admin") self.admin.groups.add(GROUP_DELEGATE_PK) self.admin.groups.remove(GROUP_ADMIN_PK) inform_changed_data(self.admin) self.create_statute_paragraph() response = self.client.patch( reverse("statuteparagraph-detail", args=[self.cp.pk]), {"text": "test_text_ke(czr/cwk1Sl2seeFwE"}, ) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) cp = StatuteParagraph.objects.get() self.assertEqual(cp.text, self.text) def test_delete_simple(self): self.create_statute_paragraph() response = self.client.delete( reverse("statuteparagraph-detail", args=[self.cp.pk]) ) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(StatuteParagraph.objects.count(), 0) def test_delete_non_admin(self): self.admin = get_user_model().objects.get(username="admin") self.admin.groups.add(GROUP_DELEGATE_PK) self.admin.groups.remove(GROUP_ADMIN_PK) inform_changed_data(self.admin) self.create_statute_paragraph() response = self.client.delete( reverse("statuteparagraph-detail", args=[self.cp.pk]) ) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(StatuteParagraph.objects.count(), 1) class ManageComments(TestCase): """ Tests the manage_comment view. Tests creation/updating and deletion of motion comments. """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") self.admin = get_user_model().objects.get() self.group_out = get_group_model().objects.get( pk=GROUP_DELEGATE_PK ) # The admin should not be in this group # Put the admin into the staff group, becaust in the admin group, he has all permissions for # every single comment section. self.admin.groups.add(GROUP_STAFF_PK) self.admin.groups.remove(GROUP_ADMIN_PK) inform_changed_data(self.admin) self.group_in = get_group_model().objects.get(pk=GROUP_STAFF_PK) self.motion = Motion( title="test_title_SlqfMw(waso0saWMPqcZ", text="test_text_f30skclqS9wWF=xdfaSL", ) self.motion.save() self.section_no_groups = MotionCommentSection( name='test_name_gj4F§(fj"(edm"§F3f3fs' ) self.section_no_groups.save() self.section_read = MotionCommentSection(name="test_name_2wv30(d2S&kvelkakl39") self.section_read.save() self.section_read.read_groups.add( self.group_in, self.group_out ) # Group out for testing multiple groups self.section_read.write_groups.add(self.group_out) self.section_read_write = MotionCommentSection( name="test_name_a3m9sd0(Mw2%slkrv30," ) self.section_read_write.save() self.section_read_write.read_groups.add(self.group_in) self.section_read_write.write_groups.add(self.group_in) def test_retrieve_comment(self): comment = MotionComment( motion=self.motion, section=self.section_read_write, comment="test_comment_gwic37Csc&3lf3eo2", ) comment.save() response = self.client.get(reverse("motion-detail", args=[self.motion.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue("comments" in response.data) comments = response.data["comments"] self.assertTrue(isinstance(comments, list)) self.assertEqual(len(comments), 1) self.assertEqual(comments[0]["comment"], "test_comment_gwic37Csc&3lf3eo2") def test_retrieve_comment_no_read_permission(self): comment = MotionComment( motion=self.motion, section=self.section_no_groups, comment="test_comment_fgkj3C7veo3ijWE(j2DJ", ) comment.save() response = self.client.get(reverse("motion-detail", args=[self.motion.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue("comments" in response.data) comments = response.data["comments"] self.assertTrue(isinstance(comments, list)) self.assertEqual(len(comments), 0) def test_wrong_data_type(self): response = self.client.post( reverse("motion-manage-comments", args=[self.motion.pk]), None ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data["detail"], "You have to provide a section_id of type int." ) def test_wrong_comment_data_type(self): response = self.client.post( reverse("motion-manage-comments", args=[self.motion.pk]), { "section_id": self.section_read_write.id, "comment": [32, "no_correct_data"], }, ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data["detail"], "The comment should be a string.") def test_non_existing_section(self): response = self.client.post( reverse("motion-manage-comments", args=[self.motion.pk]), {"section_id": 42} ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data["detail"], "A comment section with id {0} does not exist." ) self.assertEqual(response.data["args"][0], "42") def test_create_comment(self): response = self.client.post( reverse("motion-manage-comments", args=[self.motion.pk]), { "section_id": self.section_read_write.pk, "comment": "test_comment_fk3jrnfwsdg%fj=feijf", }, ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MotionComment.objects.count(), 1) comment = MotionComment.objects.get() self.assertEqual(comment.comment, "test_comment_fk3jrnfwsdg%fj=feijf") def test_update_comment(self): comment = MotionComment( motion=self.motion, section=self.section_read_write, comment="test_comment_fji387fqwdf&ff=)Fe3j", ) comment.save() response = self.client.post( reverse("motion-manage-comments", args=[self.motion.pk]), { "section_id": self.section_read_write.pk, "comment": "test_comment_fk3jrnfwsdg%fj=feijf", }, ) self.assertEqual(response.status_code, status.HTTP_200_OK) comment = MotionComment.objects.get() self.assertEqual(comment.comment, "test_comment_fk3jrnfwsdg%fj=feijf") def test_delete_comment(self): comment = MotionComment( motion=self.motion, section=self.section_read_write, comment='test_comment_5CJ"8f23jd3j2,r93keZ', ) comment.save() response = self.client.delete( reverse("motion-manage-comments", args=[self.motion.pk]), {"section_id": self.section_read_write.pk}, ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MotionComment.objects.count(), 0) def test_delete_not_existing_comment(self): """ This should fail silently; no error, if the user wants to delete a not existing comment. """ response = self.client.delete( reverse("motion-manage-comments", args=[self.motion.pk]), {"section_id": self.section_read_write.pk}, ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MotionComment.objects.count(), 0) def test_create_comment_no_write_permission(self): response = self.client.post( reverse("motion-manage-comments", args=[self.motion.pk]), { "section_id": self.section_read.pk, "comment": "test_comment_f38jfwqfj830fj4j(FU3", }, ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(MotionComment.objects.count(), 0) self.assertEqual( response.data["detail"], "You are not allowed to see or write to the comment section.", ) def test_update_comment_no_write_permission(self): comment = MotionComment( motion=self.motion, section=self.section_read, comment="test_comment_jg38dwiej2D832(D§dk)", ) comment.save() response = self.client.post( reverse("motion-manage-comments", args=[self.motion.pk]), { "section_id": self.section_read.pk, "comment": "test_comment_fk3jrnfwsdg%fj=feijf", }, ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) comment = MotionComment.objects.get() self.assertEqual(comment.comment, "test_comment_jg38dwiej2D832(D§dk)") def test_delete_comment_no_write_permission(self): comment = MotionComment( motion=self.motion, section=self.section_read, comment="test_comment_fej(NF§kfePOF383o8DN", ) comment.save() response = self.client.delete( reverse("motion-manage-comments", args=[self.motion.pk]), {"section_id": self.section_read.pk}, ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(MotionComment.objects.count(), 1) comment = MotionComment.objects.get() self.assertEqual(comment.comment, "test_comment_fej(NF§kfePOF383o8DN") class TestMotionCommentSection(TestCase): """ Tests creating, updating and deletion of comment sections. """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") self.admin = get_user_model().objects.get() self.admin.groups.add( GROUP_STAFF_PK ) # Put the admin in a groiup with limited permissions for testing. self.admin.groups.remove(GROUP_ADMIN_PK) inform_changed_data(self.admin) self.group_in = get_group_model().objects.get(pk=GROUP_STAFF_PK) self.group_out = get_group_model().objects.get( pk=GROUP_DELEGATE_PK ) # The admin should not be in this group def test_retrieve(self): """ Checks, if the sections can be seen by a manager. """ section = MotionCommentSection(name="test_name_f3jOF3m8fp.New test

", "type": "0", }, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) def test_collission(self): """ Two change recommendations with overlapping lines should lead to a Bad Request """ response = self.client.post( reverse("motionchangerecommendation-list"), { "line_from": "5", "line_to": "7", "motion_id": "1", "text": "

New test

", "type": "0", }, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) response = self.client.post( reverse("motionchangerecommendation-list"), { "line_from": "3", "line_to": "6", "motion_id": "1", "text": "

New test

", "type": "0", }, ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data["args"][0], "3") self.assertEqual(response.data["args"][1], "6") def test_no_collission_different_motions(self): """ Two change recommendations with overlapping lines, but affecting different motions, should not interfere """ self.client.post( reverse("motion-list"), { "title": "test_title_OoCoo3MeiT9li5Iengu9", "text": "test_text_thuoz0iecheiheereiCi", }, ) response = self.client.post( reverse("motionchangerecommendation-list"), { "line_from": "5", "line_to": "7", "motion_id": "1", "text": "

New test

", "type": "0", }, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) response = self.client.post( reverse("motionchangerecommendation-list"), { "line_from": "3", "line_to": "6", "motion_id": "2", "text": "

New test

", "type": "0", }, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) class NumberMotionsInCategories(TestCase): """ Tests numbering motions in categories. Default test environment: - *without* blanks - 1 min digit Testdata. All names (and prefixes) are prefixed with "test_". The ordering is ensured with "category_weight". Category tree (with motions M and amendments A): A-A B C-C """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") self.A = Category.objects.create(name="test_A", prefix="test_A") self.B = Category.objects.create(name="test_B", parent=self.A) self.C = Category.objects.create(name="test_C", prefix="test_C", parent=self.A) self.M1 = Motion( title="test_title_Eeha8Haf6peulu8ooc0z", text="test_text_faghaZoov9ooV4Acaquk", category=self.A, category_weight=1, ) self.M1.save() self.M1.identifier = "" self.M1.save() self.M2 = Motion( title="test_title_kuheih2eja2Saeshusha", text="test_text_Ha5ShaeraeSuthooP2Bu", category=self.C, category_weight=1, ) self.M2.save() self.M2.identifier = "" self.M2.save() self.M2_A1 = Motion( title="test_title_av3ejIJvwon3jvnNVaie", text="test_text_FJPiejfwdcoiwjvijao1", category=self.B, category_weight=1, parent=self.M2, ) self.M2_A1.save() self.M2_A1.identifier = "" self.M2_A1.save() self.M2_A1_A1 = Motion( title="test_title_ejvhwoxngixoqkxy.qfi", text="test_text_euh2gfaiaqfu3.f(3hgf", category=self.C, category_weight=2, parent=self.M2_A1, ) self.M2_A1_A1.save() self.M2_A1_A1.identifier = "" self.M2_A1_A1.save() self.M2_A2 = Motion( title="test_title_xoerFiwebbpiUEeuvxMa", text="test_text_zbwZWPefiisdISfwLKqN", category=self.A, category_weight=2, parent=self.M2, ) self.M2_A2.save() self.M2_A2.identifier = "" self.M2_A2.save() self.M3 = Motion( title="test_title_VWIVeiNVenudn(23J92§", text="test_text_VEDno328hn8/TBbScVEb", category=self.B, category_weight=2, ) self.M3.save() self.M3.identifier = "" self.M3.save() def test_numbering(self): response = self.client.post(reverse("category-numbering", args=[self.A.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(Motion.objects.get(pk=self.M1.pk).identifier, "test_A1") self.assertEqual(Motion.objects.get(pk=self.M3.pk).identifier, "test_A2") self.assertEqual(Motion.objects.get(pk=self.M2.pk).identifier, "test_C3") self.assertEqual(Motion.objects.get(pk=self.M2_A1.pk).identifier, "test_C3-2") self.assertEqual( Motion.objects.get(pk=self.M2_A1_A1.pk).identifier, "test_C3-2-1" ) self.assertEqual(Motion.objects.get(pk=self.M2_A2.pk).identifier, "test_C3-1") def test_with_blanks_and_leading_zeros(self): config["motions_amendments_prefix"] = "-X" config["motions_identifier_with_blank"] = True config["motions_identifier_min_digits"] = 3 response = self.client.post(reverse("category-numbering", args=[self.A.pk])) config["motions_identifier_with_blank"] = False config["motions_identifier_min_digits"] = 1 self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(Motion.objects.get(pk=self.M1.pk).identifier, "test_A 001") self.assertEqual(Motion.objects.get(pk=self.M3.pk).identifier, "test_A 002") self.assertEqual(Motion.objects.get(pk=self.M2.pk).identifier, "test_C 003") self.assertEqual( Motion.objects.get(pk=self.M2_A1.pk).identifier, "test_C 003 -X 002" ) self.assertEqual( Motion.objects.get(pk=self.M2_A1_A1.pk).identifier, "test_C 003 -X 002 -X 001", ) self.assertEqual( Motion.objects.get(pk=self.M2_A2.pk).identifier, "test_C 003 -X 001" ) def test_existing_identifier_no_category(self): # config["motions_identifier_with_blank"] = True conflicting_motion = Motion( title="test_title_al2=2k21fjv1lsck3ehlWExg", text="test_text_3omvpEhnfg082ejplk1m", ) conflicting_motion.save() conflicting_motion.identifier = "test_C3-2-1" conflicting_motion.save() response = self.client.post(reverse("category-numbering", args=[self.A.pk])) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual("test_C3-2-1", response.data["args"][0]) def test_existing_identifier_with_category(self): conflicting_category = Category.objects.create( name="test_name_hpsodhakvjdbvkblwfjr" ) conflicting_motion = Motion( title="test_title_al2=2k21fjv1lsck3ehlWExg", text="test_text_3omvpEhnfg082ejplk1m", category=conflicting_category, ) conflicting_motion.save() conflicting_motion.identifier = "test_C3-2-1" conflicting_motion.save() response = self.client.post(reverse("category-numbering", args=[self.A.pk])) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual("test_C3-2-1", response.data["args"][0]) self.assertEqual(conflicting_category.name, response.data["args"][1]) def test_incomplete_amendment_tree(self): self.M2_A1.category = None self.M2_A1.save() response = self.client.post(reverse("category-numbering", args=[self.A.pk])) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(self.M2_A1_A1.title, response.data["args"][0]) self.assertEqual(self.M2_A1.title, response.data["args"][1]) class TestMotionBlock(TestCase): def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") def make_admin_delegate(self): admin = get_user_model().objects.get(username="admin") admin.groups.add(GROUP_DELEGATE_PK) admin.groups.remove(GROUP_ADMIN_PK) inform_changed_data(admin) def test_creation(self): response = self.client.post( reverse("motionblock-list"), {"title": "test_title_r23098OMFwoqof3if3kO"} ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertTrue(MotionBlock.objects.exists()) self.assertEqual( MotionBlock.objects.get().title, "test_title_r23098OMFwoqof3if3kO" ) def test_creation_no_data(self): response = self.client.post(reverse("motionblock-list"), {}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertFalse(MotionBlock.objects.exists()) def test_creation_not_authenticated(self): self.make_admin_delegate() response = self.client.post( reverse("motionblock-list"), {"title": "test_title_2PFjpf39ap,38fuMPO§8"} ) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertFalse(MotionBlock.objects.exists()) def test_retrieve_simple(self): motion_block = MotionBlock(title="test_title") motion_block.save() response = self.client.get( reverse("motionblock-detail", args=[motion_block.pk]) ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(response.data.keys()), sorted( ("agenda_item_id", "id", "internal", "list_of_speakers_id", "title") ), ) def test_retrieve_internal_non_admin(self): self.make_admin_delegate() motion_block = MotionBlock(title="test_title", internal=True) motion_block.save() response = self.client.get( reverse("motionblock-detail", args=[motion_block.pk]) ) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) class FollowRecommendationsForMotionBlock(TestCase): """ Tests following the recommendations of motions in an motion block. """ def setUp(self): self.state_id_accepted = 2 # This should be the id of the state 'accepted'. self.state_id_rejected = 3 # This should be the id of the state 'rejected'. self.client = APIClient() self.client.login(username="admin", password="admin") self.motion_block = MotionBlock.objects.create( title="test_motion_block_name_Ufoopiub7quaezaepeic" ) self.motion = Motion( title="test_title_yo8ohy5eifeiyied2AeD", text="test_text_chi1aeth5faPhueQu8oh", motion_block=self.motion_block, ) self.motion.save() self.motion.set_recommendation(self.state_id_accepted) self.motion.save() self.motion_2 = Motion( title="test_title_eith0EemaW8ahZa9Piej", text="test_text_haeho1ohk3ou7pau2Jee", motion_block=self.motion_block, ) self.motion_2.save() self.motion_2.set_recommendation(self.state_id_rejected) self.motion_2.save() def test_follow_recommendations_for_motion_block(self): response = self.client.post( reverse("motionblock-follow-recommendations", args=[self.motion_block.pk]) ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( Motion.objects.get(pk=self.motion.pk).state.id, self.state_id_accepted ) self.assertEqual( Motion.objects.get(pk=self.motion_2.pk).state.id, self.state_id_rejected ) class CreateWorkflow(TestCase): """ Tests the creating of workflows. """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") def test_creation(self): Workflow.objects.all().delete() response = self.client.post( reverse("workflow-list"), {"name": "test_name_OoCoo3MeiT9li5Iengu9"} ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) workflow = Workflow.objects.get() self.assertEqual(workflow.name, "test_name_OoCoo3MeiT9li5Iengu9") first_state = workflow.first_state self.assertEqual(type(first_state), State) class UpdateWorkflow(TestCase): """ Tests the updating of workflows. """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") self.workflow = Workflow.objects.first() def test_rename_workflow(self): response = self.client.patch( reverse("workflow-detail", args=[self.workflow.pk]), {"name": 'test_name_wofi38DiWLT"8d3lwfo3'}, ) workflow = Workflow.objects.get(pk=self.workflow.id) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(workflow.name, 'test_name_wofi38DiWLT"8d3lwfo3') class DeleteWorkflow(TestCase): """ Tests the deletion of workflows. """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") self.workflow = Workflow.objects.first() def test_simple_delete(self): response = self.client.delete( reverse("workflow-detail", args=[self.workflow.pk]) ) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(Workflow.objects.count(), 1) # Just the other default one def test_delete_with_assigned_motions(self): self.motion = Motion( title="test_title_chee7ahCha6bingaew4e", text="test_text_birah1theL9ooseeFaip", ) self.motion.reset_state(self.workflow) self.motion.save() response = self.client.delete( reverse("workflow-detail", args=[self.workflow.pk]) ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(Workflow.objects.count(), 2) def test_delete_last_workflow(self): self.workflow.delete() other_workflow_pk = Workflow.objects.get().pk response = self.client.delete( reverse("workflow-detail", args=[other_workflow_pk]) ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(Workflow.objects.count(), 1) # Just the other default one class DeleteCategory(TestCase): """ Tests the deletion of categories. """ def setUp(self): self.client = APIClient() self.client.login(username="admin", password="admin") self.category = Category.objects.create( name="test_name_dacei2iiTh", prefix="test_prefix_lahngoaW9L" ) def test_simple_delete_category_with_two_motions(self): self.motion1 = Motion.objects.create( title="test_title_fieB5ko4ahGeex5ohsh7", text="test_text_EFoh6Ahtho9eihei1xua", category=self.category, ) self.motion2 = Motion.objects.create( title="test_title_ahboo8eerohchuoD7sut", text="test_text_pahghah9iuM9moo8Ohve", category=self.category, ) response = self.client.delete( reverse("category-detail", args=[self.category.pk]) ) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertFalse(Category.objects.exists())