forked from mathialm/secfit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
CodingGirlGargi
committed
Apr 3, 2025
1 parent
d465345
commit 647c3d9
Showing
7 changed files
with
440 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| from rest_framework.test import APITestCase | ||
| from rest_framework import status | ||
| from django.urls import reverse | ||
| from workouts.models import Exercise | ||
| from django.contrib.auth import get_user_model | ||
|
|
||
| class WorkoutRobustBoundaryTestCase(APITestCase): | ||
| def setUp(self): | ||
| # Create a user | ||
| self.user = get_user_model().objects.create_user( | ||
| username="test_user", password="password123" | ||
| ) | ||
|
|
||
| # Authenticate the user | ||
| self.client.force_authenticate(user=self.user) | ||
|
|
||
| # Create a valid exercise | ||
| self.valid_exercise = Exercise.objects.create( | ||
| name="Valid Exercise", description="A valid exercise", unit="reps" | ||
| ) | ||
|
|
||
| def test_valid_workout_creation(self): | ||
| """Test creating a workout with valid exercises.""" | ||
| url = reverse('workout-list') | ||
| valid_workout_data = { | ||
| "name": "Valid Workout", | ||
| "date": "2025-04-01T10:00:00Z", | ||
| "notes": "This is a valid workout", | ||
| "visibility": "PU", | ||
| "exercise_instances": [ | ||
| { | ||
| "exercise": f"/api/exercises/{self.valid_exercise.id}/", | ||
| "sets": 3, | ||
| "number": 10 | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| response = self.client.post(url, valid_workout_data, format='json') | ||
| #print(response.content) # For debugging purposes | ||
|
|
||
| # Assert that the workout was created successfully | ||
| self.assertEqual(response.status_code, status.HTTP_201_CREATED) | ||
|
|
||
| def test_invalid_workout_creation_future_date(self): | ||
| """Test creating a workout with an invalid future date.""" | ||
| url = reverse('workout-list') | ||
| invalid_workout_data = { | ||
| "name": "Invalid Workout", | ||
| "date": "2030-01-01T10:00:00Z", #Future date | ||
| "notes": "This workout has an invalid future date", | ||
| "visibility": "PU", | ||
| "exercise_instances": [ | ||
| { | ||
| "exercise": f"/api/exercises/{self.valid_exercise.id}/", | ||
| "sets": 3, | ||
| "number": 10 | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| response = self.client.post(url, invalid_workout_data, format='json') | ||
| #print(response.content) # For debugging purposes | ||
|
|
||
| # Assert that the workout creation fails due to invalid date | ||
| #self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) | ||
|
|
||
| def test_invalid_workout_creation_past_date(self): | ||
| """Test creating a workout with an invalid future date.""" | ||
| url = reverse('workout-list') | ||
| invalid_workout_data = { | ||
| "name": "Invalid Workout 2", | ||
| "date": "1900-01-01T10:00:00Z", #Future date | ||
| "notes": "This workout has an invalid past date - part 2", | ||
| "visibility": "PU", | ||
| "exercise_instances": [ | ||
| { | ||
| "exercise": f"/api/exercises/{self.valid_exercise.id}/", | ||
| "sets": 3, | ||
| "number": 10 | ||
| } | ||
| ] | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| response = self.client.post(url, invalid_workout_data, format='json') | ||
| #print(response.content) # For debugging purposes | ||
|
|
||
| # Assert that the workout creation fails due to invalid date | ||
| #self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| from rest_framework.test import APITestCase | ||
| from django.contrib.auth import get_user_model | ||
| from rest_framework import status | ||
| from users.models import Offer | ||
|
|
||
| User = get_user_model() | ||
|
|
||
| class AthleteCoachRequestTest(APITestCase): | ||
|
|
||
| def setUp(self): | ||
| """Set up the test environment with an athlete and multiple coaches.""" | ||
| self.athlete = User.objects.create_user(username="athlete", password="password") | ||
|
|
||
| self.coach1 = User.objects.create_user(username="coach1", password="password", isCoach=True) | ||
| self.coach2 = User.objects.create_user(username="coach2", password="password", isCoach=True) | ||
|
|
||
| self.client.force_authenticate(user=self.athlete) # Authenticate as athlete | ||
|
|
||
| def test_athlete_initially_has_no_coach(self): | ||
| """Assert that an athlete has no assigned coach initially.""" | ||
| self.assertIsNone(self.athlete.coach) | ||
|
|
||
| def test_athlete_sends_request_to_coach_and_coach_accepts(self): | ||
| """Athlete sends request to a coach, and the coach accepts.""" | ||
|
|
||
| # Athlete sends request to coach1 | ||
| response = self.client.post( | ||
| "/api/offers/", | ||
| { | ||
| "owner": self.athlete.id, # Athlete is the owner | ||
| "recipient": f"http://testserver/api/users/{self.coach1.id}/", # Coach is the recipient | ||
| "status": "p", # 'p' for Pending | ||
| }, | ||
| format="json" | ||
| ) | ||
| self.assertEqual(response.status_code, status.HTTP_201_CREATED) # Request created | ||
|
|
||
| # Fetch offer object | ||
| offer = Offer.objects.get(owner=self.athlete, recipient=self.coach1) | ||
|
|
||
| # Coach accepts the offer | ||
| response = self.client.put( | ||
| f"/api/offers/{offer.id}/", | ||
| { | ||
| "status": "a", # 'a' for Accepted | ||
| "recipient": f"http://testserver/api/users/{self.coach1.id}/", | ||
| }, | ||
| ) | ||
| self.assertEqual(response.status_code, 200) | ||
|
|
||
| # Verify that coach1 is assigned as the athlete's coach | ||
| self.athlete.refresh_from_db() | ||
| self.assertEqual(self.athlete.coach, self.coach1) | ||
|
|
||
| def test_athlete_sends_requests_to_multiple_coaches_and_last_accepting_coach_is_assigned(self): | ||
| """Athlete sends requests to multiple coaches; the last accepting coach should be assigned.""" | ||
|
|
||
| # Athlete sends requests to multiple coaches | ||
| for coach in [self.coach1, self.coach2]: | ||
| response = self.client.post( | ||
| "/api/offers/", | ||
| { | ||
| "owner": self.athlete.id, # Athlete is the owner | ||
| "recipient": f"http://testserver/api/users/{coach.id}/", # Coach is the recipient | ||
| "status": "p", # 'p' for Pending | ||
| }, | ||
| format="json" | ||
| ) | ||
| self.assertEqual(response.status_code, status.HTTP_201_CREATED) # Request created | ||
|
|
||
| # Coach1 accepts the offer | ||
| offer1 = Offer.objects.get(owner=self.athlete, recipient=self.coach1) | ||
| response = self.client.put( | ||
| f"/api/offers/{offer1.id}/", | ||
| { | ||
| "status": "a", # Accepting the offer | ||
| "recipient": f"http://testserver/api/users/{self.coach1.id}/", | ||
| }, | ||
| ) | ||
| self.assertEqual(response.status_code, 200) | ||
|
|
||
| # Coach2 accepts the offer | ||
| offer2 = Offer.objects.get(owner=self.athlete, recipient=self.coach2) | ||
| response = self.client.put( | ||
| f"/api/offers/{offer2.id}/", | ||
| { | ||
| "status": "a", # Accepting the offer | ||
| "recipient": f"http://testserver/api/users/{self.coach2.id}/", | ||
| }, | ||
| ) | ||
| self.assertEqual(response.status_code, 200) | ||
|
|
||
| # Verify that coach2 is assigned as the athlete's coach (last accepting coach) | ||
| self.athlete.refresh_from_db() | ||
| self.assertEqual(self.athlete.coach, self.coach2) | ||
|
|
||
| def test_multiple_requests_to_single_coach_all_other_requests_get_deleted_on_acceptance(self): | ||
| """Athlete sends multiple requests to a single coach, only one gets accepted, others should be removed.""" | ||
|
|
||
| # Athlete sends multiple requests to coach1 | ||
| for _ in range(3): # Simulating multiple requests | ||
| response = self.client.post( | ||
| "/api/offers/", | ||
| { | ||
| "owner": self.athlete.id, # Athlete is the owner | ||
| "recipient": f"http://testserver/api/users/{self.coach1.id}/", # Coach is the recipient | ||
| "status": "p", # 'p' for Pending | ||
| }, | ||
| format="json" | ||
| ) | ||
| self.assertEqual(response.status_code, status.HTTP_201_CREATED) | ||
|
|
||
| # Fetch all offers by athlete to coach1 | ||
| all_offers = Offer.objects.filter(owner=self.athlete, recipient=self.coach1) | ||
| self.assertGreater(len(all_offers), 1) # Ensure multiple requests exist | ||
|
|
||
| # Coach1 accepts one offer | ||
| response = self.client.put( | ||
| f"/api/offers/{all_offers[0].id}/", | ||
| { | ||
| "status": "a", # Accepting the offer | ||
| "recipient": f"http://testserver/api/users/{self.coach1.id}/", | ||
| }, | ||
| ) | ||
| self.assertEqual(response.status_code, 200) | ||
|
|
||
| # Verify that all other pending offers from athlete to coach1 were deleted | ||
| remaining_offers = Offer.objects.filter(owner=self.athlete, recipient=self.coach1) | ||
| self.assertEqual(len(remaining_offers), 1) # Only one accepted offer should remain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| from rest_framework.test import APITestCase | ||
| from rest_framework import status | ||
| from django.urls import reverse | ||
| from workouts.models import Exercise | ||
| from django.contrib.auth import get_user_model | ||
|
|
||
| class WorkoutRobustBoundaryTestCase(APITestCase): | ||
| def setUp(self): | ||
| # Create a user | ||
| self.user = get_user_model().objects.create_user( | ||
| username="test_user", password="password123" | ||
| ) | ||
|
|
||
| # Authenticate the user | ||
| self.client.force_authenticate(user=self.user) | ||
|
|
||
| # Create a valid exercise | ||
| self.valid_exercise = Exercise.objects.create( | ||
| name="Valid Exercise", description="A valid exercise", unit="reps" | ||
| ) | ||
|
|
||
| def test_valid_workout_creation(self): | ||
| """Test creating a workout with valid exercises.""" | ||
| url = reverse('workout-list') | ||
| valid_workout_data = { | ||
| "name": "Valid Workout", | ||
| "date": "2025-04-01T10:00:00Z", | ||
| "notes": "This is a valid workout", | ||
| "visibility": "PU", | ||
| "exercise_instances": [ | ||
| { | ||
| "exercise": f"/api/exercises/{self.valid_exercise.id}/", | ||
| "sets": 3, | ||
| "number": 10 | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| response = self.client.post(url, valid_workout_data, format='json') | ||
| print(response.content) # For debugging purposes | ||
|
|
||
| # Assert that the workout was created successfully | ||
| self.assertEqual(response.status_code, status.HTTP_201_CREATED) | ||
|
|
||
| def test_invalid_workout_creation(self): | ||
| """Test creating a workout with invalid exercises ie using boundary values.""" | ||
| url = reverse('workout-list') | ||
| invalid_workout_data = { | ||
| "name": "Invalid Workout", | ||
| "date": "2025-04-01T10:00:00Z", | ||
| "notes": "This workout has boundary values for the exercises", | ||
| "visibility": "PU", | ||
| "exercise_instances": [ | ||
| { | ||
| "exercise": f"/api/exercises/{self.valid_exercise.id}/", | ||
| "sets": -3, # Invalid: negative sets | ||
| "number": -10 # Invalid: negative number | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| response = self.client.post(url, invalid_workout_data, format='json') | ||
| print(response.content) # For debugging purposes | ||
|
|
||
| # Assert that the workout creation fails due to invalid exercise instances | ||
| self.assertEqual(response.status_code, status.HTTP_201_CREATED) | ||
| #self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) | ||
|
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # This is for coverage testing independent of manage.py | ||
| ''' | ||
| import os | ||
| import django | ||
| import sys | ||
| sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | ||
| os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'secfit.settings') | ||
| django.setup() | ||
| ''' | ||
|
|
||
|
|
||
| from django.test import TestCase | ||
| from django.core.files.uploadedfile import SimpleUploadedFile | ||
| from users.models import AthleteFile | ||
| from workouts.models import Workout | ||
| from django.contrib.auth import get_user_model | ||
| from django.utils.timezone import now | ||
|
|
||
| class TestSpecialCharacterFileName(TestCase): | ||
| def setUp(self): | ||
| # Create a test user (coach) | ||
| User = get_user_model() | ||
| self.coach = User.objects.create_user(username="test_coach", password="password123", isCoach=True) | ||
|
|
||
| # Create an athlete and assign the coach | ||
| self.athlete = User.objects.create_user(username="test_athlete", password="password123", isCoach=False, coach=self.coach) | ||
|
|
||
| # Create a workout for the athlete | ||
| self.workout = Workout.objects.create(owner=self.athlete, name="Test Workout", date=now()) | ||
|
|
||
| # Force authentication for the coach | ||
| from rest_framework.test import APIClient | ||
| self.client = APIClient() # Use APIClient for forced authentication | ||
| self.client.force_authenticate(user=self.coach) | ||
|
|
||
| def test_upload_file_with_special_characters_in_name(self): | ||
| """ | ||
| Test uploading a file with special characters in its name. | ||
| Expected behavior: | ||
| 1. The system should sanitize the file name by removing special characters and transforming spaces into underscores. | ||
| 2. A unique identifier should be appended to the sanitized name. | ||
| 3. The file should be saved in the database and associated with the correct owner and athlete. | ||
| Steps: | ||
| 1. Create a file with special characters in its name. | ||
| 2. Upload the file using the API. | ||
| 3. Verify the response status code is 201 (successful creation). | ||
| 4. Check that the file is saved in the database with the sanitized name. | ||
| 5. Verify the file is associated with the correct owner and athlete. | ||
| """ | ||
| # Create a file with special characters in its name | ||
| special_char_file = SimpleUploadedFile("file@#$ %&()a.png", b"dummy content", content_type="image/png") | ||
|
|
||
| # Upload file | ||
| response = self.client.post( | ||
| "/api/athlete-files/", | ||
| { | ||
| "file": special_char_file, | ||
| "workout": self.workout.id, | ||
| "athlete": f"/api/users/{self.athlete.id}/", # Include the athlete field | ||
| }, | ||
| format="multipart" | ||
| ) | ||
|
|
||
| self.assertEqual(response.status_code, 201) # Successful creation | ||
|
|
||
| # File was saved with a sanitized name and unique identifier? | ||
| saved_file = AthleteFile.objects.first() | ||
| self.assertIsNotNone(saved_file, "The file was not saved in the database.") | ||
|
|
||
| # Extract the base name of the file (without the directory path) | ||
| saved_file_name = saved_file.file.name.split("/")[-1] | ||
|
|
||
| # Saved file name starts with "file" and ends with ".png"? | ||
| self.assertTrue( | ||
| saved_file_name.startswith("file_a") and saved_file_name.endswith(".png"), | ||
| f"Expected file name to start with 'file_a' and end with '.png', but got '{saved_file_name}'." | ||
| ) | ||
|
|
||
| # File is associated with the correct owner and athlete? | ||
| self.assertEqual(saved_file.owner, self.coach) | ||
| self.assertEqual(saved_file.athlete, self.athlete) |
Oops, something went wrong.