from django.http import QueryDict from workouts.forms import WorkoutSetsField, WorkoutSetsWidget from workouts.models import WorkoutLogData from workouts.utils import lbs_to_kg def build_post_data(exercise_id, rows): qd = QueryDict("", mutable=True) qd.setlist("workouts_exercise_id", [str(r["exercise_id"]) for r in rows]) qd.setlist("workouts_sets", [str(r.get("sets") or "") for r in rows]) qd.setlist("workouts_reps", [str(r.get("reps") or "") for r in rows]) qd.setlist("workouts_weight", [str(r.get("weight") or "") for r in rows]) qd.setlist("workouts_notes", [r.get("notes") or "" for r in rows]) return qd class TestWorkoutSetsField: def field_value(self, field, qd): return field.widget.value_from_datadict(qd, {}, "workouts") def test_clean_metric(self, exercise): field = WorkoutSetsField(units="metric") qd = build_post_data( exercise.id, [{"exercise_id": exercise.id, "sets": 3, "reps": 10, "weight": 50}], ) result = field.clean(self.field_value(field, qd)) assert result[0]["exercise_id"] == exercise.id assert result[0]["sets"] == 3 assert result[0]["reps"] == 10 assert result[0]["weight_kg"] == 50.0 def test_clean_imperial(self, exercise): field = WorkoutSetsField(units="imperial") qd = build_post_data( exercise.id, [{"exercise_id": exercise.id, "sets": 3, "reps": 10, "weight": 45}], ) result = field.clean(self.field_value(field, qd)) assert result[0]["weight_kg"] == lbs_to_kg(45) def test_clean_empty(self, exercise): field = WorkoutSetsField(units="metric") qd = build_post_data( exercise.id, [{"exercise_id": "", "sets": "", "reps": "", "weight": ""}] ) assert field.clean(self.field_value(field, qd)) is None def test_clean_missing_exercise(self, exercise): field = WorkoutSetsField(units="metric") qd = build_post_data( exercise.id, [{"exercise_id": "", "sets": 3, "reps": 10, "weight": 50}], ) assert field.clean(self.field_value(field, qd)) is None class TestWorkoutLogDataForm: def test_form_valid_metric(self, exercise): form = WorkoutLogData.form()( build_post_data( exercise.id, [ {"exercise_id": exercise.id, "sets": 4, "reps": 8, "weight": 45}, { "exercise_id": exercise.id, "sets": 3, "reps": 12, "weight": 30, "notes": "drop set", }, ], ) ) WorkoutLogData.prepare_form(form, "metric") assert form.is_valid(), form.errors data = form.cleaned_data assert data["workouts"][0]["sets"] == 4 assert data["workouts"][0]["weight_kg"] == 45.0 assert data["workouts"][1]["notes"] == "drop set" def test_form_valid_imperial(self, exercise): form = WorkoutLogData.form()( build_post_data( exercise.id, [{"exercise_id": exercise.id, "sets": 3, "reps": 10, "weight": 100}], ) ) WorkoutLogData.prepare_form(form, "imperial") assert form.is_valid(), form.errors data = form.cleaned_data assert data["workouts"][0]["weight_kg"] == lbs_to_kg(100) def test_form_bodyweight_imperial(self): qd = QueryDict("", mutable=True) qd["bodyweight_kg"] = "180.5" form = WorkoutLogData.form()(qd) WorkoutLogData.prepare_form(form, "imperial") assert form.is_valid(), form.errors data = form.cleaned_data.copy() WorkoutLogData.normalize_form_data(data, "imperial") assert data["bodyweight_kg"] == lbs_to_kg(180.5) class TestWorkoutSetsWidget: def test_value_from_datadict(self, exercise): widget = WorkoutSetsWidget() qd = build_post_data( exercise.id, [{"exercise_id": exercise.id, "sets": 3, "reps": 10, "weight": 50}], ) value = widget.value_from_datadict(qd, {}, "workouts") assert value["exercise_id"] == [str(exercise.id)] assert value["weight"] == ["50"]