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 TestExerciseSimilarityDedup(TestCase): def setUp(self): django_user = User.objects.create_user( username='similarity_dedup_user', password='testpass123', ) registered_user = RegisteredUser.objects.create( user=django_user, first_name='Similarity', last_name='Dedup', ) self.preference = UserPreference.objects.create( registered_user=registered_user, days_per_week=4, fitness_level=2, ) def test_hard_similarity_blocks_near_identical_working_exercise(self): selector = ExerciseSelector(self.preference) prior = Exercise.objects.create( name='Posterior Chain Pull Alpha', movement_patterns='lower pull, lower pull - hip hinge', muscle_groups='glutes,hamstrings,traps', equipment_required='barbell', is_reps=True, is_duration=False, is_weight=True, is_compound=True, difficulty_level='intermediate', ) candidate = Exercise.objects.create( name='Posterior Chain Pull Beta', movement_patterns='lower pull, lower pull - hip hinge', muscle_groups='glutes,hamstrings,traps', equipment_required='barbell', is_reps=True, is_duration=False, is_weight=True, is_compound=True, difficulty_level='intermediate', ) selector.used_working_similarity_profiles.append( selector._build_similarity_profile(prior) ) selected = selector._weighted_pick( Exercise.objects.filter(pk=candidate.pk), Exercise.objects.none(), count=1, similarity_scope='working', ) self.assertEqual( selected, [], 'Near-identical exercise should be hard-blocked in same workout.', ) def test_soft_similarity_blocks_adjacent_superset_repetition(self): selector = ExerciseSelector(self.preference) previous_set_ex = Exercise.objects.create( name='Hip Hinge Pattern Alpha', movement_patterns='lower pull, lower pull - hip hinge, core', muscle_groups='glutes,hamstrings,core', equipment_required='barbell', is_reps=True, is_duration=False, is_weight=True, is_compound=True, difficulty_level='intermediate', ) adjacent_candidate = Exercise.objects.create( name='Hip Hinge Pattern Beta', movement_patterns='lower pull - hip hinge, core', muscle_groups='glutes,hamstrings,core', equipment_required='barbell', is_reps=True, is_duration=False, is_weight=True, is_compound=True, difficulty_level='intermediate', ) selector.last_working_similarity_profiles = [ selector._build_similarity_profile(previous_set_ex) ] selected = selector._weighted_pick( Exercise.objects.filter(pk=adjacent_candidate.pk), Exercise.objects.none(), count=1, similarity_scope='working', ) self.assertEqual( selected, [], 'Very similar adjacent-set exercise should be soft-blocked.', ) def test_dissimilar_exercise_is_allowed(self): selector = ExerciseSelector(self.preference) previous_set_ex = Exercise.objects.create( name='Posterior Chain Pull Alpha', movement_patterns='lower pull, lower pull - hip hinge, core', muscle_groups='glutes,hamstrings,core', equipment_required='barbell', is_reps=True, is_duration=False, is_weight=True, is_compound=True, difficulty_level='intermediate', ) different_candidate = Exercise.objects.create( name='Horizontal Push Builder', movement_patterns='upper push - horizontal, upper push', muscle_groups='chest,triceps,deltoids', equipment_required='dumbbell', is_reps=True, is_duration=False, is_weight=True, is_compound=True, difficulty_level='intermediate', ) selector.last_working_similarity_profiles = [ selector._build_similarity_profile(previous_set_ex) ] selected = selector._weighted_pick( Exercise.objects.filter(pk=different_candidate.pk), Exercise.objects.none(), count=1, similarity_scope='working', ) self.assertEqual(len(selected), 1) self.assertEqual(selected[0].pk, different_candidate.pk)