feat: history and calculate needs for user
CI / 🧪 Tests Laravel (push) Failing after 2m18s
CI / 🐳 Build & Push Images (push) Has been skipped

This commit is contained in:
2026-08-14 12:45:37 +02:00
parent ea5a5737ec
commit 69372a49ed
51 changed files with 2226 additions and 305 deletions
@@ -0,0 +1,70 @@
<?php
use App\Enums\PacePreference;
use App\Enums\PhysicalActivityLevel;
use App\Enums\UserSex;
use App\Enums\WeightGoal;
use App\Services\NutritionPlanCalculator;
use Carbon\CarbonImmutable;
beforeEach(function () {
CarbonImmutable::setTestNow('2026-08-14 10:00:00');
});
afterEach(function () {
CarbonImmutable::setTestNow();
});
it('calculates a reproducible maintenance plan', function () {
$plan = (new NutritionPlanCalculator)->calculate(
weightKg: 80,
heightCm: 180,
dateOfBirth: CarbonImmutable::parse('1996-08-14'),
sex: UserSex::MAN,
activityLevel: PhysicalActivityLevel::MODERATELY_ACTIVE,
weightGoal: WeightGoal::MAINTAIN_WEIGHT,
pacePreference: PacePreference::NORMAL,
);
expect($plan)
->formula_version->toBe('mifflin_st_jeor_v1')
->resting_metabolism->toBe(1780)
->maintenance_calories->toBe(2760)
->calorie_adjustment_percent->toBe(0.0)
->proteins->toBe(128)
->fats->toBe(77)
->carbs->toBe(389)
->calories->toBe(2761)
->and(($plan['proteins'] * 4) + ($plan['carbs'] * 4) + ($plan['fats'] * 9))
->toBe($plan['calories']);
});
it('applies bounded loss and gain adjustments', function (WeightGoal $goal, PacePreference $pace, float $expectedAdjustment) {
$plan = (new NutritionPlanCalculator)->calculate(
weightKg: 60,
heightCm: 165,
dateOfBirth: CarbonImmutable::parse('1990-01-01'),
sex: UserSex::WOMAN,
activityLevel: PhysicalActivityLevel::LIGHTLY_ACTIVE,
weightGoal: $goal,
pacePreference: $pace,
);
expect($plan['calorie_adjustment_percent'])->toBe($expectedAdjustment)
->and($plan['calories'])->toBeGreaterThanOrEqual(1200);
})->with([
'normal loss' => [WeightGoal::LOSE_WEIGHT, PacePreference::NORMAL, -0.15],
'fast gain' => [WeightGoal::GAIN_WEIGHT, PacePreference::FAST, 0.15],
]);
it('rejects a non binary metabolic calculation reference', function () {
(new NutritionPlanCalculator)->calculate(
weightKg: 70,
heightCm: 170,
dateOfBirth: CarbonImmutable::parse('1990-01-01'),
sex: UserSex::UNKNOWN,
activityLevel: PhysicalActivityLevel::SEDENTARY,
weightGoal: WeightGoal::MAINTAIN_WEIGHT,
pacePreference: PacePreference::SLOW,
);
})->throws(InvalidArgumentException::class);