createProduct('Produit A'); $this->createProduct('Produit B'); $client = $this->createViewerClient(); $client->request('GET', '/api/products'); $this->assertResponseIsSuccessful(); $this->assertJsonContainsHydraCollection(); $this->assertJsonContains(['totalItems' => 2]); } public function testGetItem(): void { $p = $this->createProduct('Produit A', 'REF-P001'); $client = $this->createViewerClient(); $client->request('GET', self::iri('products', $p->getId())); $this->assertResponseIsSuccessful(); $this->assertJsonContains([ 'name' => 'Produit A', 'reference' => 'REF-P001', ]); } public function testPost(): void { $client = $this->createGestionnaireClient(); $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => [ 'name' => 'Nouveau produit', 'reference' => 'REF-NEW', 'supplierPrice' => '99.99', ], ]); $this->assertResponseStatusCodeSame(201); $this->assertJsonContains(['name' => 'Nouveau produit']); } public function testPostWithType(): void { $mt = $this->createModelType('Huile', 'HUILE-001', ModelCategory::PRODUCT); $client = $this->createGestionnaireClient(); $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => [ 'name' => 'Produit typé', 'typeProduct' => self::iri('model_types', $mt->getId()), ], ]); $this->assertResponseStatusCodeSame(201); } public function testPut(): void { $p = $this->createProduct('Produit A'); $client = $this->createGestionnaireClient(); $client->request('PUT', self::iri('products', $p->getId()), [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => ['name' => 'Produit A Renommé'], ]); $this->assertResponseIsSuccessful(); $this->assertJsonContains(['name' => 'Produit A Renommé']); } public function testPatch(): void { $p = $this->createProduct('Produit A'); $client = $this->createGestionnaireClient(); $client->request('PATCH', self::iri('products', $p->getId()), [ 'headers' => ['Content-Type' => 'application/merge-patch+json'], 'json' => ['supplierPrice' => '150.00'], ]); $this->assertResponseIsSuccessful(); $this->assertJsonContains(['supplierPrice' => '150.00']); } public function testDelete(): void { $p = $this->createProduct('ToDelete'); $client = $this->createGestionnaireClient(); $client->request('DELETE', self::iri('products', $p->getId())); $this->assertResponseStatusCodeSame(204); } public function testUnauthenticatedAccess(): void { $client = $this->createUnauthenticatedClient(); $client->request('GET', '/api/products'); $this->assertResponseStatusCodeSame(401); } public function testViewerCannotWrite(): void { $client = $this->createViewerClient(); $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => ['name' => 'Blocked'], ]); $this->assertResponseStatusCodeSame(403); } public function testSearchFilter(): void { $this->createProduct('Huile moteur'); $this->createProduct('Filtre à air'); $client = $this->createViewerClient(); $client->request('GET', '/api/products?name=huile'); $this->assertResponseIsSuccessful(); $this->assertJsonContains(['totalItems' => 1]); } }