diff --git a/hackathon_site/event/api_urls.py b/hackathon_site/event/api_urls.py index 0c7b4e3d8..a00b02a37 100644 --- a/hackathon_site/event/api_urls.py +++ b/hackathon_site/event/api_urls.py @@ -6,4 +6,5 @@ urlpatterns = [ path("users/user/", views.CurrentUserAPIView.as_view(), name="current-user"), + path("teams/team/", views.CurrentTeamAPIView.as_view(), name="current-team"), ] diff --git a/hackathon_site/event/serializers.py b/hackathon_site/event/serializers.py index 0fc410ffb..afe2cda10 100644 --- a/hackathon_site/event/serializers.py +++ b/hackathon_site/event/serializers.py @@ -1,7 +1,7 @@ from django.contrib.auth.models import Group from rest_framework import serializers -from event.models import Profile, User +from event.models import Profile, User, Team class GroupSerializer(serializers.ModelSerializer): @@ -10,7 +10,20 @@ class Meta: fields = ("id", "name") +class TeamSerializer(serializers.ModelSerializer): + class Meta: + model = Team + fields = ( + "id", + "team_code", + "created_at", + "updated_at", + ) + + class ProfileSerializer(serializers.ModelSerializer): + team = TeamSerializer(read_only=True) + class Meta: model = Profile fields = ( @@ -20,6 +33,7 @@ class Meta: "attended", "acknowledge_rules", "e_signature", + "team", ) diff --git a/hackathon_site/event/test_api.py b/hackathon_site/event/test_api.py index 20fb37800..6da8d53bb 100644 --- a/hackathon_site/event/test_api.py +++ b/hackathon_site/event/test_api.py @@ -4,7 +4,8 @@ from rest_framework.test import APITestCase from hackathon_site.tests import SetupUserMixin -from event.models import Profile, User +from event.models import Profile, User, Team +from event.serializers import TeamSerializer, UserSerializer, ProfileSerializer, GroupSerializer class CurrentUserTestCase(SetupUserMixin, APITestCase): @@ -37,26 +38,48 @@ def test_user_has_no_profile(self): self.assertEqual(expected_response, data) def test_user_has_profile(self): - expected_response = { - **{ - attr: getattr(self.user, attr) - for attr in ("id", "first_name", "last_name", "email") - }, - "profile": { - attr: getattr(self.profile, attr) - for attr in ( - "id", - "status", - "id_provided", - "attended", - "acknowledge_rules", - "e_signature", - ) - }, - "groups": [{"id": self.group.id, "name": self.group.name}], - } self._login() response = self.client.get(self.view) + user_expected = User.objects.get(pk=self.user.pk) + serializer = UserSerializer(user_expected) self.assertEqual(response.status_code, status.HTTP_200_OK) - data = response.json() - self.assertEqual(data, expected_response) + self.assertEqual(response.json(), serializer.data) + + + + + +class CurrentTeamTestCase(SetupUserMixin, APITestCase): + def setUp(self): + super().setUp() + self.group = Group.objects.create(name="Test Users") + self.user.groups.add(self.group) + self.team = Team.objects.create() + + self.profile = Profile.objects.create( + user=self.user, team=self.team, status="Accepted" + ) + + self.view = reverse("api:event:current-team") + + def test_user_not_logged_in(self): + response = self.client.get(self.view) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + + def test_user_has_no_profile(self): + # when the user attempts to access the team, while it has no profile. The user must be accepted or waitlisted to have formed a team. + self.profile.delete() + self._login() + response = self.client.get(self.view) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_user_has_profile(self): + # When user has a profile and attempts to access the team, then the user should get the correct response. + self._login() + response = self.client.get(self.view) + team_expected = Team.objects.get(pk=self.team.pk) + serializer = TeamSerializer(team_expected) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json(), serializer.data) + + diff --git a/hackathon_site/event/tests.py b/hackathon_site/event/tests.py index 670d84275..652b053a6 100644 --- a/hackathon_site/event/tests.py +++ b/hackathon_site/event/tests.py @@ -1,8 +1,14 @@ +from django.contrib.auth.models import Group +from django.conf import settings from django.test import TestCase from django.urls import reverse from rest_framework import status +import pytz + + from event.models import Profile, Team, User +from event.serializers import TeamSerializer, UserSerializer, GroupSerializer, ProfileSerializer class ProfileTestCase(TestCase): @@ -31,3 +37,82 @@ def test_index_view(self): url = reverse("event:index") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class TeamSerializerTestCase(TestCase): + def test_serializer(self): + tz = pytz.timezone(settings.TIME_ZONE) + + team = Team.objects.create() + team_serialized = TeamSerializer(team).data + team_expected = { + "id": team.id, + "team_code": team.team_code, + "created_at": team.created_at.astimezone(tz).isoformat(), + "updated_at": team.updated_at.astimezone(tz).isoformat(), + } + self.assertEqual(team_expected, team_serialized) + +class UserSerializerTestCase(TestCase): + def test_serializer(self): + team = Team.objects.create() + group = Group.objects.create(name="Test") + user = User.objects.create() + user.groups.add(group) + + profile = Profile.objects.create( + user=user, + team=team, + ) + + + user_serialized = UserSerializer(user).data + profile_serialized = ProfileSerializer(user.profile).data + group_serialized = GroupSerializer(user.groups).data + + user_expected = { + "id": user.id, + "first_name": user.first_name, + "last_name": user.last_name, + "email": user.email, + "profile": profile_serialized, + "groups": group_serialized, + } + self.assertEqual(user_expected, user_serialized) + +class GroupSerializerTestCase(TestCase): + def test_serializer(self): + group = Group.objects.create(name="Test") + group_serialized = GroupSerializer(group).data + group_expected = { + "id": group.id, + "name": group.name, + } + self.assertEqual(group_expected, group_serialized) + +class ProfileSerializerTestCase(TestCase): + def setUp(self): + self.user = User.objects.create_user( + username="foo@bar.com", + password="foobar123", + first_name="Foo", + last_name="Bar", + ) + + def test_serializer(self): + team = Team.objects.create() + team_serialized = TeamSerializer(team).data + + profile = Profile.objects.create(user=self.user, team=team) + profile_serialized = ProfileSerializer(profile).data + profile_expected = { + "id": profile.id, + "status": profile.status, + "id_provided": profile.id_provided, + "attended": profile.attended, + "acknowledge_rules": profile.acknowledge_rules, + "e_signature": profile.e_signature, + "team": team_serialized, + } + self.assertEqual(profile_expected, profile_serialized) + diff --git a/hackathon_site/event/views.py b/hackathon_site/event/views.py index 24053b38c..10fdfa089 100644 --- a/hackathon_site/event/views.py +++ b/hackathon_site/event/views.py @@ -1,8 +1,8 @@ from django.views.generic import TemplateView from rest_framework import generics, mixins -from event.models import User -from event.serializers import UserSerializer +from event.models import User, Team +from event.serializers import UserSerializer, TeamSerializer class IndexView(TemplateView): @@ -30,3 +30,27 @@ def get(self, request, *args, **kwargs): group list are nested within the profile and user object, respectively. """ return self.retrieve(request, *args, **kwargs) + + +class CurrentTeamAPIView(generics.GenericAPIView, mixins.RetrieveModelMixin): + """ + View to handle API interaction with the current logged in user's team + """ + + queryset = Team.objects.all() + serializer_class = TeamSerializer + + def get_object(self): + queryset = self.get_queryset() + + return generics.get_object_or_404( + queryset, profile__user_id=self.request.user.id + ) + + def get(self, request, *args, **kwargs): + """ + Get the current users team profile and team details + + Reads the profile of the current logged in team. + """ + return self.retrieve(request, *args, **kwargs)