create(); $user->nutritionPlans()->where('is_active', true)->update([ 'calories' => 2400, 'proteins' => 140, 'carbs' => 280, 'fats' => 80, ]); Sanctum::actingAs($user); $this->getJson('/api/auth/me') ->assertOk() ->assertJsonPath('data.locale', 'en') ->assertJsonPath('data.nutritionGoals.calories', 2400) ->assertJsonPath('data.nutritionGoals.proteins', 140) ->assertJsonPath('data.nutritionGoals.carbs', 280) ->assertJsonPath('data.nutritionGoals.fats', 80); }); it('recalculates nutrition goals from the complete profile', function () { $user = User::factory()->create(); Sanctum::actingAs($user); $response = $this->patchJson('/api/nutrition-profile', [ 'dateOfBirth' => '1991-06-12', 'sex' => UserSex::MAN->value, 'heightCm' => 182, 'weightKg' => 84, 'targetWeightKg' => 78, 'physicalActivityLevel' => PhysicalActivityLevel::VERY_ACTIVE->value, 'weightGoal' => WeightGoal::LOSE_WEIGHT->value, 'pacePreference' => PacePreference::NORMAL->value, ]); $response ->assertOk() ->assertJsonPath('data.nutritionPlan.source', 'profile_recalculation') ->assertJsonPath('data.currentWeight', 84) ->assertJsonPath('data.targetWeight', 78); expect($response->json('data.nutritionGoals.calories'))->toBeGreaterThan(1200); $this->assertDatabaseCount('nutrition_plans', 2); $this->assertDatabaseCount('weight_entries', 2); $this->assertDatabaseHas('nutrition_plans', ['is_active' => false]); }); it('does not allow direct nutrition goal overrides through the account endpoint', function () { $user = User::factory()->create(); Sanctum::actingAs($user); $this->patchJson('/api/auth/me', [ 'nutritionGoals' => [ 'calories' => 9000, 'proteins' => 1, 'carbs' => 1, 'fats' => 1, ], ]) ->assertOk() ->assertJsonPath('data.nutritionGoals.calories', 2200); }); it('returns profile preferences with the authenticated user', function () { $user = User::factory()->create([ 'physical_activity_level' => PhysicalActivityLevel::VERY_ACTIVE->value, 'weight_goal' => WeightGoal::GAIN_WEIGHT->value, 'pace_preference' => PacePreference::FAST->value, ]); Sanctum::actingAs($user); $this->getJson('/api/auth/me') ->assertOk() ->assertJsonPath('data.physicalActivityLevel', PhysicalActivityLevel::VERY_ACTIVE->value) ->assertJsonPath('data.weightGoal', WeightGoal::GAIN_WEIGHT->value) ->assertJsonPath('data.pacePreference', PacePreference::FAST->value); }); it('updates profile preferences for the authenticated user', function () { $user = User::factory()->create(); Sanctum::actingAs($user); $this->patchJson('/api/nutrition-profile', [ 'physicalActivityLevel' => PhysicalActivityLevel::MODERATELY_ACTIVE->value, 'weightGoal' => WeightGoal::MAINTAIN_WEIGHT->value, 'pacePreference' => PacePreference::NORMAL->value, 'sex' => UserSex::MAN->value, 'dateOfBirth' => '2003-04-24', 'heightCm' => 180, 'weightKg' => 75, 'targetWeightKg' => null, ]) ->assertOk() ->assertJsonPath('data.physicalActivityLevel', PhysicalActivityLevel::MODERATELY_ACTIVE->value) ->assertJsonPath('data.weightGoal', WeightGoal::MAINTAIN_WEIGHT->value) ->assertJsonPath('data.pacePreference', PacePreference::NORMAL->value) ->assertJsonPath('data.sex', UserSex::MAN->value) ->assertJsonPath('data.dateOfBirth', '2003-04-24'); $this->assertDatabaseHas('users', [ 'id' => $user->id, 'physical_activity_level' => PhysicalActivityLevel::MODERATELY_ACTIVE->value, 'weight_goal' => WeightGoal::MAINTAIN_WEIGHT->value, 'pace_preference' => PacePreference::NORMAL->value, 'sex' => UserSex::MAN->value, ]); expect($user->fresh()->date_of_birth?->toDateString())->toBe('2003-04-24'); }); it('validates profile preferences', function () { Sanctum::actingAs(User::factory()->create()); $this->patchJson('/api/nutrition-profile', [ 'physicalActivityLevel' => 'daily', 'weightGoal' => 'bulk', 'pacePreference' => 'urgent', 'sex' => 'x', 'dateOfBirth' => 'tomorrow', 'heightCm' => 20, 'weightKg' => 5, ]) ->assertUnprocessable() ->assertJsonValidationErrors([ 'physicalActivityLevel', 'weightGoal', 'pacePreference', 'sex', 'dateOfBirth', 'heightCm', 'weightKg', ]); });