Skip to content

Commit

Permalink
Applied all changes
Browse files Browse the repository at this point in the history
  • Loading branch information
CodingGirlGargi committed Apr 3, 2025
1 parent d465345 commit 647c3d9
Show file tree
Hide file tree
Showing 7 changed files with 440 additions and 0 deletions.
1 change: 1 addition & 0 deletions backend/media/users/2/file_a.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions backend/media/users/2/file_a_mT2Of3i.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions backend/tests/test_TC001.py
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)
129 changes: 129 additions & 0 deletions backend/tests/test_TC002.py
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
68 changes: 68 additions & 0 deletions backend/tests/test_TC003.py
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)

82 changes: 82 additions & 0 deletions backend/tests/test_TC004.py
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)
Loading

0 comments on commit 647c3d9

Please sign in to comment.