mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-30 23:39:54 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			329 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Copyright (C) 2018-2025 by BDE ENS Paris-Saclay
 | |
| # SPDX-License-Identifier: GPL-3.0-or-later
 | |
| 
 | |
| import os
 | |
| 
 | |
| from api.tests import TestAPI
 | |
| from django.contrib.auth.models import User
 | |
| from django.core.files.uploadedfile import SimpleUploadedFile
 | |
| from django.test import TestCase
 | |
| from rest_framework.test import APITestCase
 | |
| from django.urls import reverse
 | |
| from django.utils import timezone
 | |
| 
 | |
| from ..api.views import FamilyViewSet, FamilyMembershipViewSet, ChallengeViewSet, AchievementViewSet
 | |
| from ..models import Family, FamilyMembership, Challenge, Achievement
 | |
| 
 | |
| 
 | |
| class TestFamily(TestCase):
 | |
|     """
 | |
|     Test family
 | |
|     """
 | |
| 
 | |
|     def setUp(self):
 | |
|         self.user = User.objects.create_superuser(
 | |
|             username='admintoto',
 | |
|             password='toto1234',
 | |
|             email='toto@example.com',
 | |
|         )
 | |
|         self.client.force_login(self.user)
 | |
| 
 | |
|         sess = self.client.session
 | |
|         sess['permission_mask'] = 42
 | |
|         sess.save()
 | |
| 
 | |
|         self.family = Family.objects.create(
 | |
|             name='Test family',
 | |
|             description='',
 | |
|         )
 | |
| 
 | |
|         self.challenge = Challenge.objects.create(
 | |
|             name='Test challenge',
 | |
|             description='',
 | |
|             points=100,
 | |
|         )
 | |
| 
 | |
|         self.achievement = Achievement.objects.create(
 | |
|             family=self.family,
 | |
|             challenge=self.challenge,
 | |
|             valid=False,
 | |
|         )
 | |
| 
 | |
|     def test_family_list(self):
 | |
|         """
 | |
|         Test display family list
 | |
|         """
 | |
|         response = self.client.get(reverse("family:family_list"))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_family_create(self):
 | |
|         """
 | |
|         Test create a family
 | |
|         """
 | |
|         response = self.client.get(reverse("family:family_create"))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         response = self.client.post(reverse("family:family_create"), data={
 | |
|             "name": "Family toto",
 | |
|             "description": "A test family",
 | |
|         })
 | |
|         self.assertTrue(Family.objects.filter(name="Family toto").exists())
 | |
|         self.assertRedirects(response, reverse("family:manage"), 302, 200)
 | |
| 
 | |
|     def test_family_detail(self):
 | |
|         """
 | |
|         Test display the detail of a family
 | |
|         """
 | |
