feat: ai analyze
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<?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']);
|
||||
});
|
||||
Reference in New Issue
Block a user