diff --git a/src/main/java/fr/ulille/iut/pizzaland/beans/Ingredient.java b/src/main/java/fr/ulille/iut/pizzaland/beans/Ingredient.java index 15a6b3991f0efd7bb07932e9d8023e5db722df98..f54539d845e7d0a21e6d4179062b90106bfab13d 100644 --- a/src/main/java/fr/ulille/iut/pizzaland/beans/Ingredient.java +++ b/src/main/java/fr/ulille/iut/pizzaland/beans/Ingredient.java @@ -1,6 +1,7 @@ package fr.ulille.iut.pizzaland.beans; import fr.ulille.iut.pizzaland.dto.IngredientDto; +import fr.ulille.iut.pizzaland.dto.IngredientCreateDto; public class Ingredient { private long id; @@ -69,4 +70,21 @@ public class Ingredient { public String toString() { return "Ingredient [id=" + id + ", name=" + name + "]"; } + + + public static IngredientCreateDto toCreateDto(Ingredient ingredient) { + IngredientCreateDto dto = new IngredientCreateDto(); + dto.setName(ingredient.getName()); + + return dto; + } + + public static Ingredient fromIngredientCreateDto(IngredientCreateDto dto) { + Ingredient ingredient = new Ingredient(); + ingredient.setName(dto.getName()); + + return ingredient; + } + + } diff --git a/src/main/java/fr/ulille/iut/pizzaland/dao/IngredientDao.java b/src/main/java/fr/ulille/iut/pizzaland/dao/IngredientDao.java index 0fda1f32b55e8631594446fd6039bcd8bdf5f89f..adfbc4d50b5b5315d750b6a43b5a51fe9b85f3aa 100644 --- a/src/main/java/fr/ulille/iut/pizzaland/dao/IngredientDao.java +++ b/src/main/java/fr/ulille/iut/pizzaland/dao/IngredientDao.java @@ -28,4 +28,12 @@ public interface IngredientDao { @SqlQuery("SELECT * FROM ingredients WHERE id = :id") @RegisterBeanMapper(Ingredient.class) Ingredient findById(long id); + + @SqlQuery("SELECT * FROM ingredients WHERE name = :name") + @RegisterBeanMapper(Ingredient.class) + Ingredient findByName(String name); + + @SqlUpdate("DELETE FROM ingredients WHERE id = :id") + void remove(long id); + } diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java new file mode 100644 index 0000000000000000000000000000000000000000..b2a0dfda431ac1d4b5869e5ddbfb7507f7a94256 --- /dev/null +++ b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java @@ -0,0 +1,15 @@ +package fr.ulille.iut.pizzaland.dto; + +public class IngredientCreateDto { + private String name; + + public IngredientCreateDto() {} + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java index 75f914d9a6f1f83084d399635fcacceddafac5ec..1e58e87880ecc58a3e794750b8acbcdfc32fb585 100644 --- a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java +++ b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java @@ -1,26 +1,24 @@ package fr.ulille.iut.pizzaland.dto; public class IngredientDto { - private long id; - private String name; - - public IngredientDto() { - - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name=name; - } + private long id; + private String name; + + public IngredientDto() {} + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } } diff --git a/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java b/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java index 6439bc11966154f65c662943830a4667580ba6c5..ae33b53400abafefc8f03673d11b57d3cef575d4 100644 --- a/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java +++ b/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java @@ -11,35 +11,131 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; +import org.slf4j.LoggerFactory; + import javax.ws.rs.PathParam; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; + import fr.ulille.iut.pizzaland.beans.Ingredient; import fr.ulille.iut.pizzaland.dto.IngredientDto; +import fr.ulille.iut.pizzaland.BDDFactory; +import fr.ulille.iut.pizzaland.dao.IngredientDao; + +import java.util.stream.Collectors; +import javax.ws.rs.POST; +import fr.ulille.iut.pizzaland.dto.IngredientCreateDto; +import javax.ws.rs.WebApplicationException; @Path("/ingredients") public class IngredientResource { + final static Logger LOGGER = Logger.getLogger(IngredientResource.class.getName()); + @Context + public UriInfo uriInfo; + + private IngredientDao ingredients; + -@Context -public UriInfo uriInfo; + public IngredientResource() { + ingredients = BDDFactory.buildDao(IngredientDao.class); + ingredients.createTable(); + } -public IngredientResource() { -} + @GET + public List<IngredientDto> getAll() { + LOGGER.info("IngredientResource:getAll"); -@GET -public List<IngredientDto> getAll() { + List<IngredientDto> l = ingredients.getAll().stream().map(Ingredient::toDto).collect(Collectors.toList()); + return l; + } - return new ArrayList<IngredientDto>(); -} + @GET + @Path("{id}") + public IngredientDto getOneIngredient(@PathParam("id") long id) { + LOGGER.info("getOneIngredient(" + id + ")"); + try { + Ingredient ingredient = ingredients.findById(id); + return Ingredient.toDto(ingredient); + } catch (Exception e) { + // Cette exception générera une réponse avec une erreur 404 + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + } -@GET -@Path("{id}") -public IngredientDto getOneIngredient(@PathParam("id") long id) { - Ingredient ingredient = new Ingredient(); - ingredient.setId(1); - ingredient.setName("mozzarella"); - - return Ingredient.toDto(ingredient); + @POST + public Response createIngredient(IngredientCreateDto ingredientCreateDto) { + Ingredient existing = ingredients.findByName(ingredientCreateDto.getName()); + if (existing != null) { + throw new WebApplicationException(Response.Status.CONFLICT); + } -} + try { + Ingredient ingredient = Ingredient.fromIngredientCreateDto(ingredientCreateDto); + long id = ingredients.insert(ingredient.getName()); + ingredient.setId(id); + IngredientDto ingredientDto = Ingredient.toDto(ingredient); + + URI uri = uriInfo.getAbsolutePathBuilder().path("" + id).build(); + + return Response.created(uri).entity(ingredientDto).build(); + } catch (Exception e) { + e.printStackTrace(); + throw new WebApplicationException(Response.Status.NOT_ACCEPTABLE); + } + } + + @DELETE + @Path("{id}") + public Response deleteIngredient(@PathParam("id") long id) { + if ( ingredients.findById(id) == null ) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } -} \ No newline at end of file + ingredients.remove(id); + + return Response.status(Response.Status.ACCEPTED).build(); + } + + @GET + @Path("{id}/name") + public String getIngredientName(@PathParam("id") long id) { + Ingredient ingredient = ingredients.findById(id); + if ( ingredient == null ) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + + return ingredient.getName(); + } + + @POST + @Consumes("application/x-www-form-urlencoded") + public Response createIngredient(@FormParam("name") String name) { + Ingredient existing = ingredients.findByName(name); + if ( existing != null ) { + throw new WebApplicationException(Response.Status.CONFLICT); + } + + try { + Ingredient ingredient = new Ingredient(); + ingredient.setName(name); + + long id = ingredients.insert(ingredient.getName()); + ingredient.setId(id); + IngredientDto ingredientDto = Ingredient.toDto(ingredient); + + URI uri = uriInfo.getAbsolutePathBuilder().path("" + id).build(); + + return Response.created(uri).entity(ingredientDto).build(); + } + catch ( Exception e ) { + e.printStackTrace(); + throw new WebApplicationException(Response.Status.NOT_ACCEPTABLE); + } + } + + + + +} diff --git a/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java b/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java index 75cf2d1776545f6797d2d6d3c4706ff6f8e89e10..232e7fc6ba71985774b9c8d6b33e123686373879 100644 --- a/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java +++ b/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java @@ -11,7 +11,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; - import javax.ws.rs.client.Entity; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.Application; @@ -19,77 +18,160 @@ import javax.ws.rs.core.Response; import static org.junit.Assert.assertEquals; +import fr.ulille.iut.pizzaland.dto.IngredientCreateDto; import java.util.List; import java.util.logging.Logger; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Form; + +import static org.junit.Assert.assertNotNull; +import fr.ulille.iut.pizzaland.dao.IngredientDao; /* * JerseyTest facilite l'écriture des tests en donnant accès aux * méthodes de l'interface javax.ws.rs.client.Client. * la méthode configure() permet de démarrer la ressource à tester */ + public class IngredientResourceTest extends JerseyTest { private IngredientDao dao; - - @Override - protected Application configure() { - BDDFactory.setJdbiForTests(); - return new ApiV1(); - } - - // Les méthodes setEnvUp() et tearEnvDown() serviront à terme à initialiser la base de données - // et les DAO - - // https://stackoverflow.com/questions/25906976/jerseytest-and-junit-throws-nullpointerexception - @Before - public void setEnvUp() { - dao = BDDFactory.buildDao(IngredientDao.class); - dao.createTable(); - - } - - @After - public void tearEnvDown() throws Exception { - dao.dropTable(); - } - - @Test - public void testGetEmptyList() { - // La méthode target() permet de préparer une requête sur une URI. - // La classe Response permet de traiter la réponse HTTP reçue. - Response response = target("/ingredients").request().get(); - - // On vérifie le code de la réponse (200 = OK) - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - - - // On vérifie la valeur retournée (liste vide) - // L'entité (readEntity() correspond au corps de la réponse HTTP. - // La classe javax.ws.rs.core.GenericType<T> permet de définir le type - // de la réponse lue quand on a un type complexe (typiquement une liste). - List<IngredientDto> ingredients; - ingredients = response.readEntity(new GenericType<List<IngredientDto>>(){}); - - assertEquals(0, ingredients.size()); - - } - - - - @Test - public void testGetExistingIngredient() { - Ingredient ingredient = new Ingredient(); - ingredient.setName("mozzarella"); - - long id = dao.insert(ingredient.getName()); - ingredient.setId(id); - - Response response = target("/ingredients/" + id).request().get(); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - - Ingredient result = Ingredient.fromDto(response.readEntity(IngredientDto.class)); - assertEquals(ingredient, result); - - } + + @Override + protected Application configure() { + BDDFactory.setJdbiForTests(); + + return new ApiV1(); + } + + @Before + public void setEnvUp() { + dao = BDDFactory.buildDao(IngredientDao.class); + dao.createTable(); + } + + @After + public void tearEnvDown() throws Exception { + dao.dropTable(); + } + + @Test + public void testGetExistingIngredient() { + + Ingredient ingredient = new Ingredient(); + ingredient.setName("mozzarella"); + + long id = dao.insert(ingredient.getName()); + ingredient.setId(id); + + Response response = target("/ingredients/" + id).request().get(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + Ingredient result = Ingredient.fromDto(response.readEntity(IngredientDto.class)); + assertEquals(ingredient, result); + } + + @Test + public void testGetNotExistingIngredient() { + Response response = target("/ingredients/125").request().get(); + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + } + + @Test + public void testCreateIngredient() { + IngredientCreateDto ingredientCreateDto = new IngredientCreateDto(); + ingredientCreateDto.setName("mozzarella"); + + Response response = target("/ingredients").request().post(Entity.json(ingredientCreateDto)); + + // On vérifie le code de status à 201 + assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus()); + + IngredientDto returnedEntity = response.readEntity(IngredientDto.class); + + // On vérifie que le champ d'entête Location correspond à + // l'URI de la nouvelle entité + assertEquals(target("/ingredients/" + returnedEntity.getId()).getUri(), response.getLocation()); + + // On vérifie que le nom correspond + assertEquals(returnedEntity.getName(), ingredientCreateDto.getName()); + } + + @Test + public void testCreateSameIngredient() { + IngredientCreateDto ingredientCreateDto = new IngredientCreateDto(); + ingredientCreateDto.setName("mozzarella"); + dao.insert(ingredientCreateDto.getName()); + + Response response = target("/ingredients").request().post(Entity.json(ingredientCreateDto)); + + assertEquals(Response.Status.CONFLICT.getStatusCode(), response.getStatus()); + } + + @Test + public void testCreateIngredientWithoutName() { + IngredientCreateDto ingredientCreateDto = new IngredientCreateDto(); + + Response response = target("/ingredients").request().post(Entity.json(ingredientCreateDto)); + + assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus()); + } + + @Test + public void testDeleteExistingIngredient() { + Ingredient ingredient = new Ingredient(); + ingredient.setName("mozzarella"); + long id = dao.insert(ingredient.getName()); + ingredient.setId(id); + + Response response = target("/ingredients/" + id).request().delete(); + + assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus()); + + Ingredient result = dao.findById(id); + assertEquals(result, null); + } + + @Test + public void testDeleteNotExistingIngredient() { + Response response = target("/ingredients/125").request().delete(); + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + } + + @Test + public void testGetIngredientName() { + Ingredient ingredient = new Ingredient(); + ingredient.setName("mozzarella"); + long id = dao.insert(ingredient.getName()); + + Response response = target("ingredients/" + id + "/name").request().get(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + assertEquals("mozzarella", response.readEntity(String.class)); + } + + @Test + public void testGetNotExistingIngredientName() { + Response response = target("ingredients/125/name").request().get(); + + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + } + + @Test + public void testCreateWithForm() { + Form form = new Form(); + form.param("name", "chorizo"); + + Entity<Form> formEntity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE); + Response response = target("ingredients").request().post(formEntity); + + assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus()); + String location = response.getHeaderString("Location"); + long id = Integer.parseInt(location.substring(location.lastIndexOf('/') + 1)); + Ingredient result = dao.findById(id); + + assertNotNull(result); + } }