|         response = self.client.get(reverse("family:family_detail", args=(self.family.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_family_update(self):
 | |
|         """
 | |
|         Test update a family
 | |
|         """
 | |
|         response = self.client.get(reverse("family:family_update", args=(self.family.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         response = self.client.post(reverse("family:family_update", args=(self.family.pk,)), data=dict(
 | |
|             name="Toto family updated",
 | |
|             description="A larger description for the test family"
 | |
|         ))
 | |
|         self.assertRedirects(response, self.family.get_absolute_url(), 302, 200)
 | |
|         self.assertTrue(Family.objects.filter(name="Toto family updated").exists())
 | |
| 
 | |
|     def test_family_update_picture(self):
 | |
|         """
 | |
|         Test update the picture of a family
 | |
|         """
 | |
|         response = self.client.get(reverse("family:update_pic", args=(self.family.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         old_pic = self.family.display_image
 | |
| 
 | |
|         with open("apps/family/static/family/img/default_picture.png", "rb") as f:
 | |
|             image = SimpleUploadedFile("image.png", f.read(), "image/png")
 | |
|             response = self.client.post(reverse("family:update_pic", args=(self.family.pk,)), dict(
 | |
|                 image=image,
 | |
|                 x=0,
 | |
|                 y=0,
 | |
|                 width=200,
 | |
|                 height=200,
 | |
|             ))
 | |
|             self.assertRedirects(response, self.family.get_absolute_url(), 302, 200)
 | |
| 
 | |
|         self.family.refresh_from_db()
 | |
|         self.assertTrue(os.path.exists(self.family.display_image.path))
 | |
|         os.remove(self.family.display_image.path)
 | |
| 
 | |
|         self.family.display_image = old_pic
 | |
|         self.family.save()
 | |
| 
 | |
|     def test_family_add_member(self):
 | |
|         """
 | |
|         Test add memberships to a family
 | |
|         """
 | |
|         response = self.client.get(reverse("family:family_add_member", args=(self.family.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         user = User.objects.create(username="totototo")
 | |
|         user.profile.registration_valid = True
 | |
|         user.profile.email_confirmed = True
 | |
|         user.profile.save()
 | |
|         user.save()
 | |
| 
 | |
|         response = self.client.post(reverse("family:family_add_member", args=(self.family.pk,)), data=dict(
 | |
|             user=user.pk,
 | |
|         ))
 | |
|         self.assertRedirects(response, self.family.get_absolute_url(), 302, 200)
 | |
| 
 | |
|         self.assertTrue(FamilyMembership.objects.filter(user=user, family=self.family, year=timezone.now().year).exists())
 | |
| 
 | |
|     def test_challenge_list(self):
 | |
|         """
 | |
|         Test display challenge list
 | |
|         """
 | |
|         response = self.client.get(reverse('family:challenge_list'))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_challenge_create(self):
 | |
|         """
 | |
|         Test create a challenge
 | |
|         """
 | |
|         response = self.client.get(reverse("family:challenge_create"))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         response = self.client.post(reverse("family:challenge_create"), data={
 | |
|             "name": "Challenge for toto",
 | |
|             "description": "A test challenge",
 | |
|             "points": 50,
 | |
|         })
 | |
|         self.assertTrue(Challenge.objects.filter(name="Challenge for toto").exists())
 | |
|         self.assertRedirects(response, reverse("family:manage"), 302, 200)
 | |
| 
 | |
|     def test_challenge_detail(self):
 | |
|         """
 | |
|         Test display the detail of a challenge
 | |
|         """
 | |
|         response = self.client.get(reverse("family:challenge_detail", args=(self.challenge.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_challenge_update(self):
 | |
|         """
 | |
|         Test update a challenge
 | |
|         """
 | |
|         response = self.client.get(reverse("family:challenge_update", args=(self.challenge.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         response = self.client.post(reverse("family:challenge_update", args=(self.challenge.pk,)), data=dict(
 | |
|             name="Challenge updated",
 | |
|             description="Another description",
 | |
|             points=10,
 | |
|         ))
 | |
|         self.assertRedirects(response, self.challenge.get_absolute_url(), 302, 200)
 | |
|         self.assertTrue(Challenge.objects.filter(name="Challenge updated").exists())
 | |
| 
 | |
|     def test_render_manage_page(self):
 | |
|         """
 | |
|         Test render manage page
 | |
|         """
 | |
|         response = self.client.get(reverse("family:manage"))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_validate_achievement(self):
 | |
|         """
 | |
|         Test validate an achievement
 | |
|         """
 | |
|         old_family_score = self.family.score
 | |
| 
 | |
|         response = self.client.get(reverse("family:achievement_validate", args=(self.achievement.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         response = self.client.post(reverse("family:achievement_validate", args=(self.achievement.pk,)))
 | |
|         self.assertRedirects(response, reverse("family:achievement_list"), 302, 200)
 | |
| 
 | |
|         self.achievement.refresh_from_db()
 | |
|         self.assertIs(self.achievement.valid, True)
 | |
| 
 | |
|         self.family.refresh_from_db()
 | |
|         self.assertEqual(self.family.score, old_family_score + self.achievement.challenge.points)
 | |
| 
 | |
|     def test_delete_achievement(self):
 | |
|         """
 | |
|         Test delete an achievement
 | |
|         """
 | |
|         response = self.client.get(reverse("family:achievement_delete", args=(self.achievement.pk,)))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         response = self.client.delete(reverse("family:achievement_delete", args=(self.achievement.pk,)))
 | |
|         self.assertRedirects(response, reverse("family:achievement_list"), 302, 200)
 | |
|         self.assertFalse(Achievement.objects.filter(pk=self.achievement.pk).exists())
 | |
| 
 | |
| 
 | |
| class TestBatchAchievements(APITestCase):
 | |
|     def setUp(self):
 | |
|         self.user = User.objects.create_superuser(
 | |
|             username='admintoto',
 | |
|             password='toto1234',
 | |
|             email='toto@example.com',
 | |
|         )
 | |
|         self.client.force_login(self.user)
 | |
| 
 | |
|         sess = self.client.session
 | |
|         sess['permission_mask'] = 42
 | |
|         sess.save()
 | |
| 
 | |
|         self.families = [
 | |
|             Family.objects.create(name=f'Famille {i}', description='') for i in range(2)
 | |
|         ]
 | |
|         self.challenges = [
 | |
|             Challenge.objects.create(name=f'Challenge {i}', description='', points=50) for i in range(3)
 | |
|         ]
 | |
| 
 | |
|         self.achievement = Achievement.objects.create(
 | |
|             family=self.families[0],
 | |
|             challenge=self.challenges[0],
 | |
|             valid=False,
 | |
|         )
 | |
| 
 | |
|         self.url = reverse("family:api:batch_achievements")
 | |
| 
 | |
|     def test_batch_achievement_creation(self):
 | |
|         family_ids = [f.id for f in self.families]
 | |
|         challenge_ids = [c.id for c in self.challenges]
 | |
|         response = self.client.post(
 | |
|             self.url,
 | |
|             data={
 | |
|                 'families': family_ids,
 | |
|                 'challenges': challenge_ids
 | |
|             },
 | |
|             format='json'
 | |
|         )
 | |
| 
 | |
|         self.assertEqual(response.status_code, 201)
 | |
|         for result in response.data['results']:
 | |
|             if result['family'] == self.families[0].name and result['challenge'] == self.challenges[0].name:
 | |
|                 self.assertEqual(result['status'], 'existed')
 | |
|             else:
 | |
|                 self.assertEqual(result['status'], 'created')
 | |
| 
 | |
|         expected_count = len(family_ids) * len(challenge_ids)
 | |
|         self.assertEqual(Achievement.objects.count(), expected_count)
 | |
| 
 | |
|         # Check that correct couples family/challenge exist
 | |
|         for f in self.families:
 | |
|             for c in self.challenges:
 | |
|                 self.assertTrue(
 | |
|                     Achievement.objects.filter(family=f, challenge=c).exists()
 | |
|                 )
 | |
| 
 | |
| 
 | |
| class TestFamilyAPI(TestAPI):
 | |
|     def setUp(self):
 | |
|         super().setUp()
 | |
| 
 | |
|         self.family = Family.objects.create(
 | |
|             name='Test family',
 | |
|             description='',
 | |
|         )
 | |
| 
 | |
|         self.familymembership = FamilyMembership.objects.create(
 | |
|             user=self.user,
 | |
|             family=self.family,
 | |
|         )
 | |
| 
 | |
|         self.challenge = Challenge.objects.create(
 | |
|             name='Test challenge',
 | |
|             description='',
 | |
|             points=100,
 | |
|         )
 | |
| 
 | |
|         self.achievement = Achievement.objects.create(
 | |
|             family=self.family,
 | |
|             challenge=self.challenge,
 | |
|             valid=False,
 | |
|         )
 | |
| 
 | |
|     def test_family_api(self):
 | |
|         """
 | |
|         Load Family API page and test all filters and permissions
 | |
|         """
 | |
|         self.check_viewset(FamilyViewSet, '/api/family/family/')
 | |
| 
 | |
|     def test_familymembership_api(self):
 | |
|         """
 | |
|         Load FamilyMembership API page and test all filters and permissions
 | |
|         """
 | |
|         self.check_viewset(FamilyMembershipViewSet, '/api/family/familymembership/')
 | |
| 
 | |
|     def test_challenge_api(self):
 | |
|         """
 | |
|         Load Challenge API page and test all filters and permissions
 | |
|         """
 | |
|         self.check_viewset(ChallengeViewSet, '/api/family/challenge/')
 | |
| 
 | |
|     def test_achievement_api(self):
 | |
|         """
 | |
|         Load Achievement API page and test all filters and permissions
 | |
|         """
 | |
|         self.check_viewset(AchievementViewSet, '/api/family/achievement/')
 |