Codebase hardening: 102 fixes across 35+ files
Deep audit identified 106 findings; 102 fixed, 4 deferred. Covers 8 areas: - Settings & deploy: env-gated DEBUG/SECRET_KEY, HTTPS headers, gunicorn, celery worker - Auth (registered_user): password write_only, request.data fixes, transaction safety, proper HTTP status codes - Workout app: IDOR protection, get_object_or_404, prefetch_related N+1 fixes, transaction.atomic - Video/scripts: path traversal sanitization, HLS trigger guard, auth on cache wipe - Models (exercise/equipment/muscle/superset): null-safe __str__, stable IDs, prefetch support - Generator views: helper for registered_user lookup, logger.exception, bulk_update, transaction wrapping - Generator core (rules/selector/generator): push-pull ratio, type affinity normalization, modality checks, side-pair exact match, word-boundary regex, equipment cache clearing - Generator services (plan_builder/analyzer/normalizer): transaction.atomic, muscle cache, bulk_update, glutes classification fix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,18 @@ class MovementEnforcementTestBase(TestCase):
|
||||
superset_size_min=3,
|
||||
superset_size_max=6,
|
||||
)
|
||||
cls.functional_type, _ = WorkoutType.objects.get_or_create(
|
||||
name='functional_strength_training',
|
||||
defaults={
|
||||
'typical_rest_between_sets': 60,
|
||||
'typical_intensity': 'high',
|
||||
'rep_range_min': 6,
|
||||
'rep_range_max': 12,
|
||||
'duration_bias': 0.2,
|
||||
'superset_size_min': 2,
|
||||
'superset_size_max': 4,
|
||||
},
|
||||
)
|
||||
cls.core_type = WorkoutType.objects.filter(name='core_training').first()
|
||||
if cls.core_type is None:
|
||||
cls.core_type = WorkoutType.objects.create(
|
||||
@@ -184,6 +196,54 @@ class TestMovementPatternEnforcement(MovementEnforcementTestBase):
|
||||
|
||||
pref.delete()
|
||||
|
||||
def test_working_superset_filters_stretch_entries_and_keeps_positive_rest(self):
|
||||
"""Working supersets should never keep static stretch entries."""
|
||||
pref = self._make_preference()
|
||||
gen = self._make_generator(pref)
|
||||
|
||||
valid = self._create_mock_exercise(
|
||||
name='Barbell Clean Pull',
|
||||
movement_patterns='upper pull,hip hinge',
|
||||
is_duration=False,
|
||||
is_reps=True,
|
||||
is_weight=True,
|
||||
is_compound=True,
|
||||
)
|
||||
stretch = self._create_mock_exercise(
|
||||
name='Supine Pec Stretch - T',
|
||||
movement_patterns='mobility - static, static stretch, cool down',
|
||||
is_duration=True,
|
||||
is_reps=False,
|
||||
is_weight=False,
|
||||
is_compound=False,
|
||||
exercise_tier='accessory',
|
||||
)
|
||||
|
||||
gen.exercise_selector.select_exercises.return_value = [valid, stretch]
|
||||
gen.exercise_selector.balance_stretch_positions.return_value = [valid, stretch]
|
||||
|
||||
muscle_split = {
|
||||
'muscles': ['chest', 'upper back'],
|
||||
'split_type': 'upper',
|
||||
'label': 'Upper',
|
||||
}
|
||||
wt_params = dict(WORKOUT_TYPE_DEFAULTS['functional strength'])
|
||||
wt_params['num_supersets'] = (1, 1)
|
||||
wt_params['exercises_per_superset'] = (2, 2)
|
||||
wt_params['rounds'] = (4, 4)
|
||||
|
||||
supersets = gen._build_working_supersets(
|
||||
muscle_split, self.functional_type, wt_params,
|
||||
)
|
||||
self.assertTrue(supersets, 'Expected at least one working superset.')
|
||||
ss = supersets[0]
|
||||
exercise_names = [e['exercise'].name for e in ss.get('exercises', [])]
|
||||
|
||||
self.assertIn('Barbell Clean Pull', exercise_names)
|
||||
self.assertNotIn('Supine Pec Stretch - T', exercise_names)
|
||||
self.assertGreater(ss.get('rest_between_rounds', 0), 0)
|
||||
pref.delete()
|
||||
|
||||
def test_retries_when_superset_has_duplicate_focus(self):
|
||||
"""Generator should retry when a working superset repeats focus family."""
|
||||
pref = self._make_preference()
|
||||
@@ -992,3 +1052,49 @@ class TestFinalConformance(MovementEnforcementTestBase):
|
||||
self.assertIsInstance(workout, dict)
|
||||
self.assertEqual(gen._build_working_supersets.call_count, 1)
|
||||
pref.delete()
|
||||
|
||||
def test_side_pair_warning_filtered_when_final_workout_has_no_side_entries(self):
|
||||
"""Do not surface side-pair warnings when final workout has no sided exercises."""
|
||||
pref = self._make_preference()
|
||||
gen = self._make_generator(pref)
|
||||
|
||||
gen._build_warmup = MagicMock(return_value=None)
|
||||
gen._build_cooldown = MagicMock(return_value=None)
|
||||
gen._check_quality_gates = MagicMock(return_value=[])
|
||||
gen._adjust_to_time_target = MagicMock(side_effect=lambda spec, *_args, **_kwargs: spec)
|
||||
|
||||
ex = self._create_mock_exercise('Compound Lift', movement_patterns='upper pull')
|
||||
ex.side = ''
|
||||
gen._build_working_supersets = MagicMock(return_value=[
|
||||
{
|
||||
'name': 'Working Set 1',
|
||||
'rounds': 3,
|
||||
'rest_between_rounds': 45,
|
||||
'modality': 'reps',
|
||||
'exercises': [{'exercise': ex, 'reps': 8, 'order': 1}],
|
||||
},
|
||||
])
|
||||
gen._get_final_conformance_violations = MagicMock(return_value=[])
|
||||
gen.exercise_selector.warnings = [
|
||||
'Added 2 missing opposite-side exercise partners.',
|
||||
'Removed 1 unpaired side-specific exercises to enforce left/right pairing.',
|
||||
'Could only find 3/5 exercises for deltoids.',
|
||||
]
|
||||
|
||||
gen.generate_single_workout(
|
||||
muscle_split={
|
||||
'muscles': ['upper back'],
|
||||
'split_type': 'pull',
|
||||
'label': 'Pull Day',
|
||||
},
|
||||
workout_type=self.strength_type,
|
||||
scheduled_date=date(2026, 3, 6),
|
||||
)
|
||||
|
||||
self.assertTrue(
|
||||
any('Could only find 3/5 exercises for deltoids.' in w for w in gen.warnings)
|
||||
)
|
||||
self.assertFalse(
|
||||
any('opposite-side' in w.lower() or 'side-specific' in w.lower() for w in gen.warnings)
|
||||
)
|
||||
pref.delete()
|
||||
|
||||
Reference in New Issue
Block a user