Files
leonm 69372a49ed
CI / 🧪 Tests Laravel (push) Failing after 2m18s
CI / 🐳 Build & Push Images (push) Has been skipped
feat: history and calculate needs for user
2026-08-14 12:45:37 +02:00

133 lines
4.3 KiB
PHP

<?php
use App\Enums\PacePreference;
use App\Enums\WeeklyReviewStatus;
use App\Enums\WeightGoal;
use App\Models\MealPosts;
use App\Models\NutritionPlan;
use App\Models\User;
use Carbon\CarbonImmutable;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
uses(RefreshDatabase::class);
beforeEach(function () {
CarbonImmutable::setTestNow('2026-08-17 10:00:00');
});
afterEach(function () {
CarbonImmutable::setTestNow();
});
it('returns an insufficient data review without changing the plan', function () {
$user = User::factory()->create();
Sanctum::actingAs($user);
$this->getJson('/api/weekly-reviews/current')
->assertOk()
->assertJsonPath('data.periodStart', '2026-08-10')
->assertJsonPath('data.periodEnd', '2026-08-16')
->assertJsonPath('data.status', WeeklyReviewStatus::INSUFFICIENT_DATA->value)
->assertJsonPath('data.recommendedCalorieAdjustment', 0);
$this->assertDatabaseCount('nutrition_plans', 1);
});
it('proposes and applies a small confirmed adjustment', function () {
$user = User::factory()->create([
'weight_goal' => WeightGoal::LOSE_WEIGHT,
'pace_preference' => PacePreference::NORMAL,
]);
$user->weightEntries()->delete();
foreach ([
['2026-08-03 07:00:00', 70.0],
['2026-08-07 07:00:00', 69.98],
['2026-08-12 07:00:00', 69.95],
['2026-08-16 07:00:00', 69.90],
] as [$measuredAt, $weightKg]) {
$user->weightEntries()->create([
'weight_kg' => $weightKg,
'measured_at' => $measuredAt,
]);
}
foreach (range(10, 14) as $day) {
MealPosts::factory()->for($user, 'user')->create([
'calories' => 2200,
'proteins' => 112,
'carbs' => 286,
'fats' => 61,
'eaten_at' => "2026-08-{$day} 12:00:00",
]);
}
Sanctum::actingAs($user);
$reviewResponse = $this->getJson('/api/weekly-reviews/current')
->assertOk()
->assertJsonPath('data.status', WeeklyReviewStatus::ADJUSTMENT_RECOMMENDED->value)
->assertJsonPath('data.recommendedCalorieAdjustment', -100);
$reviewId = $reviewResponse->json('data.id');
$this->postJson("/api/weekly-reviews/{$reviewId}/accept")
->assertCreated()
->assertJsonPath('data.source', 'weekly_adjustment');
$this->assertDatabaseCount('nutrition_plans', 2);
$this->assertDatabaseHas('weekly_reviews', [
'id' => $reviewId,
'recommended_calorie_adjustment' => -100,
]);
expect($user->weeklyReviews()->findOrFail($reviewId)->accepted_at)->not->toBeNull();
});
it('does not allow accepting another users review', function () {
$user = User::factory()->create();
$otherUser = User::factory()->create();
$review = $otherUser->weeklyReviews()->create([
'period_start' => '2026-08-10',
'period_end' => '2026-08-16',
'status' => WeeklyReviewStatus::ADJUSTMENT_RECOMMENDED,
'recommended_calorie_adjustment' => -100,
'message_code' => 'WEEKLY_REVIEW_ADJUSTMENT',
'metrics' => [],
'generated_at' => now(),
]);
Sanctum::actingAs($user);
$this->postJson("/api/weekly-reviews/{$review->id}/accept")->assertNotFound();
});
it('rejects an adjustment generated for a plan that is no longer active', function () {
$user = User::factory()->create();
$previousPlan = $user->nutritionPlans()->where('is_active', true)->firstOrFail();
$review = $user->weeklyReviews()->create([
'nutrition_plan_id' => $previousPlan->getKey(),
'period_start' => '2026-08-10',
'period_end' => '2026-08-16',
'status' => WeeklyReviewStatus::ADJUSTMENT_RECOMMENDED,
'recommended_calorie_adjustment' => -100,
'message_code' => 'WEEKLY_REVIEW_ADJUSTMENT',
'metrics' => [],
'generated_at' => now(),
]);
$previousPlan->update([
'is_active' => false,
'effective_until' => now(),
]);
NutritionPlan::factory()->for($user)->create([
'is_active' => true,
'effective_from' => now()->addMinute(),
]);
Sanctum::actingAs($user);
$this->postJson("/api/weekly-reviews/{$review->id}/accept")
->assertStatus(409);
expect($review->fresh()->accepted_at)->toBeNull();
});