createMany(3); }); it('returns 200 OK for default inco-sheets list request', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; // WHEN $response = $test->getJson('/api/v1/inco-sheets'); // THEN $response->assertStatus(200); $response->assertJsonStructure([ 'incoSheets', 'pagination' => [ 'page', 'pageSize', 'totalItems', 'totalPages', 'links', ], ]); }); it('returns 200 OK for page and pageSize pagination query', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; // WHEN $response = $test->getJson('/api/v1/inco-sheets?page=1&pageSize=2'); // THEN $response->assertStatus(200); $response->assertJsonPath('pagination.pageSize', 2); }); it('returns 200 OK for offset and limit pagination query', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; // WHEN $response = $test->getJson('/api/v1/inco-sheets?offset=0&limit=2'); // THEN $response->assertStatus(200); $response->assertJsonPath('pagination.pageSize', 2); }); it('returns 200 OK for sorting query parameters', function (string $sortBy, string $direction): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; // WHEN $response = $test->getJson("/api/v1/inco-sheets?sortBy={$sortBy}&sortDirection={$direction}"); // THEN $response->assertStatus(200); })->with([ ['incoSheetId', 'Ascending'], ['createdAt', 'Descending'], ['updatedAt', 'Ascending'], ]); it('returns 200 OK with matching sheets filtered by BrandCode', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; MarqueFactory::new()->create(['COD_MARQ' => 504, 'LIB_MARQ' => 'LE GAULOIS PROFESSIONNEL']); $brand = app(BrandResolver::class)->resolve(new ArcadiaId('504')); ArticleRefFactory::new()->create([ 'NO_ART' => 9999001, 'COD_SOC' => 1, 'COD_MARQUE' => 504, ]); IncoFactory::new()->create([ 'NO_ART' => 9999001, 'DENOM_LEG' => 'Produit Gaulois Pro', ]); // WHEN $response = $test->getJson("/api/v1/inco-sheets?brands[]={$brand->code->value}"); // THEN $response->assertStatus(200); $response->assertJsonPath('incoSheets.0.incoId', '9999001'); }); it('returns 200 OK with matching sheets filtered by BrandCode passed as scalar query parameter without brackets', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; MarqueFactory::new()->create(['COD_MARQ' => 504, 'LIB_MARQ' => 'LE GAULOIS PROFESSIONNEL']); $brand = app(BrandResolver::class)->resolve(new ArcadiaId('504')); ArticleRefFactory::new()->create([ 'NO_ART' => 9999001, 'COD_SOC' => 1, 'COD_MARQUE' => 504, ]); IncoFactory::new()->create([ 'NO_ART' => 9999001, 'DENOM_LEG' => 'Produit Gaulois Pro', ]); // WHEN $response = $test->getJson("/api/v1/inco-sheets?brands={$brand->code->value}"); // THEN $response->assertStatus(200); $response->assertJsonPath('incoSheets.0.incoId', '9999001'); }); it('returns 422 Unprocessable Entity when brand code format is invalid', function (): void { // GIVEN /** @var \Tests\TestCase $test */ $test = $this; // WHEN $response = $test->getJson('/api/v1/inco-sheets?brands[]=invalid'); // THEN $response->assertStatus(422); }); 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'); // 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('allegations') ->and($firstItem)->not->toHaveKey('ingredients') ->and($firstItem)->not->toHaveKey('brand'); }); });