Browse Source

Merge pull request #1662 from doccano/enhancement/improveTestHelper

Improve test helper
pull/1665/head
Hiroki Nakayama 2 years ago
committed by GitHub
parent
commit
5a03c40894
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 248 additions and 232 deletions
  1. 24
      backend/api/tests/api/test_project.py
  2. 22
      backend/api/tests/api/test_tag.py
  3. 25
      backend/api/tests/api/utils.py
  4. 40
      backend/auto_labeling/tests/test_views.py
  5. 4
      backend/data_export/tests/test_repositories.py
  6. 6
      backend/data_export/tests/test_views.py
  7. 4
      backend/data_import/tests/test_builder.py
  8. 2
      backend/data_import/tests/test_tasks.py
  9. 6
      backend/data_import/tests/test_views.py
  10. 46
      backend/examples/tests/test_comment.py
  11. 50
      backend/examples/tests/test_document.py
  12. 18
      backend/examples/tests/test_example_state.py
  13. 16
      backend/examples/tests/test_filters.py
  14. 30
      backend/examples/tests/test_models.py
  15. 48
      backend/label_types/tests/test_views.py
  16. 5
      backend/labels/tests/test_category.py
  17. 27
      backend/labels/tests/test_span.py
  18. 5
      backend/labels/tests/test_text_label.py
  19. 40
      backend/labels/tests/test_views.py
  20. 38
      backend/members/tests.py
  21. 18
      backend/metrics/tests.py
  22. 2
      backend/roles/tests.py
  23. 4
      backend/users/tests.py

24
backend/api/tests/api/test_project.py

