diff --git a/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsIndexController.php b/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsIndexController.php index 6f38fca..4abdaa3 100644 --- a/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsIndexController.php +++ b/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsIndexController.php @@ -41,7 +41,7 @@ final readonly class IncoSheetsIndexController pagination: $request->pagination(), sorter: $request->sorter(), filter: $request->filter(), - short: $request->isShort(), + short: true, ); } } diff --git a/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsSearchController.php b/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsSearchController.php index 7c5f5e6..aeb8d39 100644 --- a/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsSearchController.php +++ b/src/Presentation/Api/V1/Http/Controllers/IncoSheets/IncoSheetsSearchController.php @@ -41,7 +41,7 @@ final readonly class IncoSheetsSearchController { return new SearchInput( $request->incoIdSearch(), - $request->isShort(), + true, $request->pagination(), ...$request->brands() ); diff --git a/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsIndexRequest.php b/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsIndexRequest.php index 67479f2..bb64756 100644 --- a/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsIndexRequest.php +++ b/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsIndexRequest.php @@ -35,7 +35,6 @@ final class IncoSheetsIndexRequest extends FormRequest 'since' => ['sometimes', 'date'], 'brands' => ['sometimes', 'array'], 'brands.*' => ['sometimes', 'string'], - 'short' => ['sometimes', Rule::in(['true', 'false', true, false, '1', '0', 1, 0])], ]; } @@ -86,9 +85,4 @@ final class IncoSheetsIndexRequest extends FormRequest default => \SortDirection::Ascending, }; } - - public function isShort(): bool - { - return filter_var($this->input('short', false), FILTER_VALIDATE_BOOLEAN); - } } diff --git a/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsSearchRequest.php b/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsSearchRequest.php index bee32b2..6bcc907 100644 --- a/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsSearchRequest.php +++ b/src/Presentation/Api/V1/Http/Requests/IncoSheets/IncoSheetsSearchRequest.php @@ -7,7 +7,6 @@ namespace Presentation\Api\V1\Http\Requests\IncoSheets; use Domain\Models\ValueObjects\Brand\BrandCode; use Domain\Models\ValueObjects\Inco\IncoIdQuery; use Illuminate\Foundation\Http\FormRequest; -use Illuminate\Validation\Rule; /** * @method \Shared\Pagination pagination(int $defaultPageSize = 25) @@ -22,7 +21,6 @@ final class IncoSheetsSearchRequest extends FormRequest 'incoIdLike' => ['required', 'string'], 'brands' => ['sometimes', 'array'], 'brands.*' => ['sometimes', 'string'], - 'short' => ['sometimes', Rule::in(['true', 'false', true, false, '1', '0', 1, 0])], ]; } @@ -47,9 +45,4 @@ final class IncoSheetsSearchRequest extends FormRequest return $result; } - - public function isShort(): bool - { - return filter_var($this->input('short', false), FILTER_VALIDATE_BOOLEAN); - } } diff --git a/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsIndexResponse.php b/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsIndexResponse.php index 94bf8ef..baa2280 100644 --- a/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsIndexResponse.php +++ b/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsIndexResponse.php @@ -6,19 +6,9 @@ namespace Presentation\Api\V1\Http\Responses\IncoSheets; use Application\Arcadia\Usecase\IncoSheets\FindAll\PaginatedIncoSheet; use Application\Arcadia\Usecase\IncoSheets\FindAll\PaginatedShortIncoSheet; -use Domain\Models\ValueObjects\Inco\Additive; -use Domain\Models\ValueObjects\Inco\Allergen; use Illuminate\Http\JsonResponse; use Presentation\Api\V1\Contracts\ApiResponse; -use Presentation\Api\V1\Dto\IncoSheets\IncoSheetDto; use Presentation\Api\V1\Dto\IncoSheets\IncoShortSheetDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\AdditiveDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\AllegationsDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\BrandDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\NutriscoreDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\PortionsDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\StorageConditionDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\WeightDto; use Presentation\Api\V1\Dto\PaginationDto; use Presentation\Api\V1\Presenters\IncoSheets\IncoSheetsIndexView; use Shared\Time\Utc; @@ -51,7 +41,14 @@ final readonly class IncoSheetsIndexResponse implements ApiResponse $items = array_map( fn (PaginatedIncoSheet | PaginatedShortIncoSheet $sheet): array => match (true) { $sheet instanceof PaginatedShortIncoSheet => $this->fromPaginatedShortIncoSheet($sheet)->toArray(), - $sheet instanceof PaginatedIncoSheet => $this->fromPaginatedIncoSheet($sheet)->toArray(), + $sheet instanceof PaginatedIncoSheet => (new IncoShortSheetDto( + incoId: (string) $sheet->id, + name: $sheet->name, + label: $sheet->label, + description: $sheet->description, + createdAt: Utc::toNullableRfc3339($sheet->createdAt), + updatedAt: Utc::toNullableRfc3339($sheet->updatedAt), + ))->toArray(), }, $this->view->incoSheets ); @@ -73,40 +70,4 @@ final readonly class IncoSheetsIndexResponse implements ApiResponse updatedAt: Utc::toNullableRfc3339($sheet->updatedAt), ); } - - private function fromPaginatedIncoSheet(PaginatedIncoSheet $sheet): IncoSheetDto - { - $ingGroups = $sheet->ingredients->groups; - $ingObject = empty($ingGroups) ? (object) [] : (object) $ingGroups; - - return new IncoSheetDto( - incoId: (string) $sheet->id, - name: $sheet->name, - label: $sheet->label, - description: $sheet->description, - allegations: AllegationsDto::fromDomain($sheet->allegations), - sellArguments: $sheet->sellArguments, - preparationAdvices: $sheet->preparationAdvices, - tips: $sheet->tips, - sellFamilly: $sheet->sellFamilly, - ingredients: $ingObject, - portions: $sheet->portions !== null ? PortionsDto::fromDomain($sheet->portions) : null, - allergens: array_values(array_map( - static fn (Allergen $a): string => $a->label, - $sheet->allergens - )), - brand: BrandDto::fromDomain($sheet->brand), - isSeasonal: $sheet->isSeasonal, - weight: $sheet->weight !== null ? WeightDto::fromDomain($sheet->weight) : null, - nutriscore: $sheet->nutriscore !== null ? NutriscoreDto::fromDomain($sheet->nutriscore) : null, - storageCondition: $sheet->storageCondition !== null ? StorageConditionDto::fromDomain($sheet->storageCondition) : null, - additives: array_values(array_map( - static fn (Additive $a): AdditiveDto => AdditiveDto::fromDomain($a), - $sheet->additives - )), - incoCompoId: $sheet->compo !== null ? (string) $sheet->compo : null, - createdAt: Utc::toNullableRfc3339($sheet->createdAt), - updatedAt: Utc::toNullableRfc3339($sheet->updatedAt), - ); - } } diff --git a/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsSearchResponse.php b/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsSearchResponse.php index 02d82cb..0cf6d10 100644 --- a/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsSearchResponse.php +++ b/src/Presentation/Api/V1/Http/Responses/IncoSheets/IncoSheetsSearchResponse.php @@ -6,19 +6,9 @@ namespace Presentation\Api\V1\Http\Responses\IncoSheets; use Application\Arcadia\Usecase\IncoSheets\Search\PaginatedIncoSheet; use Application\Arcadia\Usecase\IncoSheets\Search\PaginatedShortIncoSheet; -use Domain\Models\ValueObjects\Inco\Additive; -use Domain\Models\ValueObjects\Inco\Allergen; use Illuminate\Http\JsonResponse; use Presentation\Api\V1\Contracts\ApiResponse; -use Presentation\Api\V1\Dto\IncoSheets\IncoSheetDto; use Presentation\Api\V1\Dto\IncoSheets\IncoShortSheetDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\AdditiveDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\AllegationsDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\BrandDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\NutriscoreDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\PortionsDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\StorageConditionDto; -use Presentation\Api\V1\Dto\IncoSheets\Parts\WeightDto; use Presentation\Api\V1\Dto\PaginationDto; use Presentation\Api\V1\Presenters\IncoSheets\IncoSheetsSearchView; use Shared\Time\Utc; @@ -51,7 +41,14 @@ final readonly class IncoSheetsSearchResponse implements ApiResponse $items = array_map( fn (PaginatedIncoSheet | PaginatedShortIncoSheet $sheet): array => match (true) { $sheet instanceof PaginatedShortIncoSheet => $this->fromPaginatedIncoSheetToShort($sheet)->toArray(), - $sheet instanceof PaginatedIncoSheet => $this->fromPaginatedIncoSheetToFull($sheet)->toArray(), + $sheet instanceof PaginatedIncoSheet => (new IncoShortSheetDto( + incoId: (string) $sheet->id, + name: $sheet->name, + label: $sheet->label, + description: $sheet->description, + createdAt: Utc::toNullableRfc3339($sheet->createdAt), + updatedAt: Utc::toNullableRfc3339($sheet->updatedAt), + ))->toArray(), }, $this->view->incoSheets ); @@ -73,40 +70,4 @@ final readonly class IncoSheetsSearchResponse implements ApiResponse updatedAt: Utc::toNullableRfc3339($sheet->updatedAt), ); } - - private function fromPaginatedIncoSheetToFull(PaginatedIncoSheet $sheet): IncoSheetDto - { - $ingGroups = $sheet->ingredients->groups; - $ingObject = empty($ingGroups) ? (object) [] : (object) $ingGroups; - - return new IncoSheetDto( - incoId: (string) $sheet->id, - name: $sheet->name, - label: $sheet->label, - description: $sheet->description, - allegations: AllegationsDto::fromDomain($sheet->allegations), - sellArguments: $sheet->sellArguments, - preparationAdvices: $sheet->preparationAdvices, - tips: $sheet->tips, - sellFamilly: $sheet->sellFamilly, - ingredients: $ingObject, - portions: $sheet->portions !== null ? PortionsDto::fromDomain($sheet->portions) : null, - allergens: array_values(array_map( - static fn (Allergen $a): string => $a->label, - $sheet->allergens - )), - brand: BrandDto::fromDomain($sheet->brand), - isSeasonal: $sheet->isSeasonal, - weight: $sheet->weight !== null ? WeightDto::fromDomain($sheet->weight) : null, - nutriscore: $sheet->nutriscore !== null ? NutriscoreDto::fromDomain($sheet->nutriscore) : null, - storageCondition: $sheet->storageCondition !== null ? StorageConditionDto::fromDomain($sheet->storageCondition) : null, - additives: array_values(array_map( - static fn (Additive $a): AdditiveDto => AdditiveDto::fromDomain($a), - $sheet->additives - )), - incoCompoId: $sheet->compo !== null ? (string) $sheet->compo : null, - createdAt: Utc::toNullableRfc3339($sheet->createdAt), - updatedAt: Utc::toNullableRfc3339($sheet->updatedAt), - ); - } } diff --git a/tests/Feature/Api/V1/IncoSheets/IncoSheetsIndexTest.php b/tests/Feature/Api/V1/IncoSheets/IncoSheetsIndexTest.php index b14c362..e4c1cfc 100644 --- a/tests/Feature/Api/V1/IncoSheets/IncoSheetsIndexTest.php +++ b/tests/Feature/Api/V1/IncoSheets/IncoSheetsIndexTest.php @@ -106,9 +106,7 @@ describe('IncoSheets Index Feature API', function (): void { // THEN $response->assertStatus(200); - $response->assertJsonPath('incoSheets.0.incoId', '9999001') - ->assertJsonPath('incoSheets.0.brand.code', $brand->code->value) - ->assertJsonPath('incoSheets.0.brand.label', 'Le Gaulois Professionnel'); + $response->assertJsonPath('incoSheets.0.incoId', '9999001'); }); it('returns 422 Unprocessable Entity when brand code format is invalid', function (): void { @@ -123,13 +121,13 @@ describe('IncoSheets Index Feature API', function (): void { $response->assertStatus(422); }); - it('returns 200 OK with short form inco sheets when short parameter is true', function (): void { + it('returns 200 OK with short form inco sheets structure', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; // WHEN - $response = $test->getJson('/api/v1/inco-sheets?short=true'); + $response = $test->getJson('/api/v1/inco-sheets'); // THEN $response->assertStatus(200); @@ -154,34 +152,4 @@ describe('IncoSheets Index Feature API', function (): void { ->and($firstItem)->not->toHaveKey('ingredients') ->and($firstItem)->not->toHaveKey('brand'); }); - - it('returns 200 OK with short form inco sheets when short parameter is numeric 1', function (): void { - // GIVEN - /** @var \Tests\TestCase $test */ - $test = $this; - - // WHEN - $response = $test->getJson('/api/v1/inco-sheets?short=1'); - - // THEN - $response->assertStatus(200); - $response->assertJsonStructure([ - 'incoSheets' => [ - '*' => [ - 'incoId', - 'name', - 'label', - 'description', - 'createdAt', - 'updatedAt', - ], - ], - 'pagination', - ]); - - $firstItem = $response->json('incoSheets.0'); - expect($firstItem) - ->toHaveKeys(['incoId', 'name', 'label', 'description', 'createdAt', 'updatedAt']) - ->and($firstItem)->not->toHaveKey('ingredients'); - }); }); diff --git a/tests/Feature/Api/V1/IncoSheets/IncoSheetsSearchTest.php b/tests/Feature/Api/V1/IncoSheets/IncoSheetsSearchTest.php index 78dac58..94711ea 100644 --- a/tests/Feature/Api/V1/IncoSheets/IncoSheetsSearchTest.php +++ b/tests/Feature/Api/V1/IncoSheets/IncoSheetsSearchTest.php @@ -84,8 +84,7 @@ describe('IncoSheets Search Feature API', function (): void { // THEN $response->assertStatus(200); $response->assertJsonCount(1, 'incoSheets'); - $response->assertJsonPath('incoSheets.0.incoId', '1000101') - ->assertJsonPath('incoSheets.0.brand.code', $brand->code->value); + $response->assertJsonPath('incoSheets.0.incoId', '1000101'); }); it('returns 422 Unprocessable Entity when brand code format is invalid', function (): void { @@ -101,14 +100,14 @@ describe('IncoSheets Search Feature API', function (): void { $response->assertStatus(422); }); - it('returns 200 OK with short form inco sheets when short parameter is true', function (): void { + it('returns 200 OK with short form inco sheets structure on search', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; $query = urlencode('%1000101%'); // WHEN - $response = $test->getJson("/api/v1/inco-sheets/search?incoIdLike={$query}&short=true"); + $response = $test->getJson("/api/v1/inco-sheets/search?incoIdLike={$query}"); // THEN $response->assertStatus(200); @@ -134,37 +133,6 @@ describe('IncoSheets Search Feature API', function (): void { ->and($firstItem)->not->toHaveKey('brand'); }); - it('returns 200 OK with short form inco sheets when short parameter is numeric 1', function (): void { - // GIVEN - /** @var \Tests\TestCase $test */ - $test = $this; - $query = urlencode('%10001%'); - - // WHEN - $response = $test->getJson("/api/v1/inco-sheets/search?incoIdLike={$query}&short=1"); - - // THEN - $response->assertStatus(200); - $response->assertJsonStructure([ - 'incoSheets' => [ - '*' => [ - 'incoId', - 'name', - 'label', - 'description', - 'createdAt', - 'updatedAt', - ], - ], - 'pagination', - ]); - - $firstItem = $response->json('incoSheets.0'); - expect($firstItem) - ->toHaveKeys(['incoId', 'name', 'label', 'description', 'createdAt', 'updatedAt']) - ->and($firstItem)->not->toHaveKey('ingredients'); - }); - it('returns 200 OK with empty incoSheets list when no matching inco sheets found', function (): void { // GIVEN /** @var \Tests\TestCase $test */ diff --git a/tests/Feature/OpenApi/V1/IncoSheets/IncoSheetOpenApiTest.php b/tests/Feature/OpenApi/V1/IncoSheets/IncoSheetOpenApiTest.php index 7db0640..992ecb6 100644 --- a/tests/Feature/OpenApi/V1/IncoSheets/IncoSheetOpenApiTest.php +++ b/tests/Feature/OpenApi/V1/IncoSheets/IncoSheetOpenApiTest.php @@ -36,26 +36,6 @@ describe('IncoSheet OpenAPI Conformance', function (): void { $response->assertValidResponse(200); }); - it('validates GET /api/v1/inco-sheets list response with short projection against openapi spec', function (): void { - // GIVEN - /** @var \Tests\TestCase $test */ - $test = $this; - - IncoFactory::new()->create([ - 'NO_ART' => 10002, - 'DENOM_LEG' => 'Salade Niçoise 300g', - ]); - - // WHEN - /** @var \Illuminate\Testing\TestResponse<\Symfony\Component\HttpFoundation\Response> $response */ - $response = $test->getJson('/api/v1/inco-sheets?short=true'); - - // THEN - $response->assertStatus(200); - $response->assertValidRequest(); - $response->assertValidResponse(200); - }); - it('validates GET /api/v1/inco-sheets list response with brands filter against openapi spec', function (): void { // GIVEN /** @var \Tests\TestCase $test */ @@ -142,25 +122,4 @@ describe('IncoSheet OpenAPI Conformance', function (): void { $response->assertValidRequest(); $response->assertValidResponse(200); }); - - it('validates GET /api/v1/inco-sheets/search with short projection against openapi spec', function (): void { - // GIVEN - /** @var \Tests\TestCase $test */ - $test = $this; - $query = urlencode('%10004%'); - - IncoFactory::new()->create([ - 'NO_ART' => 1000402, - 'DENOM_LEG' => 'Tarte aux Pommes', - ]); - - // WHEN - /** @var \Illuminate\Testing\TestResponse<\Symfony\Component\HttpFoundation\Response> $response */ - $response = $test->getJson("/api/v1/inco-sheets/search?incoIdLike={$query}&short=true"); - - // THEN - $response->assertStatus(200); - $response->assertValidRequest(); - $response->assertValidResponse(200); - }); });