from django.contrib.auth.models import User from django.test import TestCase from exercise.models import Exercise from generator.models import UserPreference from generator.services.exercise_selector import ExerciseSelector from registered_user.models import RegisteredUser class TestWarmupSelector(TestCase): def setUp(self): django_user = User.objects.create_user( username='warmup_selector_user', password='testpass123', ) registered_user = RegisteredUser.objects.create( user=django_user, first_name='Warmup', last_name='Tester', ) self.preference = UserPreference.objects.create( registered_user=registered_user, days_per_week=4, fitness_level=2, ) def test_warmup_excludes_working_set_movements(self): dynamic_1 = Exercise.objects.create( name='Dynamic Warmup A', movement_patterns='dynamic stretch, mobility - dynamic, activation, warm up', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=2, complexity_rating=2, difficulty_level='beginner', ) dynamic_2 = Exercise.objects.create( name='Dynamic Warmup B', movement_patterns='mobility - dynamic, cardio/locomotion, balance', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=3, complexity_rating=2, difficulty_level='beginner', ) weighted_press = Exercise.objects.create( name='Lying Dumbbell Tricep Extension', movement_patterns='upper push - horizontal, upper push, arms', is_duration=True, is_reps=False, is_weight=True, is_compound=False, exercise_tier='secondary', hr_elevation_rating=2, complexity_rating=2, difficulty_level='intermediate', ) duration_push = Exercise.objects.create( name='Floor Press Hold', movement_patterns='upper push - horizontal, upper push', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='secondary', hr_elevation_rating=2, complexity_rating=2, difficulty_level='intermediate', ) selector = ExerciseSelector(self.preference) selected = selector.select_warmup_exercises(target_muscles=[], count=4) selected_ids = {ex.pk for ex in selected} self.assertIn(dynamic_1.pk, selected_ids) self.assertIn(dynamic_2.pk, selected_ids) self.assertNotIn(weighted_press.pk, selected_ids) self.assertNotIn(duration_push.pk, selected_ids) def test_warmup_excludes_side_specific_variants(self): left_variant = Exercise.objects.create( name='Side Lying T Stretch', side='left_arm', movement_patterns='dynamic stretch, mobility - dynamic, warm up', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=2, complexity_rating=1, difficulty_level='beginner', ) right_variant = Exercise.objects.create( name='Side Lying T Stretch', side='right_arm', movement_patterns='dynamic stretch, mobility - dynamic, warm up', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=2, complexity_rating=1, difficulty_level='beginner', ) unsided_a = Exercise.objects.create( name='Worlds Greatest Stretch', side='', movement_patterns='dynamic stretch, mobility - dynamic, warm up', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=2, complexity_rating=1, difficulty_level='beginner', ) unsided_b = Exercise.objects.create( name='Hip Opener Flow', side='', movement_patterns='activation, warmup, cardio/locomotion', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=3, complexity_rating=2, difficulty_level='beginner', ) selector = ExerciseSelector(self.preference) selected = selector.select_warmup_exercises(target_muscles=[], count=2) selected_ids = {ex.pk for ex in selected} self.assertEqual(selected_ids, {unsided_a.pk, unsided_b.pk}) self.assertNotIn(left_variant.pk, selected_ids) self.assertNotIn(right_variant.pk, selected_ids) self.assertTrue(all(not (ex.side or '').strip() for ex in selected)) def test_cooldown_excludes_side_specific_variants(self): left_variant = Exercise.objects.create( name="Matsyendra's Pose", side='left_side', movement_patterns='static stretch, cool down', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=1, complexity_rating=1, difficulty_level='beginner', ) right_variant = Exercise.objects.create( name="Matsyendra's Pose", side='right_side', movement_patterns='static stretch, cool down', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=1, complexity_rating=1, difficulty_level='beginner', ) unsided_a = Exercise.objects.create( name='Butterfly Stretch', side='', movement_patterns='mobility - static, cooldown', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=1, complexity_rating=1, difficulty_level='beginner', ) unsided_b = Exercise.objects.create( name='Hamstring Reach', side='', movement_patterns='static stretch, cool down', is_duration=True, is_reps=False, is_weight=False, is_compound=False, exercise_tier='accessory', hr_elevation_rating=2, complexity_rating=1, difficulty_level='beginner', ) selector = ExerciseSelector(self.preference) selected = selector.select_cooldown_exercises(target_muscles=[], count=2) selected_ids = {ex.pk for ex in selected} self.assertEqual(selected_ids, {unsided_a.pk, unsided_b.pk}) self.assertNotIn(left_variant.pk, selected_ids) self.assertNotIn(right_variant.pk, selected_ids) self.assertTrue(all(not (ex.side or '').strip() for ex in selected))