92 lines
2.8 KiB
PHP
92 lines
2.8 KiB
PHP
<?php
|
||
|
||
use App\Ai\Agents\MealImageAnalyzer;
|
||
use App\Enums\IngredientUnit;
|
||
use App\Enums\MealPostType;
|
||
use App\Models\User;
|
||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
use Illuminate\Http\UploadedFile;
|
||
use Laravel\Sanctum\Sanctum;
|
||
|
||
uses(RefreshDatabase::class);
|
||
|
||
function fakeMealAnalysisImage(): UploadedFile
|
||
{
|
||
$path = tempnam(sys_get_temp_dir(), 'meal-analysis-');
|
||
|
||
file_put_contents($path, base64_decode(
|
||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAFgwJ/lmHqWQAAAABJRU5ErkJggg=='
|
||
));
|
||
|
||
return new UploadedFile($path, 'meal.png', 'image/png', null, true);
|
||
}
|
||
|
||
it('analyzes a meal image into a draft', function () {
|
||
Sanctum::actingAs(User::factory()->create());
|
||
|
||
MealImageAnalyzer::fake([
|
||
[
|
||
'title' => ' Bowl saumon avocat ',
|
||
'caption' => 'Un bowl avec du saumon, du riz et de l’avocat.',
|
||
'type' => MealPostType::LUNCH->value,
|
||
'calories' => 612,
|
||
'proteins' => 39.4,
|
||
'carbs' => 58.2,
|
||
'fats' => 25.1,
|
||
'ingredients' => [
|
||
[
|
||
'position' => 12,
|
||
'ingredient' => ' Riz ',
|
||
'quantity' => 150,
|
||
'unit' => IngredientUnit::GRAM->value,
|
||
],
|
||
[
|
||
'position' => 13,
|
||
'ingredient' => 'Saumon',
|
||
'quantity' => 120,
|
||
'unit' => IngredientUnit::GRAM->value,
|
||
],
|
||
],
|
||
],
|
||
]);
|
||
|
||
$response = $this
|
||
->withHeader('Accept', 'application/json')
|
||
->post('/api/meal-posts/analyze-image', [
|
||
'image' => fakeMealAnalysisImage(),
|
||
]);
|
||
|
||
$response
|
||
->assertOk()
|
||
->assertJsonPath('data.title', 'Bowl saumon avocat')
|
||
->assertJsonPath('data.type', MealPostType::LUNCH->value)
|
||
->assertJsonPath('data.calories', 612)
|
||
->assertJsonPath('data.proteins', 39.4)
|
||
->assertJsonPath('data.ingredients.0.position', 1)
|
||
->assertJsonPath('data.ingredients.0.ingredient', 'Riz')
|
||
->assertJsonPath('data.ingredients.1.ingredient', 'Saumon');
|
||
|
||
MealImageAnalyzer::assertPrompted(
|
||
fn ($prompt): bool => str_contains($prompt->prompt, "Analyse l'image")
|
||
&& $prompt->attachments->count() === 1
|
||
);
|
||
});
|
||
|
||
it('requires authentication to analyze a meal image', function () {
|
||
$this
|
||
->withHeader('Accept', 'application/json')
|
||
->post('/api/meal-posts/analyze-image', [
|
||
'image' => fakeMealAnalysisImage(),
|
||
])
|
||
->assertUnauthorized();
|
||
});
|
||
|
||
it('validates the analyzed image', function () {
|
||
Sanctum::actingAs(User::factory()->create());
|
||
|
||
$this
|
||
->postJson('/api/meal-posts/analyze-image')
|
||
->assertUnprocessable()
|
||
->assertJsonValidationErrors(['image']);
|
||
});
|