From 4dcd43bedb205fa5185c8c24cfec0b3c2944e004 Mon Sep 17 00:00:00 2001 From: Hironsan Date: Tue, 25 Jan 2022 15:50:10 +0900 Subject: [PATCH] Add TextLabelManager --- backend/api/managers.py | 10 ++++ backend/api/models.py | 6 +- backend/api/tests/test_text_label.py | 84 ++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 backend/api/tests/test_text_label.py diff --git a/backend/api/managers.py b/backend/api/managers.py index a500993a..eac6fd74 100644 --- a/backend/api/managers.py +++ b/backend/api/managers.py @@ -66,6 +66,16 @@ class SpanManager(AnnotationManager): return True +class TextLabelManager(AnnotationManager): + + def can_annotate(self, label, project) -> bool: + texts = self.get_labels(label, project) + for text in texts: + if text.is_same_text(label): + return False + return True + + class ExampleManager(Manager): def bulk_create(self, objs, batch_size=None, ignore_conflicts=False): diff --git a/backend/api/models.py b/backend/api/models.py index 247f31d4..2d075020 100644 --- a/backend/api/models.py +++ b/backend/api/models.py @@ -9,7 +9,7 @@ from django.db import models from polymorphic.models import PolymorphicModel from .managers import (AnnotationManager, CategoryManager, ExampleManager, - ExampleStateManager, SpanManager) + ExampleStateManager, SpanManager, TextLabelManager) DOCUMENT_CLASSIFICATION = 'DocumentClassification' SEQUENCE_LABELING = 'SequenceLabeling' @@ -400,6 +400,7 @@ class Span(Annotation): class TextLabel(Annotation): + objects = TextLabelManager() example = models.ForeignKey( to=Example, on_delete=models.CASCADE, @@ -407,6 +408,9 @@ class TextLabel(Annotation): ) text = models.TextField() + def is_same_text(self, other: 'TextLabel'): + return self.text == other.text + class Meta: unique_together = ( 'example', diff --git a/backend/api/tests/test_text_label.py b/backend/api/tests/test_text_label.py new file mode 100644 index 00000000..f8dcb74a --- /dev/null +++ b/backend/api/tests/test_text_label.py @@ -0,0 +1,84 @@ +import abc + +from django.test import TestCase +from model_mommy import mommy + +from api.models import SEQ2SEQ, TextLabel + +from .api.utils import prepare_project + + +class TestTextLabelAnnotation(abc.ABC, TestCase): + collaborative = False + + @classmethod + def setUpTestData(cls): + cls.project = prepare_project( + SEQ2SEQ, + collaborative_annotation=cls.collaborative + ) + cls.example = mommy.make('Example', project=cls.project.item) + users = cls.project.users + cls.user = users[0] + cls.another_user = users[1] + cls.text_label = TextLabel( + example=cls.example, + user=cls.user, + text='foo' + ) + + def test_can_annotate_category_to_unannotated_data(self): + can_annotate = TextLabel.objects.can_annotate(self.text_label, self.project.item) + self.assertTrue(can_annotate) + + +class TestNonCollaborativeTextLabelAnnotation(TestTextLabelAnnotation): + collaborative = False + + def test_cannot_annotate_same_text_to_annotated_data(self): + mommy.make( + 'TextLabel', + example=self.example, + user=self.user, + text=self.text_label.text + ) + can_annotate = TextLabel.objects.can_annotate(self.text_label, self.project.item) + self.assertFalse(can_annotate) + + def test_can_annotate_different_text_to_annotated_data(self): + mommy.make('TextLabel', example=self.example, user=self.user) + can_annotate = TextLabel.objects.can_annotate(self.text_label, self.project.item) + self.assertTrue(can_annotate) + + def test_allow_another_user_to_annotate_same_text(self): + mommy.make( + 'TextLabel', + example=self.example, + user=self.another_user, + text=self.text_label.text + ) + can_annotate = TextLabel.objects.can_annotate(self.text_label, self.project.item) + self.assertTrue(can_annotate) + + +class TestCollaborativeTextLabelAnnotation(TestTextLabelAnnotation): + collaborative = True + + def test_deny_another_user_to_annotate_same_text(self): + mommy.make( + 'TextLabel', + example=self.example, + user=self.another_user, + text=self.text_label.text + ) + can_annotate = TextLabel.objects.can_annotate(self.text_label, self.project.item) + self.assertFalse(can_annotate) + + def test_allow_another_user_to_annotate_different_text(self): + mommy.make( + 'TextLabel', + example=self.example, + user=self.another_user + ) + can_annotate = TextLabel.objects.can_annotate(self.text_label, self.project.item) + self.assertTrue(can_annotate)