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
zcmXZgd0f{;9>?+F$04Yo5hw^Mo`497XPT=-T5OsNO6sNy8IWm;iJEs`JZn7zN<1SK
z*OW?KjA+ZP$GRPAt)(kvv?k_iR@+1Ks)ri;dOP!nJZI)R-<i*RX66eIZ(Z`0UiR(F
z4)eMiV-DpQ<B#8C5dMTs@EQi-ZES|VTw_8o44Y#V-iKXqJWj%HcnBZIpD+%y9y4YP
z7U9!)7#HEdiN-S>Db!A+6V{^wO6Khp%*Hre>a4^_>K|Yl)?*aL<{8r(`(kH&82exm
z4#HiSi06=)Ojy2MaACe@Ot3oApp`AaKwOSKT!rzt7TaNsdwvrAsn?@2^$iB#1=Kh{
zy83n0^PAWM{R@n_3wxvH9p+I8r7#kk;sk7glTa(2g8{e(!>|-Jz%~rWYSjB5q6Yjo
zYODU^+ApF4xPc0|5fz~S6UOvMFO<Rn3d69I8ZZubU_bmP>cyMb78|hxww+}6d<ZJl
zn^AlJ8Ft5;I13Y=G^Q19MQz0a)bq>80zA`hvRz54b12?Thq0)YKIPgMx%L;Fm9D)O
zm9eAFdTdGk2UNyxp)%EMirvz77)ZSXMlrvMr=S(4VG|tc>LZ+)u00!d>L;KEoa~-2
zM4gplRO**v60UQ;gIe(g?2Qpm*^Fmk3iF#K6g0qoOvD42fTuA7n@r_=U?wV+6{u5R
zgKhAbtAFqGpJq%n?Xehx{je#HLT&M%P=|3bdg`#BLNojn)$tUD;yL8%o1Zb=k1JZp
z!J_`+bgmQ@ahb1Tn;GmowkWcJp1~UGJ!Uc)p2x8`lml@Px1i3@qqE6>8ij?k?Oq?m
z!_<$VGO+O(dlvqIItz6ejNhRGyzFemR@6i17_$L8V+0;Vy>}e7W#>@u-9Tj^a4z{*
z3j5Brr#lms+Co(ObI$Fq{UGWV)S*^z6*Y0IdG-U8j5>V7Q16dHJ)eOJ=y}w&-iocU
z+M|#};VAaQ8>rKqGT%l#7<K=%uq%#1o!&)w0GFZ$x@UoXFB28OV|Zs`459u!Mqw#x
zi>pw#%&VcGlpMj%_$BHP-bQUf{6gEFi5h4&Dy5#QmpC`00^Et3_!HDteT!Z2M^vEU
zi|j4xhOxT;{V6DbY}EC895vAt)JkTdCR~oqu^hF6N>nEHVl=*q>VFIw*qp&OcpJ6y
zsAui>AQfY%r(sjw{|OWn*(9fjny?&|iQU)^PoM_+85L+V-VMULQGvBV1rm>%_&(Hk
zWdiE(J%-B6OjKr8O8%KLe&}9qLGAtfn2Dd^oiA0feK8*O;$YN7526B}h#GhvYENH4
z^{d2ed>!@Nx7a?9Mjggv^b}b-1>OHgP$`^<T0s$Npf%3*sI93$t#~);%+#O)tw$}O
z0mtEG)cX%Dv4M_8o&Kj#fi7M`{x#rBG-yvNunX?NKtD2ony7B6ec@Zw*4%K0EVBc~
zpx#eKt#lA}#L=jQJcG(u2`Xb%sQ!nRkzxh#FZbX}Or(AZQ?bo*yLTgS67^hE|Bp}u
ze2z-x*LdfH<m!#ih!r-VMAXD-sFja%PW33XrJ)$L6)&S!u;0}`My0eKm5CovTlEVn
zfPm-hX>Nf7s3)OTT!30}F+Pf$P+NNqHBZp<b|GH0D|EspJV-|EQC|$i;i!qTP`^%d
zP%E8=8gK#na5d`vb?A@f*dI5e`kg?%e-0JE6(rN13Hq~*q$l>{!9Wbc8K{ZoqE@;B
z6;KHVU^x!NEjSv#z~Pv*(grdI)$XBwd!E27?6}JQp)w0sGry^zkj{hdtNF;_bgac|
zn1pYvv3~=8g{u43+LfeWF!kS|R`>wwER4l2I2E<ErKs=5KGfD8##}suA<S>m*4YOS
zp$^AH)G43sd=BHNZ*=v)x%wxlO#Kg)k*m&MQ4{@!N_FH5)&x}ldr|YGqo+L^Lm>=v
zoYSx+^@XUtT!UI^iEH14T4@z(OWsHI`w*Mr5p0GhQR6qD#=nR<OTVB33@jo4YKSed
zr#un6Q6GRQn2$PKWvIy4qgJ{VmD24v72iR2%OsSNZhVs;3OJ+8t~?9%&Ckc)Sd0qz
zfIhv7td<6?=p$@_U!&T8#Jlh&YGt7>+Cv$IdfwI5`=ajm{istv9+iPIRKOJ&ft9Fh
z`8JNk6P|16_>w(@gOCrO@vtQ>Mom<TO4&Bdz*^Ma`mMJ{pblF+s{b(5Lb6d?kdIpN
zR1CqVQ2~1MDJbF<*d70l$@l}NV05|tQz-*esn5mnxCbA=pbf_K!iP~SDn<o<3>DxR
zOv5XviTi9crY8=@A<S>4Q_w(rQG0gX*@*g*1#hw`?1b8i1k^wSokLNn9f_Ja4>NHV
zYK0%5GVnR7-zijJKVfU#f4|N4_j@#If_qS@dkB@vM^Sq?8FdH?F%f5@z8e+DA2;SK
zZoyoBEX7-xg~eO#nK_P;)X$&-xQ_Z8!i2nRCyqo#9FLl~w=*5vQ_sS#I0H4n2G?GN
zpHe@H%HYNdd%w3kYp@mVM^NK7pcZ-wJr#Vf*vKMK^=_z+gHWj(jynCLQ4{1~EKWjw
z>6T$A?m-1si(2VX)OZc3g<U}%!bXfj|83-7k;QJad(#^=PzI{Q7}S8%QQv_jsDPHE
z&cGVfmXxCcdKoq0JE-?R#Wr{zbvFFA+glQj3b5yP&%XEo4ee;iL#22Lrr~ak#_v&q
z1?;ddhNC7*Kn*+)({VUzL2EG;ccRYH7uXLkU>dfov<u7iDD<MC2sOb@REn!nU&eP)
z10F^Ncm_LRqpNq?X}@ggs0`$w`Ymv7LIwCX>hvE$jsFcQv)*?UG|^3Li@|@f19nBF
zC>^zeajyMI%%;8!_1-DxdDH|~Py+|=vKfj&?R_$8oB<ezzsF?V|0xuFG;F{oxY@Y_
z1E^P_UfhS;^Y>AQ^9cR{PvKlleAQ-hJ1(Mr61(E)-E1q)#}#-QH(<dYU1RqDHwx2e
zNT}i;uE%@vJ&ePfn1r#f*{#SxO`MDEaW6K*W2pD*@j(oD-Ix(L0*B&8oQkJW3m*Ok
zw~G1AND5lnA5jD4p+8Q?J~$IK(W|I_AEO31j=^{m)&Dex;aO~gmr?zH#op+@*KSdN
z)I1~b&ix<f8m3?j51v6CqEZaP{is7!i_P&cYLDwM6fdH_4>#O%-#**F1uBp@RKN+S
zfRnH<_Sr}N@1Zb-23?mO7>6fuAYMnkn7ZG#_d%WhM{okpL#4b9wPlT{J-_#_#ypFU
zqcYNfg?I^5F}K>Dt&(c;uS2%pHEedif=cO5SKp0_{0-EK-a=*OJ@@=W=TQu#{WH}2
zb*TPdx%ydDrp}{o%Vp0!2s&UpHbn&#jvAn~YmY%q*a;)B8|wKGRR8-?E6u=U9E&Nq
z9DCvc9Dx7D!Px#y+wSF1&_L@@56Vz49>-DWS7ZP0CL8rhea-m+Mp8eGad;IwVB}kN
zi~2jqqYj&gU2qll!2QUf?r0h)D007A+p#689*a+4QuX1^hkU+|{i@f-j||{6l$}l*
z<qPwb_3FOTFRJ=r_o!YG6ASa>Mit~uFUl{-k1HyeSum?0zxu13#Tl*QA1rvf=+L`Q
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 ""