Skip to content

Commit 2262bf1

Browse files
Merge pull request #20 from jazkarta/task/filter-participant-list
Ref: Added filter for participant list to only fetch the participants…
2 parents 55a9f53 + 0a214c1 commit 2262bf1

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

api/participant/tests/test_participant_viewset.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from django.contrib.auth import get_user_model
55
from users.models.user import UserRole
66
from participant.models import Invitation
7+
from django.utils import timezone
8+
from datetime import timedelta
79

810
User = get_user_model()
911

@@ -60,6 +62,8 @@ def test_invite_participant(self, api_client, researcher_user, participant_user,
6062

6163
url = reverse("participant-invite", kwargs={"pk": participant_user.pk})
6264
payload = {"email": "guardian@example.com"}
65+
66+
# print(f"")
6367

6468
response = api_client.post(url, payload, format="json")
6569

@@ -86,3 +90,52 @@ def test_check_email(self, api_client, researcher_user, email, is_taken, expecte
8690
assert response.status_code == expected_status
8791
if expected_status == status.HTTP_200_OK:
8892
assert response.data["detail"] == "Email is available"
93+
94+
@pytest.mark.parametrize("invited_by_user", [True, False])
95+
def test_list_participants_filtered_by_logged_in_user(
96+
self, api_client, researcher_user, participant_user, invited_by_user
97+
):
98+
"""
99+
Test that the list endpoint only returns participants invited by the logged-in researcher.
100+
"""
101+
102+
participant_1 = User.objects.create_user(
103+
email="p1@example.com", password="password123", role=UserRole.PARTICIPANT
104+
)
105+
participant_2 = User.objects.create_user(
106+
email="p2@example.com", password="password123", role=UserRole.PARTICIPANT
107+
)
108+
109+
expiry = timezone.now() + timedelta(days=7)
110+
111+
if invited_by_user:
112+
Invitation.objects.create(user=participant_1, invited_by=researcher_user, expiry_date=expiry)
113+
Invitation.objects.create(user=participant_2, invited_by=researcher_user, expiry_date=expiry)
114+
expected_ids = [participant_1.id, participant_2.id]
115+
else:
116+
other_researcher = User.objects.create_user(
117+
email="other@example.com",
118+
password="password123",
119+
role=UserRole.RESEARCHER
120+
)
121+
Invitation.objects.create(user=participant_1, invited_by=other_researcher, expiry_date=expiry)
122+
Invitation.objects.create(user=participant_2, invited_by=other_researcher, expiry_date=expiry)
123+
expected_ids = []
124+
125+
api_client.force_authenticate(user=researcher_user)
126+
url = reverse("participant-list")
127+
response = api_client.get(url, format="json")
128+
129+
assert response.status_code == 200
130+
131+
# Handle pagination if present
132+
if isinstance(response.data, dict) and "results" in response.data:
133+
returned_ids = [p["id"] for p in response.data["results"]]
134+
else:
135+
returned_ids = [p["id"] for p in response.data]
136+
137+
print(f"\nInvited: {invited_by_user}")
138+
print(f"Expected IDs: {expected_ids}")
139+
print(f"Returned IDs: {returned_ids}")
140+
141+
assert set(returned_ids) == set(expected_ids), f"Expected IDs {expected_ids}, but got {returned_ids}"

api/participant/views.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,24 @@ class ParticipantViewSet(viewsets.ModelViewSet):
3030
"""
3131
ViewSet for managing participant accounts.
3232
Only Researchers can create participants.
33+
Researchers will see the list of the participants invited by himself.
3334
"""
34-
queryset = User.objects.filter(role=UserRole.PARTICIPANT)
3535
serializer_class = ParticipantCreateSerializer
3636
permission_classes = [IsResearcher]
37+
queryset = User.objects.filter(role=UserRole.PARTICIPANT)
38+
39+
def get_queryset(self):
40+
qs = super().get_queryset()
41+
if self.action == "list":
42+
qs = (
43+
qs.filter(invitations__invited_by=self.request.user)
44+
.select_related(
45+
"participant_profile",
46+
"participant_profile__guardian",
47+
)
48+
.distinct()
49+
)
50+
return qs
3751

3852
@swagger_auto_schema(
3953
manual_parameters=[

0 commit comments

Comments
 (0)