From 89efc33d75febed612755dd1c023d56d8e23993f Mon Sep 17 00:00:00 2001 From: mpeltriaux <michel.peltriaux@sgdnord.rlp.de> Date: Fri, 8 Sep 2023 12:47:50 +0200 Subject: [PATCH] # Unit test konova app * adds unit test for konova app models * drops unused/unnecessary code fragments * updates translation --- compensation/models/compensation.py | 7 +- .../views/compensation/compensation.py | 13 +- intervention/models/intervention.py | 10 +- intervention/views/intervention.py | 9 +- konova/forms/remove_form.py | 6 + konova/models/object.py | 31 +-- konova/tests/test_views.py | 7 +- konova/tests/unit/test_models.py | 182 ++++++++++++++++++ konova/utils/message_templates.py | 2 +- locale/de/LC_MESSAGES/django.mo | Bin 47250 -> 47228 bytes locale/de/LC_MESSAGES/django.po | 73 ++++--- 11 files changed, 255 insertions(+), 85 deletions(-) create mode 100644 konova/tests/unit/test_models.py diff --git a/compensation/models/compensation.py b/compensation/models/compensation.py index d09599d9..a32926c9 100644 --- a/compensation/models/compensation.py +++ b/compensation/models/compensation.py @@ -421,19 +421,18 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin, PikMixin): ) return docs - def mark_as_edited(self, user: User, request: HttpRequest = None, edit_comment: str = None, reset_recorded: bool = True): - """ Performs internal logic for setting the recordedd/checked state of the related intervention + def mark_as_edited(self, user: User, request: HttpRequest = None, edit_comment: str = None): + """ Performs internal logic for setting the checked state of the related intervention Args: user (User): The performing user request (HttpRequest): The performing request edit_comment (str): Additional comment for the log entry - reset_recorded (bool): Whether the record-state of the object should be reset Returns: """ - self.intervention.unrecord(user, request) + self.intervention.set_unchecked() action = super().mark_as_edited(user, edit_comment=edit_comment) return action diff --git a/compensation/views/compensation/compensation.py b/compensation/views/compensation/compensation.py index 0a198bb1..1b4691c7 100644 --- a/compensation/views/compensation/compensation.py +++ b/compensation/views/compensation/compensation.py @@ -25,7 +25,7 @@ from konova.forms.modals import RemoveModalForm from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE, \ - RECORDED_BLOCKS_EDIT, CHECKED_RECORDED_RESET, FORM_INVALID, PARAMS_INVALID, IDENTIFIER_REPLACED, \ + RECORDED_BLOCKS_EDIT, CHECK_STATE_RESET, FORM_INVALID, PARAMS_INVALID, IDENTIFIER_REPLACED, \ COMPENSATION_ADDED_TEMPLATE, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED from konova.utils.user_checks import in_group @@ -170,15 +170,14 @@ def edit_view(request: HttpRequest, id: str): geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=comp) if request.method == "POST": if data_form.is_valid() and geom_form.is_valid(): - # Preserve state of intervention recorded/checked to determine whether the user must be informed or not - # about a change of the recorded/checked state - intervention_recorded = comp.intervention.recorded is not None - intervention_checked = comp.intervention.checked is not None + # Preserve state of intervention checked to determine whether the user must be informed or not + # about a change of the check state + intervention_is_checked = comp.intervention.checked is not None # The data form takes the geom form for processing, as well as the performing user comp = data_form.save(request.user, geom_form) - if intervention_recorded or intervention_checked: - messages.info(request, CHECKED_RECORDED_RESET) + if intervention_is_checked: + messages.info(request, CHECK_STATE_RESET) messages.success(request, _("Compensation {} edited").format(comp.identifier)) if geom_form.geometry_simplified: messages.info( diff --git a/intervention/models/intervention.py b/intervention/models/intervention.py index b54fa8f5..d54a1b9d 100644 --- a/intervention/models/intervention.py +++ b/intervention/models/intervention.py @@ -279,22 +279,20 @@ class Intervention(BaseObject, revocation.delete() self.mark_as_edited(user, request=form.request, edit_comment=REVOCATION_REMOVED) - def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None, reset_recorded: bool = True): - """ In case the object or a related object changed, internal processes need to be started, such as - unrecord and uncheck + def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None): + """ Log the edit action + + If the object is checked, set it to unchecked due to the editing. Another check is needed then. Args: performing_user (User): The user which performed the editing action request (HttpRequest): The used request for this action edit_comment (str): Additional comment for the log entry - reset_recorded (bool): Whether the record-state of the object should be reset Returns: """ action = super().mark_as_edited(performing_user, edit_comment=edit_comment) - if reset_recorded: - self.unrecord(performing_user, request) if self.checked: self.set_unchecked() return action diff --git a/intervention/views/intervention.py b/intervention/views/intervention.py index a69ba4a0..681fc3b6 100644 --- a/intervention/views/intervention.py +++ b/intervention/views/intervention.py @@ -22,7 +22,7 @@ from konova.forms.modals import RemoveModalForm from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.message_templates import DATA_CHECKED_PREVIOUSLY_TEMPLATE, RECORDED_BLOCKS_EDIT, \ - CHECKED_RECORDED_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED + CHECK_STATE_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED from konova.utils.user_checks import in_group @@ -230,12 +230,11 @@ def edit_view(request: HttpRequest, id: str): if data_form.is_valid() and geom_form.is_valid(): # The data form takes the geom form for processing, as well as the performing user # Save the current state of recorded|checked to inform the user in case of a status reset due to editing - i_rec = intervention.recorded is not None - i_check = intervention.checked is not None + intervention_is_checked = intervention.checked is not None intervention = data_form.save(request.user, geom_form) messages.success(request, _("Intervention {} edited").format(intervention.identifier)) - if i_check or i_rec: - messages.info(request, CHECKED_RECORDED_RESET) + if intervention_is_checked: + messages.info(request, CHECK_STATE_RESET) if geom_form.geometry_simplified: messages.info( request, diff --git a/konova/forms/remove_form.py b/konova/forms/remove_form.py index d5c884a6..5d08ca22 100644 --- a/konova/forms/remove_form.py +++ b/konova/forms/remove_form.py @@ -14,6 +14,12 @@ from user.models import UserActionLogEntry, User class RemoveForm(BaseForm): + """ DEPRECATED + + NOT USED IN ANY PLACE. + CAN BE DELETED AT SOME POINT. + + """ check = forms.BooleanField( label=_("Confirm"), label_suffix=_(""), diff --git a/konova/models/object.py b/konova/models/object.py index 1fe0cebb..51817cb5 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -23,13 +23,9 @@ from django.core.exceptions import ObjectDoesNotExist from django.http import HttpRequest from django.utils.timezone import now from django.db import models, transaction -from compensation.settings import COMPENSATION_IDENTIFIER_TEMPLATE, COMPENSATION_IDENTIFIER_LENGTH, \ - ECO_ACCOUNT_IDENTIFIER_TEMPLATE, ECO_ACCOUNT_IDENTIFIER_LENGTH -from ema.settings import EMA_IDENTIFIER_LENGTH, EMA_IDENTIFIER_TEMPLATE -from intervention.settings import INTERVENTION_IDENTIFIER_LENGTH, INTERVENTION_IDENTIFIER_TEMPLATE from konova.utils import generators from konova.utils.generators import generate_random_string -from konova.utils.message_templates import CHECKED_RECORDED_RESET, GEOMETRY_CONFLICT_WITH_TEMPLATE +from konova.utils.message_templates import GEOMETRY_CONFLICT_WITH_TEMPLATE class UuidModel(models.Model): @@ -298,27 +294,6 @@ class RecordableObjectMixin(models.Model): return action - def unrecord(self, performing_user, request: HttpRequest = None): - """ Unrecords a dataset - - Args: - performing_user (User): The user which performed the editing action - request (HttpRequest): The used request for this action - - Returns: - - """ - action = None - if self.recorded: - action = self.set_unrecorded(performing_user) - self.log.add(action) - if request: - messages.info( - request, - CHECKED_RECORDED_RESET - ) - return action - @abstractmethod def is_ready_for_publish(self) -> bool: """ Check for all needed publishing-constraints on the data @@ -353,7 +328,7 @@ class CheckableObjectMixin(models.Model): abstract = True def set_unchecked(self) -> None: - """ Perform unrecording + """ Perform unchecking Args: @@ -363,7 +338,7 @@ class CheckableObjectMixin(models.Model): if not self.checked: # Nothing to do return - # Do not .delete() the checked attribute! Just set it to None, since a delete() would kill it out of the + # Do not .delete() the checked attribute! Just set it to None, since a delete() would remove it from the # log history, which is not what we want! self.checked = None self.save() diff --git a/konova/tests/test_views.py b/konova/tests/test_views.py index 81736c82..6eebfa1f 100644 --- a/konova/tests/test_views.py +++ b/konova/tests/test_views.py @@ -290,7 +290,7 @@ class BaseTestCase(TestCase): ]) return codes - def create_dummy_team(self): + def create_dummy_team(self, name: str = None): """ Creates a dummy team Returns: @@ -299,8 +299,11 @@ class BaseTestCase(TestCase): if self.superuser is None: self.create_users() + if not name: + name = "Testteam" + team = Team.objects.get_or_create( - name="Testteam", + name=name, description="Testdescription", )[0] team.users.add(self.superuser) diff --git a/konova/tests/unit/test_models.py b/konova/tests/unit/test_models.py new file mode 100644 index 00000000..8f0e881b --- /dev/null +++ b/konova/tests/unit/test_models.py @@ -0,0 +1,182 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 08.09.23 + +""" +from django.test import RequestFactory + +from intervention.forms.modals.share import ShareModalForm +from konova.models import DeadlineType +from konova.settings import ZB_GROUP +from konova.tests.test_views import BaseTestCase +from konova.utils.user_checks import is_default_group_only +from user.models import UserAction + + + +class DeadlineTestCase(BaseTestCase): + def setUp(self) -> None: + super().setUp() + + def test_str(self): + self.assertEqual(str(self.finished_deadline), self.finished_deadline.type) + + def test_type_humanized_property(self): + self.assertEqual(self.finished_deadline.type_humanized, DeadlineType.FINISHED.label) + + +class BaseObjectTestCase(BaseTestCase): + def test_add_log_entry(self): + self.assertEqual(self.intervention.log.count(), 0) + self.intervention.add_log_entry(UserAction.EDITED, self.user, "TEST") + self.assertEqual(self.intervention.log.count(), 1) + last_log = self.intervention.log.first() + self.assertEqual(last_log.user, self.user) + self.assertEqual(last_log.comment, "TEST") + self.assertEqual(last_log.action, UserAction.EDITED) + + def test_generate_new_identifier(self): + old_identifier = self.intervention.identifier + new_identifier = self.intervention.generate_new_identifier() + self.assertNotEqual(old_identifier, new_identifier) + + +class RecordableObjectMixinTestCase(BaseTestCase): + def test_set_recorded_and_set_unrecorded(self): + """ Tests set_unrecorded() as well + + Returns: + + """ + self.intervention.set_recorded(self.user) + self.assertIsNotNone(self.intervention.recorded) + self.assertEqual(self.intervention.recorded.user, self.user) + self.assertEqual(self.intervention.recorded.action, UserAction.RECORDED) + + self.intervention.set_unrecorded(self.user) + self.assertIsNone(self.intervention.recorded) + last_log = self.intervention.log.first() + self.assertEqual(last_log.action, UserAction.UNRECORDED) + self.assertEqual(last_log.user, self.user) + + +class CheckableObjectMixinTestCase(BaseTestCase): + def test_set_unchecked_and_set_checked(self): + self.intervention.set_checked(self.user) + self.assertIsNotNone(self.intervention.checked) + self.assertEqual(self.intervention.checked.action, UserAction.CHECKED) + self.assertEqual(self.intervention.checked.user, self.user) + checked_action = self.intervention.checked + + self.intervention.set_unchecked() + self.assertIsNone(self.intervention.checked) + + # There is no explicit UNCHECKED UserAction since unchecking does never happen manually but only as an + # automatic consequence of editing an already checked entry. Therefore the last log entry in this case would + # be the checking of the entry + last_log = self.intervention.log.first() + self.assertEqual(last_log.action, UserAction.CHECKED) + self.assertEqual(last_log.user, self.user) + self.assertEqual(last_log, checked_action) + + def test_get_last_checked_action(self): + self.intervention.set_checked(self.user) + action = self.intervention.checked + + self.intervention.mark_as_edited(self.user) + last_log = self.intervention.log.first() + self.assertNotEqual(last_log, action) + + last_check_action = self.intervention.get_last_checked_action() + self.assertEqual(action, last_check_action) + + +class ShareableObjectMixinTestCase(BaseTestCase): + def test_share_with_and_is_shared_with(self): + self.assertFalse(self.intervention.is_shared_with(self.user)) + self.assertNotIn(self.user, self.intervention.shared_users) + + self.intervention.share_with_user(self.user) + self.assertTrue(self.intervention.is_shared_with(self.user)) + self.assertIn(self.user, self.intervention.shared_users) + + self.assertTrue(self.intervention.is_only_shared_with(self.user)) + self.assertFalse(self.intervention.is_only_shared_with(self.superuser)) + self.assertNotIn(self.superuser, self.intervention.shared_users) + self.intervention.share_with_user(self.superuser) + self.assertFalse(self.intervention.is_only_shared_with(self.user)) + self.assertIn(self.superuser, self.intervention.shared_users) + + self.intervention.share_with_user_list([]) + self.assertNotIn(self.superuser, self.intervention.shared_users) + self.assertNotIn(self.user, self.intervention.shared_users) + self.intervention.share_with_user_list([ + self.superuser, + self.user + ]) + self.assertIn(self.superuser, self.intervention.shared_users) + self.assertIn(self.user, self.intervention.shared_users) + + def test_share_with_team_and_team_list(self): + self.assertNotIn(self.team, self.intervention.shared_teams) + self.intervention.share_with_team(self.team) + self.assertIn(self.team, self.intervention.shared_teams) + + another_team = self.create_dummy_team(name="Another team") + team_list = [ + self.team, + another_team + ] + self.assertNotIn(another_team, self.intervention.shared_teams) + self.intervention.share_with_team_list(team_list) + self.assertIn(another_team, self.intervention.shared_teams) + + def test_update_shared_access(self): + another_team = self.create_dummy_team(name="Another team") + request = RequestFactory().request() + request.user = self.superuser + self.superuser.groups.add( + self.groups.get(name=ZB_GROUP) + ) + + self.intervention.share_with_team(another_team) + self.intervention.share_with_user(self.user) + self.assertTrue(self.intervention.is_shared_with(self.user)) + self.assertIn(another_team, self.intervention.shared_teams) + + data = { + "users": [ + self.superuser.id, + ], + "teams": [ + self.team.id, + ] + } + form = ShareModalForm(data, request=request, instance=self.intervention) + self.assertTrue(form.is_valid(), msg=form.errors) + form.save() + self.assertNotIn(self.user, self.intervention.shared_users) + self.assertNotIn(another_team, self.intervention.shared_teams) + self.assertIn(self.superuser, self.intervention.shared_users) + self.assertIn(self.team, self.intervention.shared_teams) + + def test_unshare_with_default_users(self): + self.superuser.groups.add( + self.groups.get( + name=ZB_GROUP + ) + ) + self.intervention.share_with_user(self.user) + self.intervention.share_with_user(self.superuser) + + self.assertTrue(is_default_group_only(self.user)) + self.assertFalse(is_default_group_only(self.superuser)) + + self.assertTrue(self.intervention.is_shared_with(self.user)) + self.assertTrue(self.intervention.is_shared_with(self.superuser)) + + self.intervention.unshare_with_default_users() + self.assertFalse(self.intervention.is_shared_with(self.user)) + self.assertTrue(self.intervention.is_shared_with(self.superuser)) diff --git a/konova/utils/message_templates.py b/konova/utils/message_templates.py index 6dcaa335..b36e2a0a 100644 --- a/konova/utils/message_templates.py +++ b/konova/utils/message_templates.py @@ -18,7 +18,7 @@ INTERVENTION_INVALID = _("There are errors in this intervention.") IDENTIFIER_REPLACED = _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") ENTRY_REMOVE_MISSING_PERMISSION = _("Only conservation or registration office users are allowed to remove entries.") MISSING_GROUP_PERMISSION = _("You need to be part of another user group.") -CHECKED_RECORDED_RESET = _("Status of Checked and Recorded reseted") +CHECK_STATE_RESET = _("Status of Checked reset") RECORDED_BLOCKS_EDIT = _("Entry is recorded. To edit data, the entry first needs to be unrecorded.") # SHARE diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index e5844ea944eb086d7bc0c948b8ee5234484d0af7..cbfcbda46c4d13446b591eba2bfb1aa43bd5b008 100644 GIT binary patch delta 5870 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 delta 5892 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 Z%!=<3Kc=8)e!=9tCkqRzr|b&9>;F<CiiZFI diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index f243ba26..4eef6ffc 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -29,21 +29,21 @@ #: konova/filters/mixins/office.py:25 konova/filters/mixins/office.py:56 #: konova/filters/mixins/office.py:57 konova/filters/mixins/record.py:23 #: konova/filters/mixins/self_created.py:24 konova/filters/mixins/share.py:23 -#: konova/forms/geometry_form.py:33 konova/forms/modals/document_form.py:26 +#: konova/forms/geometry_form.py:32 konova/forms/modals/document_form.py:26 #: konova/forms/modals/document_form.py:36 #: konova/forms/modals/document_form.py:50 #: konova/forms/modals/document_form.py:62 #: konova/forms/modals/document_form.py:80 #: konova/forms/modals/remove_form.py:23 #: konova/forms/modals/resubmission_form.py:22 -#: konova/forms/modals/resubmission_form.py:38 konova/forms/remove_form.py:19 -#: user/forms/user.py:39 +#: konova/forms/modals/resubmission_form.py:38 konova/forms/remove_form.py:25 +#: konova/tests/unit/test_forms.py:59 user/forms/user.py:39 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-30 13:24+0200\n" +"POT-Creation-Date: 2023-09-08 11:30+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -401,6 +401,7 @@ msgid "An explanatory name" msgstr "Aussagekräftiger Titel" #: compensation/forms/compensation.py:49 ema/forms.py:51 ema/forms.py:114 +#: ema/tests/unit/test_forms.py:31 ema/tests/unit/test_forms.py:85 msgid "Compensation XY; Location ABC" msgstr "Kompensation XY; Flur ABC" @@ -490,8 +491,8 @@ msgid "" "{}m² have been deducted from this eco account so far. The given value of {} " "would be too low." msgstr "" -"{}n² wurden bereits von diesem Ökokonto abgebucht. Der eingegebene Wert von {} " -"wäre daher zu klein." +"{}n² wurden bereits von diesem Ökokonto abgebucht. Der eingegebene Wert von " +"{} wäre daher zu klein." #: compensation/forms/eco_account.py:249 msgid "The account can not be removed, since there are still deductions." @@ -935,6 +936,7 @@ msgstr "Öffentlicher Bericht" #: ema/templates/ema/detail/includes/controls.html:15 #: intervention/templates/intervention/detail/includes/controls.html:15 #: konova/forms/modals/resubmission_form.py:51 +#: konova/tests/unit/test_forms.py:302 konova/tests/unit/test_forms.py:316 #: templates/email/resubmission/resubmission.html:4 msgid "Resubmission" msgstr "Wiedervorlage" @@ -997,7 +999,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms/modals/document_form.py:79 +#: konova/forms/modals/document_form.py:79 konova/tests/unit/test_forms.py:58 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -1013,7 +1015,7 @@ msgstr "Erstellt" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:61 #: ema/templates/ema/detail/includes/documents.html:61 #: intervention/templates/intervention/detail/includes/documents.html:70 -#: konova/forms/modals/document_form.py:141 +#: konova/forms/modals/document_form.py:141 konova/tests/unit/test_forms.py:118 msgid "Edit document" msgstr "Dokument bearbeiten" @@ -1187,6 +1189,7 @@ msgstr "weitere Nutzer" #: ema/templates/ema/detail/includes/controls.html:18 #: intervention/forms/modals/share.py:63 #: intervention/templates/intervention/detail/includes/controls.html:18 +#: intervention/tests/unit/test_forms.py:150 msgid "Share" msgstr "Freigabe" @@ -1291,14 +1294,14 @@ msgstr "Daten zu den verantwortlichen Stellen" msgid "Compensations - Overview" msgstr "Kompensationen - Übersicht" -#: compensation/views/compensation/compensation.py:182 +#: compensation/views/compensation/compensation.py:181 #: konova/utils/message_templates.py:40 msgid "Compensation {} edited" msgstr "Kompensation {} bearbeitet" -#: compensation/views/compensation/compensation.py:197 -#: compensation/views/eco_account/eco_account.py:171 ema/views/ema.py:231 -#: intervention/views/intervention.py:253 +#: compensation/views/compensation/compensation.py:196 +#: compensation/views/eco_account/eco_account.py:173 ema/views/ema.py:231 +#: intervention/views/intervention.py:252 msgid "Edit {}" msgstr "Bearbeite {}" @@ -1316,19 +1319,19 @@ msgstr "Ökokonten - Übersicht" msgid "Eco-Account {} added" msgstr "Ökokonto {} hinzugefügt" -#: compensation/views/eco_account/eco_account.py:156 +#: compensation/views/eco_account/eco_account.py:158 msgid "Eco-Account {} edited" msgstr "Ökokonto {} bearbeitet" -#: compensation/views/eco_account/eco_account.py:285 +#: compensation/views/eco_account/eco_account.py:287 msgid "Eco-account removed" msgstr "Ökokonto entfernt" -#: ema/forms.py:42 ema/views/ema.py:102 +#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:102 msgid "New EMA" msgstr "Neue EMA hinzufügen" -#: ema/forms.py:108 +#: ema/forms.py:108 ema/tests/unit/test_forms.py:81 msgid "Edit EMA" msgstr "Bearbeite EMA" @@ -1427,7 +1430,7 @@ msgid "Binding on" msgstr "Datum Bestandskraft bzw. Rechtskraft" #: intervention/forms/intervention.py:216 -#: intervention/tests/unit/test_forms.py:27 +#: intervention/tests/unit/test_forms.py:36 #: intervention/views/intervention.py:105 msgid "New intervention" msgstr "Neuer Eingriff" @@ -1450,6 +1453,7 @@ msgid "Run check" msgstr "Prüfung vornehmen" #: intervention/forms/modals/check.py:36 konova/forms/modals/record_form.py:30 +#: konova/tests/unit/test_forms.py:155 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -1512,6 +1516,7 @@ msgstr "Muss kleiner als 15 Mb sein" #: intervention/forms/modals/revocation.py:62 #: intervention/templates/intervention/detail/includes/revocation.html:18 +#: intervention/tests/unit/test_forms.py:234 msgid "Add revocation" msgstr "Widerspruch hinzufügen" @@ -1553,6 +1558,7 @@ msgstr "" "noch nicht freigegeben wurde. Geben Sie den ganzen Nutzernamen an." #: intervention/forms/modals/share.py:64 +#: intervention/tests/unit/test_forms.py:151 msgid "Share settings for {}" msgstr "Freigabe Einstellungen für {}" @@ -1668,11 +1674,11 @@ msgstr "Eingriffe - Übersicht" msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views/intervention.py:236 +#: intervention/views/intervention.py:235 msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views/intervention.py:278 +#: intervention/views/intervention.py:277 msgid "{} removed" msgstr "{} entfernt" @@ -1790,12 +1796,12 @@ msgstr "Speichern" msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms/geometry_form.py:32 konova/utils/quality.py:44 +#: konova/forms/geometry_form.py:31 konova/utils/quality.py:44 #: konova/utils/quality.py:46 templates/form/collapsable/form.html:45 msgid "Geometry" msgstr "Geometrie" -#: konova/forms/geometry_form.py:101 +#: konova/forms/geometry_form.py:100 msgid "Only surfaces allowed. Points or lines must be buffered." msgstr "" "Nur Flächen erlaubt. Punkte oder Linien müssen zu Flächen gepuffert werden." @@ -1813,7 +1819,7 @@ msgstr "Datei" msgid "Allowed formats: pdf, jpg, png. Max size 15 MB." msgstr "Formate: pdf, jpg, png. Maximal 15 MB." -#: konova/forms/modals/document_form.py:116 +#: konova/forms/modals/document_form.py:116 konova/tests/unit/test_forms.py:95 msgid "Added document" msgstr "Dokument hinzugefügt" @@ -1821,32 +1827,34 @@ msgstr "Dokument hinzugefügt" msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms/modals/record_form.py:29 +#: konova/forms/modals/record_form.py:29 konova/tests/unit/test_forms.py:153 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms/modals/record_form.py:36 +#: konova/forms/modals/record_form.py:36 konova/tests/unit/test_forms.py:168 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms/modals/record_form.py:37 +#: konova/forms/modals/record_form.py:37 konova/tests/unit/test_forms.py:167 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms/modals/record_form.py:38 +#: konova/forms/modals/record_form.py:38 konova/tests/unit/test_forms.py:170 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." -#: konova/forms/modals/remove_form.py:22 konova/forms/remove_form.py:18 +#: konova/forms/modals/remove_form.py:22 konova/forms/remove_form.py:24 msgid "Confirm" msgstr "Bestätige" -#: konova/forms/modals/remove_form.py:32 konova/forms/remove_form.py:30 +#: konova/forms/modals/remove_form.py:32 konova/forms/remove_form.py:36 +#: konova/tests/unit/test_forms.py:209 konova/tests/unit/test_forms.py:261 msgid "Remove" msgstr "Löschen" -#: konova/forms/modals/remove_form.py:33 +#: konova/forms/modals/remove_form.py:33 konova/tests/unit/test_forms.py:210 +#: konova/tests/unit/test_forms.py:262 msgid "Are you sure?" msgstr "Sind Sie sicher?" @@ -1855,6 +1863,7 @@ msgid "When do you want to be reminded?" msgstr "Wann wollen Sie erinnert werden?" #: konova/forms/modals/resubmission_form.py:52 +#: konova/tests/unit/test_forms.py:303 konova/tests/unit/test_forms.py:317 msgid "Set your resubmission for this entry." msgstr "Setzen Sie eine Wiedervorlage für diesen Eintrag." @@ -1862,7 +1871,7 @@ msgstr "Setzen Sie eine Wiedervorlage für diesen Eintrag." msgid "The date should be in the future" msgstr "Das Datum sollte in der Zukunft liegen" -#: konova/forms/remove_form.py:32 +#: konova/forms/remove_form.py:38 msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" @@ -2077,8 +2086,8 @@ msgid "You need to be part of another user group." msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" #: konova/utils/message_templates.py:21 -msgid "Status of Checked and Recorded reseted" -msgstr "'Geprüft'/'Verzeichnet' wurde zurückgesetzt" +msgid "Status of Checked reset" +msgstr "Status 'Geprüft' wurde zurückgesetzt" #: konova/utils/message_templates.py:22 msgid ""