|
|
@ -1,12 +1,14 @@ |
|
|
|
from rest_framework import status |
|
|
|
from rest_framework.reverse import reverse |
|
|
|
|
|
|
|
from ...models import DOCUMENT_CLASSIFICATION, SEQUENCE_LABELING, Category |
|
|
|
from ...models import (DOCUMENT_CLASSIFICATION, SEQUENCE_LABELING, Category, |
|
|
|
Span) |
|
|
|
from .utils import (CRUDMixin, make_annotation, make_doc, make_label, |
|
|
|
make_user, prepare_project) |
|
|
|
|
|
|
|
|
|
|
|
class TestAnnotationList(CRUDMixin): |
|
|
|
model = Category |
|
|
|
task = DOCUMENT_CLASSIFICATION |
|
|
|
view_name = 'annotation_list' |
|
|
|
|
|
|
@ -16,9 +18,13 @@ class TestAnnotationList(CRUDMixin): |
|
|
|
cls.non_member = make_user() |
|
|
|
doc = make_doc(cls.project.item) |
|
|
|
for member in cls.project.users: |
|
|
|
make_annotation(task=cls.task, doc=doc, user=member) |
|
|
|
cls.make_annotation(doc, member) |
|
|
|
cls.url = reverse(viewname=cls.view_name, args=[cls.project.item.id, doc.id]) |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def make_annotation(cls, doc, member): |
|
|
|
make_annotation(cls.task, doc=doc, user=member) |
|
|
|
|
|
|
|
def test_allows_project_member_to_fetch_annotation(self): |
|
|
|
for member in self.project.users: |
|
|
|
response = self.assert_fetch(member, status.HTTP_200_OK) |
|
|
@ -32,15 +38,28 @@ class TestAnnotationList(CRUDMixin): |
|
|
|
|
|
|
|
def test_allows_project_member_to_bulk_delete_annotation(self): |
|
|
|
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT) |
|
|
|
count = Category.objects.count() |
|
|
|
count = self.model.objects.count() |
|
|
|
self.assertEqual(count, 2) # delete only own annotation |
|
|
|
|
|
|
|
|
|
|
|
class TestCategoryList(TestAnnotationList): |
|
|
|
model = Category |
|
|
|
task = DOCUMENT_CLASSIFICATION |
|
|
|
view_name = 'category_list' |
|
|
|
|
|
|
|
|
|
|
|
class TestSpanList(TestAnnotationList): |
|
|
|
model = Span |
|
|
|
task = SEQUENCE_LABELING |
|
|
|
view_name = 'span_list' |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def make_annotation(cls, doc, member): |
|
|
|
make_annotation(cls.task, doc=doc, user=member, start_offset=0, end_offset=1) |
|
|
|
|
|
|
|
|
|
|
|
class TestSharedAnnotationList(CRUDMixin): |
|
|
|
model = Category |
|
|
|
task = DOCUMENT_CLASSIFICATION |
|
|
|
view_name = 'annotation_list' |
|
|
|
|
|
|
@ -49,9 +68,13 @@ class TestSharedAnnotationList(CRUDMixin): |
|
|
|
cls.project = prepare_project(task=cls.task, collaborative_annotation=True) |
|
|
|
doc = make_doc(cls.project.item) |
|
|
|
for member in cls.project.users: |
|
|
|
make_annotation(task=cls.task, doc=doc, user=member) |
|
|
|
cls.make_annotation(doc, member) |
|
|
|
cls.url = reverse(viewname=cls.view_name, args=[cls.project.item.id, doc.id]) |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def make_annotation(cls, doc, member): |
|
|
|
make_annotation(cls.task, doc=doc, user=member) |
|
|
|
|
|
|
|
def test_allows_project_member_to_fetch_all_annotation(self): |
|
|
|
for member in self.project.users: |
|
|
|
response = self.assert_fetch(member, status.HTTP_200_OK) |
|
|
@ -59,14 +82,34 @@ class TestSharedAnnotationList(CRUDMixin): |
|
|
|
|
|
|
|
def test_allows_project_member_to_bulk_delete_annotation(self): |
|
|
|
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT) |
|
|
|
count = Category.objects.count() |
|
|
|
count = self.model.objects.count() |
|
|
|
self.assertEqual(count, 0) # delete all annotation in the doc |
|
|
|
|
|
|
|
|
|
|
|
class TestSharedCategoryList(TestSharedAnnotationList): |
|
|
|
model = Category |
|
|
|
task = DOCUMENT_CLASSIFICATION |
|
|
|
view_name = 'category_list' |
|
|
|
|
|
|
|
|
|
|
|
class TestSharedSpanList(TestSharedCategoryList): |
|
|
|
model = Span |
|
|
|
task = SEQUENCE_LABELING |
|
|
|
view_name = 'span_list' |
|
|
|
start_offset = 0 |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def make_annotation(cls, doc, member): |
|
|
|
make_annotation( |
|
|
|
cls.task, |
|
|
|
doc=doc, |
|
|
|
user=member, |
|
|
|
start_offset=cls.start_offset, |
|
|
|
end_offset=cls.start_offset + 1 |
|
|
|
) |
|
|
|
cls.start_offset += 1 |
|
|
|
|
|
|
|
|
|
|
|
class TestAnnotationCreation(CRUDMixin): |
|
|
|
task = DOCUMENT_CLASSIFICATION |
|
|
|
view_name = 'annotation_list' |
|
|
@ -75,10 +118,13 @@ class TestAnnotationCreation(CRUDMixin): |
|
|
|
self.project = prepare_project(task=self.task) |
|
|
|
self.non_member = make_user() |
|
|
|
doc = make_doc(self.project.item) |
|
|
|
label = make_label(self.project.item) |
|
|
|
self.data = {'label': label.id} |
|
|
|
self.data = self.create_data() |
|
|
|
self.url = reverse(viewname=self.view_name, args=[self.project.item.id, doc.id]) |
|
|
|
|
|
|
|
def create_data(self): |
|
|
|
label = make_label(self.project.item) |
|
|
|
return {'label': label.id} |
|
|
|
|
|
|
|
def test_allows_project_member_to_annotate(self): |
|
|
|
for member in self.project.users: |
|
|
|
self.assert_create(member, status.HTTP_201_CREATED) |
|
|
@ -94,6 +140,15 @@ class TestCategoryCreation(TestAnnotationCreation): |
|
|
|
view_name = 'category_list' |
|
|
|
|
|
|
|
|
|
|
|
class TestSpanCreation(TestAnnotationCreation): |
|
|
|
task = SEQUENCE_LABELING |
|
|
|
view_name = 'span_list' |
|
|
|
|
|
|
|
def create_data(self): |
|
|
|
label = make_label(self.project.item) |
|
|
|
return {'label': label.id, 'start_offset': 0, 'end_offset': 1} |
|
|
|
|
|
|
|
|
|
|
|
class TestAnnotationDetail(CRUDMixin): |
|
|
|
task = SEQUENCE_LABELING |
|
|
|
view_name = 'annotation_detail' |
|
|
@ -158,6 +213,11 @@ class TestCategoryDetail(TestAnnotationDetail): |
|
|
|
return make_annotation(task=self.task, doc=doc, user=self.project.users[0]) |
|
|
|
|
|
|
|
|
|
|
|
class TestSpanDetail(TestAnnotationDetail): |
|
|
|
task = SEQUENCE_LABELING |
|
|
|
view_name = 'span_detail' |
|
|
|
|
|
|
|
|
|
|
|
class TestSharedAnnotationDetail(CRUDMixin): |
|
|
|
task = DOCUMENT_CLASSIFICATION |
|
|
|
view_name = 'annotation_detail' |
|
|
@ -165,11 +225,14 @@ class TestSharedAnnotationDetail(CRUDMixin): |
|
|
|
def setUp(self): |
|
|
|
self.project = prepare_project(task=self.task, collaborative_annotation=True) |
|
|
|
doc = make_doc(self.project.item) |
|
|
|
annotation = make_annotation(task=self.task, doc=doc, user=self.project.users[0]) |
|
|
|
annotation = self.make_annotation(doc, self.project.users[0]) |
|
|
|
label = make_label(self.project.item) |
|
|
|
self.data = {'label': label.id} |
|
|
|
self.url = reverse(viewname=self.view_name, args=[self.project.item.id, doc.id, annotation.id]) |
|
|
|
|
|
|
|
def make_annotation(self, doc, member): |
|
|
|
return make_annotation(self.task, doc=doc, user=member) |
|
|
|
|
|
|
|
def test_allows_any_member_to_get_annotation(self): |
|
|
|
for member in self.project.users: |
|
|
|
self.assert_fetch(member, status.HTTP_200_OK) |
|
|
@ -184,3 +247,11 @@ class TestSharedAnnotationDetail(CRUDMixin): |
|
|
|
|
|
|
|
class TestSharedCategoryDetail(TestSharedAnnotationDetail): |
|
|
|
view_name = 'category_detail' |
|
|
|
|
|
|
|
|
|
|
|
class TestSharedSpanDetail(TestSharedAnnotationDetail): |
|
|
|
task = SEQUENCE_LABELING |
|
|
|
view_name = 'span_detail' |
|
|
|
|
|
|
|
def make_annotation(self, doc, member): |
|
|
|
return make_annotation(self.task, doc=doc, user=member, start_offset=0, end_offset=1) |