@ -13,7 +13,7 @@ class TestProjectList(CRUDMixin):
cls.url = reverse(viewname='project_list')
def test_return_projects_to_member(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
project = response.data[0]
self.assertEqual(len(response.data), 1)
@ -45,10 +45,10 @@ class TestProjectCreate(CRUDMixin):
response = self.assert_create(self.user, status.HTTP_201_CREATED)
self.assertEqual(response.data['name'], self.data['name'])
def test_disallows_non_staff_user_to_create_project(self):
def test_denies_non_staff_user_to_create_project(self):
self.assert_create(self.user, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_create_project(self):
def test_denies_unauthenticated_user_to_create_project(self):
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
@ -87,7 +87,7 @@ class TestProjectDetailAPI(CRUDMixin):
cls.data = {'description': 'lorem', 'resourcetype': 'SequenceLabelingProject'}
def test_return_project_to_member(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['id'], self.project.item.id)
@ -95,22 +95,22 @@ class TestProjectDetailAPI(CRUDMixin):
self.assert_fetch(self.non_member, status.HTTP_403_FORBIDDEN)
def test_allows_admin_to_update_project(self):
response = self.assert_update(self.project.users[0], status.HTTP_200_OK)
response = self.assert_update(self.project.admin, status.HTTP_200_OK)
self.assertEqual(response.data['description'], self.data['description'])
def test_disallows_non_admin_to_update_project(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_update_project(self):
for member in self.project.staffs:
self.assert_update(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_member_to_update_project(self):
def test_denies_non_member_to_update_project(self):
self.assert_update(self.non_member, status.HTTP_403_FORBIDDEN)
def test_allows_admin_to_delete_project(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
def test_disallows_non_admin_to_delete_project(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_delete_project(self):
for member in self.project.staffs:
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_member_to_delete_project(self):
def test_denies_non_member_to_delete_project(self):
self.assert_delete(self.non_member, status.HTTP_403_FORBIDDEN)

22
backend/api/tests/api/test_tag.py

@ -14,7 +14,7 @@ class TestTagList(CRUDMixin):
cls.url = reverse(viewname='tag_list', args=[cls.project.item.id])
def test_return_tags_to_member(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
@ -34,15 +34,15 @@ class TestTagCreate(CRUDMixin):
cls.url = reverse(viewname='tag_list', args=[cls.project.item.id])
cls.data = {'text': 'example'}
def test_allow_admin_to_create_tag(self):
response = self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
def test_allows_admin_to_create_tag(self):
response = self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(response.data['text'], self.data['text'])
def test_disallow_non_admin_to_create_tag(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_create_tag(self):
for member in self.project.staffs:
self.assert_create(member, status.HTTP_403_FORBIDDEN)
def test_disallow_unauthenticated_user_to_create_tag(self):
def test_denies_unauthenticated_user_to_create_tag(self):
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
@ -57,12 +57,12 @@ class TestTagDelete(CRUDMixin):
tag = make_tag(project=self.project.item)
self.url = reverse(viewname='tag_detail', args=[self.project.item.id, tag.id])
def test_allow_admin_to_delete_tag(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
def test_allows_admin_to_delete_tag(self):
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
def test_disallow_non_admin_to_delete_tag(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_delete_tag(self):
for member in self.project.staffs:
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
def test_disallow_unauthenticated_user_to_delete_tag(self):
def test_denies_unauthenticated_user_to_delete_tag(self):
self.assert_delete(expected=status.HTTP_403_FORBIDDEN)

25
backend/api/tests/api/utils.py

@ -1,5 +1,4 @@
import os
from collections import namedtuple
from typing import List
from django.conf import settings
@ -17,7 +16,27 @@ from roles.models import Role
DATA_DIR = os.path.join(os.path.dirname(__file__), '../../../data_import/tests/data')
ProjectData = namedtuple('ProjectData', ['item', 'users'])
class ProjectData:
def __init__(self, item, members):
self.item = item
self.members = members
@property
def admin(self):
return self.members[0]
@property
def approver(self):
return self.members[1]
@property
def annotator(self):
return self.members[2]
@property
def staffs(self):
return [self.approver, self.annotator]
def create_default_roles():
@ -83,7 +102,7 @@ def make_project(
return ProjectData(
item=project,
users=users,
members=users
)

40
backend/auto_labeling/tests/test_views.py

@ -23,23 +23,23 @@ class TestTemplateList(CRUDMixin):
def test_allow_admin_to_fetch_template_list(self):
self.url += '?task_name=DocumentClassification'
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
self.assertIn('Custom REST Request', response.data)
self.assertGreaterEqual(len(response.data), 1)
def test_deny_non_admin_to_fetch_template_list(self):
def test_deny_project_staff_to_fetch_template_list(self):
self.url += '?task_name=DocumentClassification'
for user in self.project.users[1:]:
for user in self.project.staffs:
self.assert_fetch(user, status.HTTP_403_FORBIDDEN)
def test_return_only_default_template_with_empty_task_name(self):
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
self.assertIn('Custom REST Request', response.data)
def test_return_only_default_template_with_wrong_task_name(self):
self.url += '?task_name=foobar'
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
self.assertIn('Custom REST Request', response.data)
@ -57,21 +57,21 @@ class TestConfigParameter(CRUDMixin):
@patch('auto_labeling.views.RestAPIRequestTesting.send_request', return_value={})
def test_called_with_proper_model(self, mock):
self.assert_create(self.project.users[0], status.HTTP_200_OK)
self.assert_create(self.project.admin, status.HTTP_200_OK)
_, kwargs = mock.call_args
expected = RequestModelFactory.create(self.data['model_name'], self.data['model_attrs'])
self.assertEqual(kwargs['model'], expected)
@patch('auto_labeling.views.RestAPIRequestTesting.send_request', return_value={})
def test_called_with_text(self, mock):
self.assert_create(self.project.users[0], status.HTTP_200_OK)
self.assert_create(self.project.admin, status.HTTP_200_OK)
_, kwargs = mock.call_args
self.assertEqual(kwargs['example'], self.data['text'])
@patch('auto_labeling.views.RestAPIRequestTesting.send_request', return_value={})
def test_called_with_image(self, mock):
self.data['text'] = str(data_dir / 'images/1500x500.jpeg')
self.assert_create(self.project.users[0], status.HTTP_200_OK)
self.assert_create(self.project.admin, status.HTTP_200_OK)
_, kwargs = mock.call_args
self.assertEqual(kwargs['example'], self.data['text'])
@ -96,13 +96,13 @@ class TestTemplateMapping(CRUDMixin):
self.url = reverse(viewname='auto_labeling_template_test', args=[self.project.item.id])
def test_template_mapping(self):
response = self.assert_create(self.project.users[0], status.HTTP_200_OK)
response = self.assert_create(self.project.admin, status.HTTP_200_OK)
expected = [{'label': 'NEUTRAL'}]
self.assertEqual(response.json(), expected)
def test_json_decode_error(self):
self.data['template'] = ''
self.assert_create(self.project.users[0], status.HTTP_400_BAD_REQUEST)
self.assert_create(self.project.admin, status.HTTP_400_BAD_REQUEST)
class TestLabelMapping(CRUDMixin):
@ -117,7 +117,7 @@ class TestLabelMapping(CRUDMixin):
self.url = reverse(viewname='auto_labeling_mapping_test', args=[self.project.item.id])
def test_label_mapping(self):
response = self.assert_create(self.project.users[0], status.HTTP_200_OK)
response = self.assert_create(self.project.admin, status.HTTP_200_OK)
expected = [{'label': 'Negative'}]
self.assertEqual(response.json(), expected)
@ -141,12 +141,12 @@ class TestConfigCreation(CRUDMixin):
self.url = reverse(viewname='auto_labeling_configs', args=[self.project.item.id])
def test_create_config(self):
response = self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
response = self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(response.data['model_name'], self.data['model_name'])
def test_list_config(self):
mommy.make('AutoLabelingConfig', project=self.project.item)
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
@ -168,7 +168,7 @@ class TestAutomatedLabeling(CRUDMixin):
@patch('auto_labeling.views.execute_pipeline', return_value=Categories([{'label': 'POS'}]))
def test_category_labeling(self, mock):
mommy.make('AutoLabelingConfig', task_type='Category', project=self.project.item)
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(Category.objects.count(), 1)
self.assertEqual(Category.objects.first().label, self.category_pos)
@ -182,7 +182,7 @@ class TestAutomatedLabeling(CRUDMixin):
def test_multiple_configs(self, mock):
mommy.make('AutoLabelingConfig', task_type='Category', project=self.project.item)
mommy.make('AutoLabelingConfig', task_type='Category', project=self.project.item)
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(Category.objects.count(), 2)
self.assertEqual(Category.objects.first().label, self.category_pos)
self.assertEqual(Category.objects.last().label, self.category_neg)
@ -197,7 +197,7 @@ class TestAutomatedLabeling(CRUDMixin):
def test_cannot_label_same_category_type(self, mock):
mommy.make('AutoLabelingConfig', task_type='Category', project=self.project.item)
mommy.make('AutoLabelingConfig', task_type='Category', project=self.project.item)
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(Category.objects.count(), 1)
@patch(
@ -210,14 +210,14 @@ class TestAutomatedLabeling(CRUDMixin):
def test_allow_multi_type_configs(self, mock):
mommy.make('AutoLabelingConfig', task_type='Category', project=self.project.item)
mommy.make('AutoLabelingConfig', task_type='Span', project=self.project.item)
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(Category.objects.count(), 1)
self.assertEqual(Span.objects.count(), 1)
@patch('auto_labeling.views.execute_pipeline', return_value=Categories([{'label': 'POS'}]))
def test_cannot_use_other_project_config(self, mock):
mommy.make('AutoLabelingConfig', task_type='Category')
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(Category.objects.count(), 0)
@ -240,7 +240,7 @@ class TestAutomatedSpanLabeling(CRUDMixin):
def test_cannot_label_overlapping_span(self, mock):
mommy.make('AutoLabelingConfig', task_type='Span', project=self.project.item)
mommy.make('AutoLabelingConfig', task_type='Span', project=self.project.item)
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(Span.objects.count(), 1)
@ -262,5 +262,5 @@ class TestAutomatedTextLabeling(CRUDMixin):
def test_cannot_label_same_text(self, mock):
mommy.make('AutoLabelingConfig', task_type='Text', project=self.project.item)
mommy.make('AutoLabelingConfig', task_type='Text', project=self.project.item)
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(TextLabel.objects.count(), 1)

4
backend/data_export/tests/test_repositories.py

@ -14,8 +14,8 @@ class TestCSVWriter(unittest.TestCase):
def test_list(self):
example = mommy.make('Example', project=self.project.item, text='example')
category = mommy.make('Category', example=example, user=self.project.users[0])
span = mommy.make('Span', example=example, user=self.project.users[0], start_offset=0, end_offset=1)
category = mommy.make('Category', example=example, user=self.project.admin)
span = mommy.make('Span', example=example, user=self.project.admin, start_offset=0, end_offset=1)
repository = IntentDetectionSlotFillingRepository(self.project.item)
expected = [
{

6
backend/data_export/tests/test_views.py

@ -12,10 +12,10 @@ class TestDownloadCatalog(CRUDMixin):
self.url = reverse(viewname='download-format', args=[self.project.item.id])
def test_allows_project_admin_to_list_catalog(self):
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
for item in response.data:
self.assertIn('name', item)
def test_denies_non_project_admin_to_list_catalog(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_list_catalog(self):
for member in self.project.staffs:
self.assert_fetch(member, status.HTTP_403_FORBIDDEN)

4
backend/data_import/tests/test_builder.py

@ -44,14 +44,14 @@ class TestColumnBuilder(unittest.TestCase):
expected = {'data': 'Text', 'label': []}
self.assert_record(actual, expected)
def test_disallow_no_data_column(self):
def test_denies_no_data_column(self):
row = {'label': 'Label'}
data_column = builders.DataColumn('text', TextData)
label_columns = [builders.LabelColumn('label', CategoryLabel)]
with self.assertRaises(FileParseException):
self.create_record(row, data_column, label_columns)
def test_disallow_empty_text(self):
def test_denies_empty_text(self):
row = {'text': '', 'label': 'Label'}
data_column = builders.DataColumn('text', TextData)
label_columns = [builders.LabelColumn('label', CategoryLabel)]

2
backend/data_import/tests/test_tasks.py

@ -18,7 +18,7 @@ class TestImportData(TestCase):
def setUp(self):
self.project = prepare_project(self.task)
self.user = self.project.users[0]
self.user = self.project.admin
self.data_path = pathlib.Path(__file__).parent / 'data'
def import_dataset(self, filename, file_format, kwargs=None):

6
backend/data_import/tests/test_views.py

@ -12,10 +12,10 @@ class TestImportCatalog(CRUDMixin):
self.url = reverse(viewname='catalog', args=[self.project.item.id])
def test_allows_project_admin_to_list_catalog(self):
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
for item in response.data:
self.assertIn('name', item)
def test_denies_non_project_admin_to_list_catalog(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_list_catalog(self):
for member in self.project.staffs:
self.assert_fetch(member, status.HTTP_403_FORBIDDEN)

46
backend/examples/tests/test_comment.py

@ -12,14 +12,14 @@ class TestCommentListDocAPI(CRUDMixin):
cls.non_member = make_user()
doc1 = make_doc(cls.project.item)
doc2 = make_doc(cls.project.item)
make_comment(doc1, cls.project.users[0])
make_comment(doc2, cls.project.users[0])
make_comment(doc1, cls.project.admin)
make_comment(doc2, cls.project.admin)
cls.data = {'text': 'example'}
cls.url = reverse(viewname='comment_list', args=[cls.project.item.id])
cls.url += f'?example={doc1.id}'
def test_allows_project_member_to_list_comments(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 1)
@ -30,7 +30,7 @@ class TestCommentListDocAPI(CRUDMixin):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_member_to_create_comment(self):
for member in self.project.users:
for member in self.project.members:
self.assert_create(member, status.HTTP_201_CREATED)
def test_denies_non_project_member_to_create_comment(self):
@ -46,11 +46,11 @@ class TestCommentListProjectAPI(CRUDMixin):
self.project = prepare_project()
self.non_member = make_user()
self.doc = make_doc(self.project.item)
make_comment(self.doc, self.project.users[0])
make_comment(self.doc, self.project.admin)
self.url = reverse(viewname='comment_list', args=[self.project.item.id])
def test_allows_project_member_to_list_comments(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 1)
@ -69,7 +69,7 @@ class TestCommentListProjectAPI(CRUDMixin):
def test_allows_project_member_to_delete_comments(self):
# Todo: Disallow non admin to delete comments.
for member in self.project.users:
for member in self.project.members:
self.assert_bulk_delete(member, status.HTTP_204_NO_CONTENT)
response = self.client.get(self.url)
self.assertEqual(response.data['count'], 0)
@ -87,47 +87,47 @@ class TestCommentDetailAPI(CRUDMixin):
self.project = prepare_project()
self.non_member = make_user()
doc = make_doc(self.project.item)
comment = make_comment(doc, self.project.users[0])
comment = make_comment(doc, self.project.admin)
self.data = {'text': 'example'}
self.url = reverse(viewname='comment_detail', args=[self.project.item.id, comment.id])
def test_allows_comment_owner_to_get_comment(self):
# Todo: Allows project member to get comment.
self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
self.assert_fetch(self.project.admin, status.HTTP_200_OK)
def test_disallows_non_comment_owner_to_get_comment(self):
for member in self.project.users[1:]:
def test_denies_non_comment_owner_to_get_comment(self):
for member in self.project.staffs:
self.assert_fetch(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_project_member_to_get_comment(self):
def test_denies_non_project_member_to_get_comment(self):
self.assert_fetch(self.non_member, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_get_comment(self):
def test_denies_unauthenticated_user_to_get_comment(self):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_comment_owner_to_update_comment(self):
response = self.assert_update(self.project.users[0], status.HTTP_200_OK)
response = self.assert_update(self.project.admin, status.HTTP_200_OK)
self.assertEqual(response.data['text'], self.data['text'])
def test_disallows_non_comment_owner_to_update_comment(self):
for member in self.project.users[1:]:
def test_denies_non_comment_owner_to_update_comment(self):
for member in self.project.staffs:
self.assert_update(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_project_member_to_update_comment(self):
def test_denies_non_project_member_to_update_comment(self):
self.assert_update(self.non_member, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_update_comment(self):
def test_denies_unauthenticated_user_to_update_comment(self):
self.assert_update(expected=status.HTTP_403_FORBIDDEN)
def test_allows_comment_owner_to_delete_comment(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
def test_disallows_non_comment_owner_to_delete_comment(self):
for member in self.project.users[1:]:
def test_denies_non_comment_owner_to_delete_comment(self):
for member in self.project.staffs:
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_project_member_to_delete_comment(self):
def test_denies_non_project_member_to_delete_comment(self):
self.assert_delete(self.non_member, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_delete_comment(self):
def test_denies_unauthenticated_user_to_delete_comment(self):
self.assert_delete(expected=status.HTTP_403_FORBIDDEN)

50
backend/examples/tests/test_document.py

@ -18,7 +18,7 @@ class TestExampleListAPI(CRUDMixin):
self.url = reverse(viewname='example_list', args=[self.project.item.id])
def test_allows_project_member_to_list_docs(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 1)
self.assertIn('results', response.data)
@ -32,28 +32,28 @@ class TestExampleListAPI(CRUDMixin):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_create_doc(self):
response = self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
response = self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(response.data['text'], self.data['text'])
def test_denies_non_project_admin_to_create_doc(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_create_doc(self):
for member in self.project.staffs:
self.assert_create(member, status.HTTP_403_FORBIDDEN)
def test_denies_unauthenticated_user_to_create_doc(self):
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
def test_is_confirmed(self):
make_example_state(self.example, self.project.users[0])
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
make_example_state(self.example, self.project.admin)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
self.assertTrue(response.data['results'][0]['is_confirmed'])
def test_is_not_confirmed(self):
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
self.assertFalse(response.data['results'][0]['is_confirmed'])
def test_does_not_share_another_user_confirmed(self):
make_example_state(self.example, self.project.users[0])
response = self.assert_fetch(self.project.users[1], status.HTTP_200_OK)
make_example_state(self.example, self.project.admin)
response = self.assert_fetch(self.project.annotator, status.HTTP_200_OK)
self.assertFalse(response.data['results'][0]['is_confirmed'])
@ -76,8 +76,8 @@ class TestExampleListCollaborative(CRUDMixin):
self.assertTrue(response.data['results'][0]['is_confirmed'])
def test_does_not_share_confirmed_in_other_role(self):
admin = self.project.users[0]
approver = self.project.users[1]
admin = self.project.admin
approver = self.project.approver
make_example_state(self.example, admin)
response = self.assert_fetch(admin, status.HTTP_200_OK)
@ -91,7 +91,7 @@ class TestExampleListFilter(CRUDMixin):
def setUp(self):
self.project = prepare_project(task=DOCUMENT_CLASSIFICATION)
self.example = make_doc(self.project.item)
make_example_state(self.example, self.project.users[0])
make_example_state(self.example, self.project.admin)
def reverse(self, query_kwargs=None):
base_url = reverse(viewname='example_list', args=[self.project.item.id])
@ -103,27 +103,27 @@ class TestExampleListFilter(CRUDMixin):
self.assertEqual(response.data['count'], expected)
def test_returns_example_if_confirmed_is_true(self):
user = self.project.users[0]
user = self.project.admin
self.assert_filter(data={'confirmed': 'True'}, user=user, expected=1)
def test_does_not_return_example_if_confirmed_is_false(self):
user = self.project.users[0]
user = self.project.admin
self.assert_filter(data={'confirmed': 'False'}, user=user, expected=0)
def test_returns_example_if_confirmed_is_empty(self):
user = self.project.users[0]
user = self.project.admin
self.assert_filter(data={'confirmed': ''}, user=user, expected=1)
def test_does_not_return_example_if_user_is_different(self):
user = self.project.users[1]
user = self.project.approver
self.assert_filter(data={'confirmed': 'True'}, user=user, expected=0)
def test_returns_example_if_user_is_different(self):
user = self.project.users[1]
user = self.project.approver
self.assert_filter(data={'confirmed': 'False'}, user=user, expected=1)
def test_returns_example_if_user_is_different_and_confirmed_is_empty(self):
user = self.project.users[1]
user = self.project.approver
self.assert_filter(data={'confirmed': ''}, user=user, expected=1)
@ -137,7 +137,7 @@ class TestExampleDetail(CRUDMixin):
self.url = reverse(viewname='example_detail', args=[self.project.item.id, doc.id])
def test_allows_project_member_to_get_doc(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertIn('text', response.data)
@ -148,21 +148,21 @@ class TestExampleDetail(CRUDMixin):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_update_doc(self):
response = self.assert_update(self.project.users[0], status.HTTP_200_OK)
response = self.assert_update(self.project.admin, status.HTTP_200_OK)
self.assertEqual(response.data['text'], self.data['text'])
def test_denies_non_project_admin_to_update_doc(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_update_doc(self):
for member in self.project.staffs:
self.assert_update(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_update_doc(self):
self.assert_update(self.non_member, status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_delete_doc(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
def test_denies_non_project_admin_to_delete_doc(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_delete_doc(self):
for member in self.project.staffs:
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_delete_doc(self):

18
backend/examples/tests/test_example_state.py

@ -11,12 +11,12 @@ class TestExampleStateList(CRUDMixin):
cls.non_member = make_user()
cls.project = prepare_project()
cls.example = make_doc(cls.project.item)
for user in cls.project.users:
make_example_state(cls.example, user)
for member in cls.project.members:
make_example_state(cls.example, member)
cls.url = reverse(viewname='example_state_list', args=[cls.project.item.id, cls.example.id])
def test_returns_example_state_to_project_member(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 1)
@ -35,7 +35,7 @@ class TestExampleStateConfirm(CRUDMixin):
self.url = reverse(viewname='example_state_list', args=[self.project.item.id, self.example.id])
def test_allows_member_to_confirm_example(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 0)
self.assert_create(member, status.HTTP_201_CREATED) # confirm
@ -54,13 +54,13 @@ class TestExampleStateConfirmCollaborative(CRUDMixin):
self.url = reverse(viewname='example_state_list', args=[self.project.item.id, self.example.id])
def test_initial_state(self):
for user in self.project.users:
response = self.assert_fetch(user, status.HTTP_200_OK)
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 0)
def test_can_approve_state(self):
admin = self.project.users[0]
admin = self.project.admin
self.assert_create(admin, status.HTTP_201_CREATED)
for user in self.project.users:
response = self.assert_fetch(user, status.HTTP_200_OK)
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 1)

16
backend/examples/tests/test_filters.py

@ -13,8 +13,8 @@ class TestFilterMixin(TestCase):
self.example = make_doc(project.item)
self.request = MagicMock()
self.queryset = Example.objects.all()
make_example_state(self.example, project.users[0])
self.request.user = project.users[0]
make_example_state(self.example, project.admin)
self.request.user = project.admin
def assert_filter(self, data, expected):
f = ExampleFilter(
@ -41,15 +41,15 @@ class TestExampleFilter(TestFilterMixin):
self.assert_filter(data={'confirmed': ''}, expected=1)
def test_does_not_return_example_if_user_is_different(self):
self.request.user = self.project.users[1]
self.request.user = self.project.approver
self.assert_filter(data={'confirmed': 'True'}, expected=0)
def test_returns_example_if_user_is_different(self):
self.request.user = self.project.users[1]
self.request.user = self.project.approver
self.assert_filter(data={'confirmed': 'False'}, expected=1)
def test_returns_example_if_user_is_different_and_confirmed_is_empty(self):
self.request.user = self.project.users[1]
self.request.user = self.project.approver
self.assert_filter(data={'confirmed': ''}, expected=1)
@ -62,16 +62,16 @@ class TestExampleFilterOnCollaborative(TestFilterMixin):
self.prepare(project=self.project)
def test_returns_example_if_confirmed_is_true(self):
for member in self.project.users:
for member in self.project.members:
self.request.user = member
self.assert_filter(data={'confirmed': 'True'}, expected=1)
def test_does_not_return_example_if_confirmed_is_false(self):
for member in self.project.users:
for member in self.project.members:
self.request.user = member
self.assert_filter(data={'confirmed': 'False'}, expected=0)
def test_returns_example_if_confirmed_is_empty(self):
for member in self.project.users:
for member in self.project.members:
self.request.user = member
self.assert_filter(data={'confirmed': ''}, expected=1)

30
backend/examples/tests/test_models.py

@ -19,41 +19,41 @@ class TestExampleState(TestCase):
self.assertEqual(done, 0)
def test_done_confirmed_by_user(self):
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.users[0])
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.admin)
done = ExampleState.objects.count_done(self.examples)
self.assertEqual(done, 1)
def test_done_confirmed_by_multiple_user(self):
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.users[0])
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.users[1])
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.admin)
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.approver)
done = ExampleState.objects.count_done(self.examples)
self.assertEqual(done, 1)
def test_done_confirmed_by_different_example(self):
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.users[0])
mommy.make('ExampleState', example=self.other, confirmed_by=self.project.users[1])
done = ExampleState.objects.count_done(self.examples, self.project.users[0])
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.admin)
mommy.make('ExampleState', example=self.other, confirmed_by=self.project.approver)
done = ExampleState.objects.count_done(self.examples, self.project.admin)
self.assertEqual(done, 1)
def test_initial_user(self):
progress = ExampleState.objects.measure_member_progress(self.examples, self.project.users)
expected_progress = [{'user': user.username, 'done': 0} for user in self.project.users]
progress = ExampleState.objects.measure_member_progress(self.examples, self.project.members)
expected_progress = [{'user': member.username, 'done': 0} for member in self.project.members]
self.assertEqual(progress, {'total': 2, 'progress': expected_progress})
def test_user_count_after_confirmation(self):
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.users[0])
progress = ExampleState.objects.measure_member_progress(self.examples, self.project.users)
expected_progress = [{'user': user.username, 'done': 0} for user in self.project.users]
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.admin)
progress = ExampleState.objects.measure_member_progress(self.examples, self.project.members)
expected_progress = [{'user': member.username, 'done': 0} for member in self.project.members]
expected_progress[0]['done'] = 1
self.assertEqual(progress, {'total': 2, 'progress': expected_progress})
def test_user_count_after_multiple_user_confirmation(self):
user1 = self.project.users[0]
user2 = self.project.users[1]
user1 = self.project.admin
user2 = self.project.approver
mommy.make('ExampleState', example=self.example, confirmed_by=user1)
mommy.make('ExampleState', example=self.example, confirmed_by=user2)
progress = ExampleState.objects.measure_member_progress(self.examples, self.project.users)
expected_progress = [{'user': user.username, 'done': 0} for user in self.project.users]
progress = ExampleState.objects.measure_member_progress(self.examples, self.project.members)
expected_progress = [{'user': member.username, 'done': 0} for member in self.project.members]
expected_progress[0]['done'] = 1
expected_progress[1]['done'] = 1
self.assertEqual(progress, {'total': 2, 'progress': expected_progress})

48
backend/label_types/tests/test_views.py

@ -27,7 +27,7 @@ class TestLabelList(CRUDMixin):
make_label(cls.project_b.item)
def test_returns_labels_to_project_member(self):
for member in self.project_a.users:
for member in self.project_a.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]['id'], self.label.id)
@ -47,7 +47,7 @@ class TestLabelSearch(CRUDMixin):
self.url = reverse(viewname='category_types', args=[self.project.item.id])
def test_search(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
@ -62,16 +62,16 @@ class TestLabelCreate(CRUDMixin):
cls.data = {'text': 'example'}
def test_allows_admin_to_create_label(self):
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
def test_disallows_non_admin_to_create_label(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_create_label(self):
for member in self.project.staffs:
self.assert_create(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_project_member_to_create_label(self):
def test_denies_non_project_member_to_create_label(self):
self.assert_create(self.non_member, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_create_label(self):
def test_denies_unauthenticated_user_to_create_label(self):
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
@ -86,7 +86,7 @@ class TestLabelDetailAPI(CRUDMixin):
cls.data = {'text': 'example'}
def test_returns_label_to_project_member(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(response.data['id'], self.label.id)
@ -97,30 +97,30 @@ class TestLabelDetailAPI(CRUDMixin):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_admin_to_update_label(self):
response = self.assert_update(self.project.users[0], status.HTTP_200_OK)
response = self.assert_update(self.project.admin, status.HTTP_200_OK)
self.assertEqual(response.data['text'], self.data['text'])
def test_disallows_non_admin_to_update_label(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_update_label(self):
for member in self.project.staffs:
self.assert_update(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_project_member_to_update_label(self):
def test_denies_non_project_member_to_update_label(self):
self.assert_update(self.non_member, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_update_label(self):
def test_denies_unauthenticated_user_to_update_label(self):
self.assert_update(expected=status.HTTP_403_FORBIDDEN)
def test_allows_admin_to_delete_label(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
def test_disallows_non_admin_to_delete_label(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_delete_label(self):
for member in self.project.staffs:
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_project_member_to_delete_label(self):
def test_denies_non_project_member_to_delete_label(self):
self.assert_delete(self.non_member, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_delete_label(self):
def test_denies_unauthenticated_user_to_delete_label(self):
self.assert_delete(expected=status.HTTP_403_FORBIDDEN)
@ -140,17 +140,17 @@ class TestLabelUploadAPI(APITestCase):
self.assertEqual(response.status_code, expected_status)
def test_allows_project_admin_to_upload_label(self):
self.assert_upload_file('label/valid_labels.json', self.project.users[0], status.HTTP_201_CREATED)
self.assert_upload_file('label/valid_labels.json', self.project.admin, status.HTTP_201_CREATED)
def test_disallows_project_member_to_upload_label(self):
for member in self.project.users[1:]:
def test_denies_project_member_to_upload_label(self):
for member in self.project.staffs:
self.assert_upload_file('label/valid_labels.json', member, status.HTTP_403_FORBIDDEN)
def test_disallows_non_project_member_to_upload_label(self):
def test_denies_non_project_member_to_upload_label(self):
self.assert_upload_file('label/valid_labels.json', self.non_member, status.HTTP_403_FORBIDDEN)
def test_disallows_unauthenticated_user_to_upload_label(self):
def test_denies_unauthenticated_user_to_upload_label(self):
self.assert_upload_file('label/valid_labels.json', expected_status=status.HTTP_403_FORBIDDEN)
def test_try_to_upload_invalid_file(self):
self.assert_upload_file('label/invalid_labels.json', self.project.users[0], status.HTTP_400_BAD_REQUEST)
self.assert_upload_file('label/invalid_labels.json', self.project.admin, status.HTTP_400_BAD_REQUEST)

5
backend/labels/tests/test_category.py

@ -22,9 +22,8 @@ class TestCategoryLabeling(abc.ABC, TestCase):
)
cls.example = mommy.make('Example', project=cls.project.item)
cls.label_type = mommy.make('CategoryType', project=cls.project.item)
users = cls.project.users
cls.user = users[0]
cls.another_user = users[1]
cls.user = cls.project.admin
cls.another_user = cls.project.approver
cls.category = Category(
example=cls.example,
label=cls.label_type,

27
backend/labels/tests/test_span.py

@ -24,9 +24,8 @@ class TestSpanLabeling(abc.ABC, TestCase):
)
cls.example = mommy.make('Example', project=cls.project.item)
cls.label_type = mommy.make('SpanType', project=cls.project.item)
users = cls.project.users
cls.user = users[0]
cls.another_user = users[1]
cls.user = cls.project.admin
cls.another_user = cls.project.approver
cls.span = Span(
example=cls.example,
label=cls.label_type,
@ -150,7 +149,7 @@ class TestSpan(TestCase):
def setUp(self):
self.project = prepare_project(SEQUENCE_LABELING, allow_overlapping=False)
self.example = mommy.make('Example', project=self.project.item)
self.user = self.project.users[0]
self.user = self.project.admin
def test_start_offset_is_not_negative(self):
with self.assertRaises(IntegrityError):
@ -185,7 +184,7 @@ class TestSpan(TestCase):
def test_unique_constraint_if_overlapping_is_allowed(self):
project = prepare_project(SEQUENCE_LABELING, allow_overlapping=True)
example = mommy.make('Example', project=project.item)
user = project.users[0]
user = project.admin
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=user)
spans = [(5, 10), (5, 11), (4, 10), (6, 9), (9, 15), (0, 6)]
for start_offset, end_offset in spans:
@ -204,8 +203,8 @@ class TestSpanWithoutCollaborativeMode(TestCase):
self.example = mommy.make('Example', project=self.project.item)
def test_allow_users_to_create_same_spans(self):
mommy.make('Span', example=self.example, start_offset=5, end_offset=10, user=self.project.users[0])
mommy.make('Span', example=self.example, start_offset=5, end_offset=10, user=self.project.users[1])
mommy.make('Span', example=self.example, start_offset=5, end_offset=10, user=self.project.admin)
mommy.make('Span', example=self.example, start_offset=5, end_offset=10, user=self.project.approver)
class TestSpanWithCollaborativeMode(TestCase):
@ -213,15 +212,15 @@ class TestSpanWithCollaborativeMode(TestCase):
def test_deny_users_to_create_same_spans(self):
project = prepare_project(SEQUENCE_LABELING, True, allow_overlapping=False)
example = mommy.make('Example', project=project.item)
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.users[0])
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.admin)
with self.assertRaises(ValidationError):
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.users[1])
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.approver)
def test_allow_users_to_create_same_spans_if_overlapping_is_allowed(self):
project = prepare_project(SEQUENCE_LABELING, True, allow_overlapping=True)
example = mommy.make('Example', project=project.item)
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.users[0])
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.users[1])
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.admin)
mommy.make('Span', example=example, start_offset=5, end_offset=10, user=project.approver)
class TestLabelDistribution(TestCase):
@ -229,7 +228,7 @@ class TestLabelDistribution(TestCase):
def setUp(self):
self.project = prepare_project(SEQUENCE_LABELING, allow_overlapping=False)
self.example = mommy.make('Example', project=self.project.item)
self.user = self.project.users[0]
self.user = self.project.admin
def test_calc_label_distribution(self):
label_a = mommy.make('SpanType', text='labelA', project=self.project.item)
@ -238,10 +237,10 @@ class TestLabelDistribution(TestCase):
mommy.make('Span', example=self.example, start_offset=10, end_offset=15, user=self.user, label=label_b)
distribution = Span.objects.calc_label_distribution(
examples=self.project.item.examples.all(),
members=self.project.users,
members=self.project.members,
labels=SpanType.objects.all()
)
expected = {user.username: {label.text: 0 for label in SpanType.objects.all()} for user in self.project.users}
expected = {user.username: {label.text: 0 for label in SpanType.objects.all()} for user in self.project.members}
expected[self.user.username][label_a.text] = 1
expected[self.user.username][label_b.text] = 1
self.assertEqual(distribution, expected)

5
backend/labels/tests/test_text_label.py

@ -19,9 +19,8 @@ class TestTextLabeling(abc.ABC, TestCase):
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.user = cls.project.admin
cls.another_user = cls.project.approver
cls.text_label = TextLabel(
example=cls.example,
user=cls.user,

40
backend/labels/tests/test_views.py

@ -17,7 +17,7 @@ class TestLabelList:
cls.project = prepare_project(task=cls.task)
cls.non_member = make_user()
doc = make_doc(cls.project.item)
for member in cls.project.users:
for member in cls.project.members:
cls.make_annotation(doc, member)
cls.url = reverse(viewname=cls.view_name, args=[cls.project.item.id, doc.id])
@ -26,7 +26,7 @@ class TestLabelList:
make_annotation(cls.task, doc=doc, user=member)
def test_allows_project_member_to_fetch_annotation(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1) # fetch only own annotation
@ -37,7 +37,7 @@ class TestLabelList:
self.assert_fetch(self.non_member, status.HTTP_403_FORBIDDEN)
def test_allows_project_member_to_bulk_delete_annotation(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
count = self.model.objects.count()
self.assertEqual(count, 2) # delete only own annotation
@ -73,7 +73,7 @@ class TestSharedLabelList:
def setUpTestData(cls):
cls.project = prepare_project(task=cls.task, collaborative_annotation=True)
doc = make_doc(cls.project.item)
for member in cls.project.users:
for member in cls.project.members:
cls.make_annotation(doc, member)
cls.url = reverse(viewname=cls.view_name, args=[cls.project.item.id, doc.id])
@ -82,12 +82,12 @@ class TestSharedLabelList:
make_annotation(cls.task, doc=doc, user=member)
def test_allows_project_member_to_fetch_all_annotation(self):
for member in self.project.users:
for member in self.project.members:
response = self.assert_fetch(member, status.HTTP_200_OK)
self.assertEqual(len(response.data), 3)
def test_allows_project_member_to_bulk_delete_annotation(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
count = self.model.objects.count()
self.assertEqual(count, 0) # delete all annotation in the doc
@ -138,7 +138,7 @@ class TestDataLabeling:
return {'label': label.id}
def test_allows_project_member_to_annotate(self):
for member in self.project.users:
for member in self.project.members:
self.assert_create(member, status.HTTP_201_CREATED)
def test_denies_non_project_member_to_annotate(self):
@ -186,16 +186,16 @@ class TestLabelDetail:
return make_annotation(
task=self.task,
doc=doc,
user=self.project.users[0],
user=self.project.admin,
start_offset=0,
end_offset=1
)
def test_allows_owner_to_get_annotation(self):
self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
self.assert_fetch(self.project.admin, status.HTTP_200_OK)
def test_denies_non_owner_to_get_annotation(self):
for member in self.project.users[1:]:
for member in self.project.staffs:
self.assert_fetch(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_get_annotation(self):
@ -205,20 +205,20 @@ class TestLabelDetail:
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_owner_to_update_annotation(self):
self.assert_update(self.project.users[0], status.HTTP_200_OK)
self.assert_update(self.project.admin, status.HTTP_200_OK)
def test_denies_non_owner_to_update_annotation(self):
for member in self.project.users[1:]:
for member in self.project.staffs:
self.assert_update(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_update_annotation(self):
self.assert_update(self.non_member, status.HTTP_403_FORBIDDEN)
def test_allows_owner_to_delete_annotation(self):
self.assert_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
def test_denies_non_owner_to_delete_annotation(self):
for member in self.project.users[1:]:
for member in self.project.staffs:
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_delete_annotation(self):
@ -230,7 +230,7 @@ class TestCategoryDetail(TestLabelDetail, CRUDMixin):
view_name = 'category_detail'
def create_annotation_data(self, doc):
return make_annotation(task=self.task, doc=doc, user=self.project.users[0])
return make_annotation(task=self.task, doc=doc, user=self.project.admin)
class TestSpanDetail(TestLabelDetail, CRUDMixin):
@ -247,7 +247,7 @@ class TestTextDetail(TestLabelDetail, CRUDMixin):
self.data = {'text': 'changed'}
def create_annotation_data(self, doc):
return make_annotation(task=self.task, doc=doc, user=self.project.users[0])
return make_annotation(task=self.task, doc=doc, user=self.project.admin)
class TestSharedLabelDetail:
@ -257,7 +257,7 @@ class TestSharedLabelDetail:
def setUp(self):
self.project = prepare_project(task=self.task, collaborative_annotation=True)
doc = make_doc(self.project.item)
annotation = self.make_annotation(doc, self.project.users[0])
annotation = self.make_annotation(doc, self.project.admin)
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])
@ -266,15 +266,15 @@ class TestSharedLabelDetail:
return make_annotation(self.task, doc=doc, user=member)
def test_allows_any_member_to_get_annotation(self):
for member in self.project.users:
for member in self.project.members:
self.assert_fetch(member, status.HTTP_200_OK)
def test_allows_any_member_to_update_annotation(self):
for member in self.project.users:
for member in self.project.members:
self.assert_update(member, status.HTTP_200_OK)
def test_allows_any_member_to_delete_annotation(self):
self.assert_delete(self.project.users[1], status.HTTP_204_NO_CONTENT)
self.assert_delete(self.project.approver, status.HTTP_204_NO_CONTENT)
class TestSharedCategoryDetail(TestSharedLabelDetail, CRUDMixin):

38
backend/members/tests.py

@ -20,10 +20,10 @@ class TestMemberListAPI(CRUDMixin):
self.url = reverse(viewname='member_list', args=[self.project.item.id])
def test_allows_project_admin_to_know_members(self):
self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
self.assert_fetch(self.project.admin, status.HTTP_200_OK)
def test_denies_non_project_admin_to_know_members(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_know_members(self):
for member in self.project.staffs:
self.assert_fetch(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_know_members(self):
@ -33,10 +33,10 @@ class TestMemberListAPI(CRUDMixin):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_add_member(self):
self.assert_create(self.project.users[0], status.HTTP_201_CREATED)
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
def test_denies_non_project_admin_to_add_member(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_add_member(self):
for member in self.project.staffs:
self.assert_create(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_add_member(self):
@ -53,12 +53,12 @@ class TestMemberListAPI(CRUDMixin):
self.assertEqual(response.status_code, expected)
def test_allows_project_admin_to_remove_members(self):
self.assert_bulk_delete(self.project.users[0], status.HTTP_204_NO_CONTENT)
self.assert_bulk_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
response = self.client.get(self.url)
self.assertEqual(len(response.data), 1)
def test_denies_non_project_admin_to_remove_members(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_remove_members(self):
for member in self.project.staffs:
self.assert_bulk_delete(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_remove_members(self):
@ -74,15 +74,15 @@ class TestMemberRoleDetailAPI(CRUDMixin):
self.project = prepare_project()
self.non_member = make_user()
admin_role = Role.objects.get(name=settings.ROLE_PROJECT_ADMIN)
member = Member.objects.get(user=self.project.users[1])
member = Member.objects.get(user=self.project.approver)
self.url = reverse(viewname='member_detail', args=[self.project.item.id, member.id])
self.data = {'role': admin_role.id}
def test_allows_project_admin_to_known_member(self):
self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
self.assert_fetch(self.project.admin, status.HTTP_200_OK)
def test_denies_non_project_admin_to_know_member(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_know_member(self):
for member in self.project.staffs:
self.assert_fetch(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_know_member(self):
@ -92,10 +92,10 @@ class TestMemberRoleDetailAPI(CRUDMixin):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_change_member_role(self):
self.assert_update(self.project.users[0], status.HTTP_200_OK)
self.assert_update(self.project.admin, status.HTTP_200_OK)
def test_denies_non_project_admin_to_change_member_role(self):
for member in self.project.users[1:]:
def test_denies_project_staff_to_change_member_role(self):
for member in self.project.staffs:
self.assert_update(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_change_member_role(self):
@ -110,10 +110,10 @@ class TestMemberFilter(CRUDMixin):
def setUp(self):
self.project = prepare_project()
self.url = reverse(viewname='member_list', args=[self.project.item.id])
self.url += f'?user={self.project.users[0].id}'
self.url += f'?user={self.project.admin.id}'
def test_filter_role_by_user_id(self):
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
@ -121,7 +121,7 @@ class TestMemberManager(CRUDMixin):
def test_has_role(self):
project = prepare_project()
admin = project.users[0]
admin = project.admin
expected = [
(settings.ROLE_PROJECT_ADMIN, True),
(settings.ROLE_ANNOTATION_APPROVER, False),

18
backend/metrics/tests.py

@ -14,14 +14,14 @@ class TestMemberProgress(CRUDMixin):
self.url = reverse(viewname='member_progress', args=[self.project.item.id])
def test_fetch_initial_progress(self):
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
expected_progress = [{'user': user.username, 'done': 0} for user in self.project.users]
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
expected_progress = [{'user': member.username, 'done': 0} for member in self.project.members]
self.assertEqual(response.data, {'total': 1, 'progress': expected_progress})
def test_fetch_progress(self):
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.users[0])
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
expected_progress = [{'user': user.username, 'done': 0} for user in self.project.users]
mommy.make('ExampleState', example=self.example, confirmed_by=self.project.admin)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
expected_progress = [{'user': member.username, 'done': 0} for member in self.project.members]
expected_progress[0]['done'] = 1
self.assertEqual(response.data, {'total': 1, 'progress': expected_progress})
@ -32,13 +32,13 @@ class TestCategoryDistribution(CRUDMixin):
self.project = prepare_project(DOCUMENT_CLASSIFICATION)
self.example = make_doc(self.project.item)
self.label = make_label(self.project.item, text='label')
mommy.make('Category', example=self.example, label=self.label, user=self.project.users[0])
mommy.make('Category', example=self.example, label=self.label, user=self.project.admin)
self.url = reverse(viewname='category_distribution', args=[self.project.item.id])
def test_fetch_distribution(self):
response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK)
response = self.assert_fetch(self.project.admin, status.HTTP_200_OK)
expected = {
user.username: {self.label.text: 0} for user in self.project.users
member.username: {self.label.text: 0} for member in self.project.members
}
expected[self.project.users[0].username][self.label.text] = 1
expected[self.project.admin.username][self.label.text] = 1
self.assertEqual(response.data, expected)

2
backend/roles/tests.py

@ -15,5 +15,5 @@ class TestRoleAPI(CRUDMixin):
def test_allows_authenticated_user_to_get_roles(self):
self.assert_fetch(self.user, status.HTTP_200_OK)
def test_disallows_unauthenticated_user_to_get_roles(self):
def test_denies_unauthenticated_user_to_get_roles(self):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)

4
backend/users/tests.py

@ -12,14 +12,14 @@ class TestUserAPI(APITestCase):
cls.user = make_user(username='bob')
cls.url = reverse(viewname='user_list')
def test_allow_authenticated_user_to_get_users(self):
def test_allows_authenticated_user_to_get_users(self):
self.client.force_login(self.user)
response = self.client.get(self.url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]['username'], self.user.username)
def test_disallow_unauthenticated_user_to_get_users(self):
def test_denies_unauthenticated_user_to_get_users(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

Loading…
Cancel
Save