Unraid deployment fixes and generator improvements
- Add Next.js rewrites to proxy API calls through same origin (fixes login/media on werkout.treytartt.com) - Fix mediaUrl() in DayCard and ExerciseRow to use relative paths in production - Add proxyTimeout for long-running workout generation endpoints - Add CSRF trusted origin for treytartt.com - Split docker-compose into production (Unraid) and dev configs - Show display_name and descriptions on workout type cards - Generator: rules engine improvements, movement enforcement, exercise selector updates - Add new test files for rules drift, workout research generation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
56
generator/tests/test_check_rules_drift.py
Normal file
56
generator/tests/test_check_rules_drift.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase
|
||||
|
||||
from generator.models import WorkoutType
|
||||
from generator.rules_engine import DB_CALIBRATION
|
||||
|
||||
|
||||
class TestCheckRulesDriftCommand(TestCase):
|
||||
"""Tests for the strict drift-check command behavior."""
|
||||
|
||||
@staticmethod
|
||||
def _sync_workout_type(name, values):
|
||||
wt, _ = WorkoutType.objects.get_or_create(
|
||||
name=name,
|
||||
defaults={
|
||||
'display_name': name.replace('_', ' ').title(),
|
||||
'description': f'Calibrated {name}',
|
||||
**values,
|
||||
},
|
||||
)
|
||||
update_fields = []
|
||||
for field_name, field_value in values.items():
|
||||
if getattr(wt, field_name) != field_value:
|
||||
setattr(wt, field_name, field_value)
|
||||
update_fields.append(field_name)
|
||||
if update_fields:
|
||||
wt.save(update_fields=update_fields)
|
||||
return wt
|
||||
|
||||
def test_passes_when_all_types_match(self):
|
||||
for type_name, values in DB_CALIBRATION.items():
|
||||
self._sync_workout_type(type_name, values)
|
||||
|
||||
# Should not raise SystemExit when everything matches.
|
||||
call_command('check_rules_drift', verbosity=0)
|
||||
|
||||
def test_fails_when_type_missing(self):
|
||||
for type_name, values in DB_CALIBRATION.items():
|
||||
self._sync_workout_type(type_name, values)
|
||||
WorkoutType.objects.filter(name='cardio').delete()
|
||||
|
||||
with self.assertRaises(SystemExit) as ctx:
|
||||
call_command('check_rules_drift', verbosity=0)
|
||||
self.assertEqual(ctx.exception.code, 1)
|
||||
|
||||
def test_fails_when_value_mismatch(self):
|
||||
for type_name, values in DB_CALIBRATION.items():
|
||||
self._sync_workout_type(type_name, values)
|
||||
|
||||
target = WorkoutType.objects.get(name='hypertrophy')
|
||||
target.typical_rest_between_sets = 999
|
||||
target.save(update_fields=['typical_rest_between_sets'])
|
||||
|
||||
with self.assertRaises(SystemExit) as ctx:
|
||||
call_command('check_rules_drift', verbosity=0)
|
||||
self.assertEqual(ctx.exception.code, 1)
|
||||
Reference in New Issue
Block a user