Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change club serialization based on approval status #733

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions backend/tests/clubs/test_serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
from datetime import timedelta
from unittest import mock

from django.conf import settings
from django.contrib.auth.models import Permission, User
from django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from rest_framework.exceptions import ValidationError
from rest_framework.request import Request
from rest_framework.test import APIRequestFactory

from clubs.models import Club, Membership
from clubs.serializers import ClubSerializer


class ClubSerializerTestCase(TestCase):
def setUp(self):
self.factory = APIRequestFactory()
self.user = User.objects.create_user(username="testuser", password="12345")
self.club = Club.objects.create(name="Test Club", code="test", approved=True)

# Set renewal period in settings to current time
now = timezone.now()
self.renewal_start = now - timedelta(days=30)
self.renewal_end = now + timedelta(days=30)
settings.RENEWAL_PERIOD = (self.renewal_start, self.renewal_end)

self.serializer = ClubSerializer()

def test_privileged_user_sees_current_version(self):
self.user.user_permissions.add(
Permission.objects.get(codename="see_pending_clubs")
)
request = self.factory.get(reverse("clubs-detail", args=[self.club.code]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for not using client like in the other test files?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to actually send the request to the API -- we just want to create the request object, and then pass it to the serializer. This lets us test the serializer itself instead of the entire view.

The user_permissions.add pattern was unintentional. Changed to self.user.is_superuser = True instead.

request.user = self.user

self.serializer.context["request"] = Request(request)
result = self.serializer.to_representation(self.club)
self.assertEqual(result["name"], "Test Club")

def test_member_sees_current_version(self):
Membership.objects.create(person=self.user, club=self.club)
request = self.factory.get(reverse("clubs-detail", args=[self.club.code]))
request.user = self.user

self.serializer.context["request"] = Request(request)
result = self.serializer.to_representation(self.club)
self.assertEqual(result["name"], "Test Club")

def test_approved_club_visible_to_all(self):
request = self.factory.get(reverse("clubs-detail", args=[self.club.code]))
request.user = self.user

self.serializer.context["request"] = Request(request)
result = self.serializer.to_representation(self.club)
self.assertEqual(result["name"], "Test Club")

def test_bypass_flag_shows_current_version(self):
request = self.factory.get(
f"{reverse('clubs-detail', args=[self.club.code])}?bypass=true"
)
request.user = self.user

self.serializer.context["request"] = Request(request)
result = self.serializer.to_representation(self.club)
self.assertEqual(result["name"], "Test Club")

def test_non_privileged_user_during_renewal_period(self):
# Simulate deactivation at the beginning of the renewal period
self.club.save()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional?

self.club.approved = False
self.club.save()

# Insert a previously approved version into the club's history
past_time = timezone.now() - timedelta(days=180)
with mock.patch("django.utils.timezone.now", return_value=past_time):
self.club.name = "Past Approved Version"
self.club.approved = True
self.club.approved_on = past_time
self.club.save()

self.club.name = "Current Unapproved Version"
self.club.approved = False
self.club.approved_on = None
self.club.save()

request = self.factory.get("/fake-url/")
request.user = self.user
serializer = ClubSerializer(context={"request": Request(request)})

result = serializer.to_representation(self.club)
self.assertEqual(result["name"], "Past Approved Version")
self.assertNotEqual(result["name"], "Current Unapproved Version")

def test_non_privileged_user_outside_renewal_period_ghost_club(self):
self.club.approved = False
self.club.ghost = True
self.club.save()

current_date = self.renewal_end + timedelta(days=1)
with mock.patch("django.utils.timezone.now", return_value=current_date):
approved_date = self.renewal_start + timedelta(days=1)
with mock.patch("django.utils.timezone.now", return_value=approved_date):
self.club.name = "Current Cycle Approved Version"
self.club.approved = True
self.club.approved_on = approved_date
self.club.save()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless there is internal logic in club.save or serializer.to_representation that uses django.utils.timezone.now, we might not need the with clauses since we are explicitly setting club.approved_on


self.club.name = "Current Unapproved Version"
self.club.approved = False
self.club.approved_on = None
self.club.save()

request = self.factory.get(reverse("clubs-detail", args=[self.club.code]))
request.user = self.user

self.serializer.context["request"] = Request(request)
result = self.serializer.to_representation(self.club)
self.assertEqual(result["name"], "Current Cycle Approved Version")
self.assertNotEqual(result["name"], "Current Unapproved Version")

def test_non_privileged_user_no_approved_version(self):
self.club.approved = False
self.club.save()

request = self.factory.get(reverse("clubs-detail", args=[self.club.code]))
request.user = self.user
self.serializer.context["request"] = Request(request)

with self.assertRaises(ValidationError) as context:
self.serializer.to_representation(self.club)

self.assertEqual(context.exception.detail[0], "Club not found")
self.assertEqual(context.exception.get_codes()[0], "not_found")

def test_non_privileged_user_outside_renewal_period_non_ghost_club(self):
self.club.approved = False
self.club.ghost = False
self.club.save()

current_date = self.renewal_end + timedelta(days=1)
with mock.patch("django.utils.timezone.now", return_value=current_date):
request = self.factory.get(reverse("clubs-detail", args=[self.club.code]))
request.user = self.user

self.serializer.context["request"] = Request(request)
with self.assertRaises(ValidationError) as context:
self.serializer.to_representation(self.club)

self.assertEqual(context.exception.detail[0], "Club not found")
self.assertEqual(context.exception.get_codes()[0], "not_found") #
Loading