Skip to content

Commit 500cd85

Browse files
committed
Add test cases for assignment API
1 parent 82e7289 commit 500cd85

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
from rest_framework import status
2+
from rest_framework.reverse import reverse
3+
4+
from .utils import make_assignment, make_doc
5+
from api.tests.utils import CRUDMixin
6+
from examples.models import Assignment
7+
from projects.models import Member
8+
from projects.tests.utils import prepare_project
9+
from users.tests.utils import make_user
10+
11+
12+
class TestAssignmentList(CRUDMixin):
13+
def setUp(self):
14+
self.project = prepare_project()
15+
self.non_member = make_user()
16+
self.example = make_doc(self.project.item)
17+
make_assignment(self.project.item, self.example, self.project.admin)
18+
self.data = {"example": self.example.id, "assignee": self.project.staffs[0].id}
19+
self.url = reverse(viewname="assignment_list", args=[self.project.item.id])
20+
21+
def test_allow_project_member_to_list_assignments(self):
22+
for member in self.project.members:
23+
self.assert_fetch(member, status.HTTP_200_OK)
24+
25+
def test_denies_non_project_member_to_list_assignments(self):
26+
self.assert_fetch(self.non_member, status.HTTP_403_FORBIDDEN)
27+
28+
def test_denies_unauthenticated_user_to_list_assignments(self):
29+
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
30+
31+
def test_allows_project_admin_to_assign(self):
32+
response = self.assert_create(self.project.admin, status.HTTP_201_CREATED)
33+
self.assertEqual(response.data["example"], self.data["example"])
34+
self.assertEqual(response.data["assignee"], self.data["assignee"])
35+
36+
def test_denies_non_admin_to_assign(self):
37+
for member in self.project.staffs:
38+
self.assert_create(member, status.HTTP_403_FORBIDDEN)
39+
40+
def test_denies_non_project_member_to_assign(self):
41+
self.assert_create(self.non_member, status.HTTP_403_FORBIDDEN)
42+
43+
def test_denies_unauthenticated_user_to_assign(self):
44+
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
45+
46+
47+
class TestAssignmentDetail(CRUDMixin):
48+
def setUp(self):
49+
self.project = prepare_project()
50+
self.non_member = make_user()
51+
example = make_doc(self.project.item)
52+
assignment = make_assignment(self.project.item, example, self.project.admin)
53+
self.data = {"assignee": self.project.staffs[0].id}
54+
self.url = reverse(viewname="assignment_detail", args=[self.project.item.id, assignment.id])
55+
56+
def test_allows_project_member_to_get_assignment(self):
57+
for member in self.project.members:
58+
self.assert_fetch(member, status.HTTP_200_OK)
59+
60+
def test_denies_non_project_member_to_get_assignment(self):
61+
self.assert_fetch(self.non_member, status.HTTP_403_FORBIDDEN)
62+
63+
def test_denies_unauthenticated_user_to_get_assignment(self):
64+
self.assert_fetch(expected=status.HTTP_403_FORBIDDEN)
65+
66+
def test_allows_project_admin_to_reassign(self):
67+
response = self.assert_update(self.project.admin, status.HTTP_200_OK)
68+
self.assertEqual(response.data["assignee"], self.data["assignee"])
69+
70+
def test_denies_non_admin_to_reassign(self):
71+
for member in self.project.staffs:
72+
self.assert_update(member, status.HTTP_403_FORBIDDEN)
73+
74+
def test_denies_non_project_member_to_reassign(self):
75+
self.assert_update(self.non_member, status.HTTP_403_FORBIDDEN)
76+
77+
def test_denies_unauthenticated_user_to_reassign(self):
78+
self.assert_update(expected=status.HTTP_403_FORBIDDEN)
79+
80+
def test_allows_project_admin_to_unassign(self):
81+
self.assert_delete(self.project.admin, status.HTTP_204_NO_CONTENT)
82+
83+
def test_denies_non_admin_to_unassign(self):
84+
for member in self.project.staffs:
85+
self.assert_delete(member, status.HTTP_403_FORBIDDEN)
86+
87+
def test_denies_non_project_member_to_unassign(self):
88+
self.assert_delete(self.non_member, status.HTTP_403_FORBIDDEN)
89+
90+
def test_denies_unauthenticated_user_to_unassign(self):
91+
self.assert_delete(expected=status.HTTP_403_FORBIDDEN)
92+
93+
94+
class TestAssignmentBulk(CRUDMixin):
95+
def setUp(self):
96+
self.project = prepare_project()
97+
self.non_member = make_user()
98+
self.example = make_doc(self.project.item)
99+
members = Member.objects.filter(project=self.project.item)
100+
workloads = [{"member_id": member.id, "weight": 100} for member in members]
101+
self.data = {"strategy_name": "sampling_without_replacement", "workloads": workloads}
102+
self.url = reverse(viewname="bulk_assignment", args=[self.project.item.id])
103+
104+
def test_denies_non_admin_to_bulk_assign(self):
105+
for member in self.project.staffs:
106+
self.assert_create(member, status.HTTP_403_FORBIDDEN)
107+
108+
def test_denies_non_project_member_to_bulk_assign(self):
109+
self.assert_create(self.non_member, status.HTTP_403_FORBIDDEN)
110+
111+
def test_denies_unauthenticated_user_to_bulk_assign(self):
112+
self.assert_create(expected=status.HTTP_403_FORBIDDEN)
113+
114+
def test_allows_project_admin_to_bulk_assign(self):
115+
self.assert_create(self.project.admin, status.HTTP_201_CREATED)
116+
expected = self.project.item.examples.count() * len(self.project.members)
117+
self.assertEqual(Assignment.objects.count(), expected)

backend/examples/tests/utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ def make_image(project, filepath):
1515

1616
def make_example_state(example, user):
1717
return mommy.make("ExampleState", example=example, confirmed_by=user)
18+
19+
20+
def make_assignment(project, example, user):
21+
return mommy.make("Assignment", project=project, example=example, assignee=user)

backend/examples/views/assignment.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,15 @@ def post(self, *args, **kwargs):
8383
members = sorted(members, key=lambda m: workload_allocation.member_ids.index(m.id))
8484

8585
dataset_size = project.examples.count() # Todo: unassigned examples
86-
strategy = create_assignment_strategy(strategy_name, dataset_size, workload_allocation.weights)
86+
strategy = create_assignment_strategy(
87+
strategy_name, dataset_size, workload_allocation.weights
88+
) # Todo: raise 400 if weights are not valid
8789
assignments = strategy.assign()
88-
example_ids = project.examples.values_list("pk", flat=True)
90+
examples = project.examples.all()
8991
assignments = [
9092
Assignment(
9193
project=project,
92-
example=example_ids[assignment.example],
94+
example=examples[assignment.example],
9395
assignee=members[assignment.user].user,
9496
)
9597
for assignment in assignments

0 commit comments

Comments
 (0)