Browse Source

Add test cases for assignment API

pull/2261/head
Hironsan 1 year ago
parent
commit
500cd85a5d
3 changed files with 126 additions and 3 deletions
  1. 117
      backend/examples/tests/test_assignment.py
  2. 4
      backend/examples/tests/utils.py
  3. 8
      backend/examples/views/assignment.py

117
backend/examples/tests/test_assignment.py

@ -0,0 +1,117 @@
from rest_framework import status
from rest_framework.reverse import reverse
from .utils import make_assignment, make_doc
from api.tests.utils import CRUDMixin
from examples.models import Assignment
from projects.models import Member
from projects.tests.utils import prepare_project
from users.tests.utils import make_user
class TestAssignmentList(CRUDMixin):
def setUp(self):
self.project = prepare_project()
self.non_member = make_user()
self.example = make_doc(self.project.item)
make_assignment(self.project.item, self.example, self.project.admin)
self.data = {"example": self.example.id, "assignee": self.project.staffs[0].id}
self.url = reverse(viewname="assignment_list", args=[self.project.item.id])
def test_allow_project_member_to_list_assignments(self):
for member in self.project.members:
self.assert_fetch(member, status.HTTP_200_OK)
def test_denies_non_project_member_to_list_assignments(self):
self.assert_fetch(self.non_member, status.HTTP_403_FORBIDDEN)
def test_denies_unauthenticated_user_to_list_assignments(self):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_assign(self):
response = self.assert_create(self.project.admin, status.HTTP_201_CREATED)
self.assertEqual(response.data["example"], self.data["example"])
self.assertEqual(response.data["assignee"], self.data["assignee"])
def test_denies_non_admin_to_assign(self):
for member in self.project.staffs:
self.assert_create(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_assign(self):
self.assert_create(self.non_member, status.HTTP_403_FORBIDDEN)
def test_denies_unauthenticated_user_to_assign(self):
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
class TestAssignmentDetail(CRUDMixin):
def setUp(self):
self.project = prepare_project()
self.non_member = make_user()
example = make_doc(self.project.item)
assignment = make_assignment(self.project.item, example, self.project.admin)
self.data = {"assignee": self.project.staffs[0].id}
self.url = reverse(viewname="assignment_detail", args=[self.project.item.id, assignment.id])
def test_allows_project_member_to_get_assignment(self):
for member in self.project.members:
self.assert_fetch(member, status.HTTP_200_OK)
def test_denies_non_project_member_to_get_assignment(self):
self.assert_fetch(self.non_member, status.HTTP_403_FORBIDDEN)
def test_denies_unauthenticated_user_to_get_assignment(self):
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_reassign(self):
response = self.assert_update(self.project.admin, status.HTTP_200_OK)
self.assertEqual(response.data["assignee"], self.data["assignee"])
def test_denies_non_admin_to_reassign(self):
for member in self.project.staffs:
self.assert_update(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_reassign(self):
self.assert_update(self.non_member, status.HTTP_403_FORBIDDEN)
def test_denies_unauthenticated_user_to_reassign(self):
self.assert_update(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_unassign(self):
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
def test_denies_non_admin_to_unassign(self):
for member in self.project.staffs:
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_unassign(self):
self.assert_delete(self.non_member, status.HTTP_403_FORBIDDEN)
def test_denies_unauthenticated_user_to_unassign(self):
self.assert_delete(expected=status.HTTP_403_FORBIDDEN)
class TestAssignmentBulk(CRUDMixin):
def setUp(self):
self.project = prepare_project()
self.non_member = make_user()
self.example = make_doc(self.project.item)
members = Member.objects.filter(project=self.project.item)
workloads = [{"member_id": member.id, "weight": 100} for member in members]
self.data = {"strategy_name": "sampling_without_replacement", "workloads": workloads}
self.url = reverse(viewname="bulk_assignment", args=[self.project.item.id])
def test_denies_non_admin_to_bulk_assign(self):
for member in self.project.staffs:
self.assert_create(member, status.HTTP_403_FORBIDDEN)
def test_denies_non_project_member_to_bulk_assign(self):
self.assert_create(self.non_member, status.HTTP_403_FORBIDDEN)
def test_denies_unauthenticated_user_to_bulk_assign(self):
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
def test_allows_project_admin_to_bulk_assign(self):
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
expected = self.project.item.examples.count() * len(self.project.members)
self.assertEqual(Assignment.objects.count(), expected)

4
backend/examples/tests/utils.py

@ -15,3 +15,7 @@ def make_image(project, filepath):
def make_example_state(example, user):
return mommy.make("ExampleState", example=example, confirmed_by=user)
def make_assignment(project, example, user):
return mommy.make("Assignment", project=project, example=example, assignee=user)

8
backend/examples/views/assignment.py

@ -83,13 +83,15 @@ class BulkAssignment(APIView):
members = sorted(members, key=lambda m: workload_allocation.member_ids.index(m.id))
dataset_size = project.examples.count() # Todo: unassigned examples
strategy = create_assignment_strategy(strategy_name, dataset_size, workload_allocation.weights)
strategy = create_assignment_strategy(
strategy_name, dataset_size, workload_allocation.weights
) # Todo: raise 400 if weights are not valid
assignments = strategy.assign()
example_ids = project.examples.values_list("pk", flat=True)
examples = project.examples.all()
assignments = [
Assignment(
project=project,
example=example_ids[assignment.example],
example=examples[assignment.example],
assignee=members[assignment.user].user,
)
for assignment in assignments

Loading…
Cancel
Save