From 4ac5ab2e0434e43a7fe6bef0e6a2faa7d386bc7c Mon Sep 17 00:00:00 2001
From: Ryan Rossez <ryan.rossez@outlook.fr>
Date: Tue, 18 Feb 2020 15:48:54 +0100
Subject: [PATCH] =?UTF-8?q?Pizza=20sans=20ingr=C3=A9dients=20fonctionnel?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../fr/ulille/iut/pizzaland/beans/Pizza.java  | 117 +++++++++++
 .../fr/ulille/iut/pizzaland/dao/PizzaDao.java |  56 ++++++
 .../pizzaland/dto/IngredientCreateDto.java    |   1 +
 .../iut/pizzaland/dto/IngredientDto.java      |   2 +
 .../iut/pizzaland/dto/PizzaCreateDto.java     |  28 +++
 .../fr/ulille/iut/pizzaland/dto/PizzaDto.java |  45 +++++
 .../pizzaland/resources/PizzaResource.java    | 118 +++++++++++
 src/main/resources/ingredients.json           |   1 +
 src/main/resources/pizza.json                 |   5 +
 .../iut/pizzaland/IngredientResourceTest.java |   4 +-
 .../iut/pizzaland/PizzaResourceTest.java      | 190 ++++++++++++++++++
 11 files changed, 565 insertions(+), 2 deletions(-)
 create mode 100644 src/main/java/fr/ulille/iut/pizzaland/beans/Pizza.java
 create mode 100644 src/main/java/fr/ulille/iut/pizzaland/dao/PizzaDao.java
 create mode 100644 src/main/java/fr/ulille/iut/pizzaland/dto/PizzaCreateDto.java
 create mode 100644 src/main/java/fr/ulille/iut/pizzaland/dto/PizzaDto.java
 create mode 100644 src/main/java/fr/ulille/iut/pizzaland/resources/PizzaResource.java
 create mode 100644 src/main/resources/pizza.json
 create mode 100644 src/test/java/fr/ulille/iut/pizzaland/PizzaResourceTest.java

diff --git a/src/main/java/fr/ulille/iut/pizzaland/beans/Pizza.java b/src/main/java/fr/ulille/iut/pizzaland/beans/Pizza.java
new file mode 100644
index 0000000..e4fb47f
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/beans/Pizza.java
@@ -0,0 +1,117 @@
+package fr.ulille.iut.pizzaland.beans;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.ulille.iut.pizzaland.dto.*;
+
+public class Pizza {
+    private long id;
+    private String name;
+    private List<Ingredient> ingredients = new ArrayList<Ingredient>();
+
+    public Pizza() {
+    }
+  
+    public Pizza(long id, String name) {
+      this.id = id;
+      this.name = name;
+      this.ingredients=new ArrayList<Ingredient>();
+    }
+
+    public Pizza(long id, String name,List<Ingredient> ingredients){
+        this.id=id;
+        this.name=name;
+        this.ingredients=ingredients;
+    }
+  
+    public void setId(long id) {
+      this.id = id;
+    }
+  
+    public long getId() {
+      return id;
+    }
+  
+    public String getName() {
+      return name;
+    }
+  
+    public void setName(String name) {
+      this.name = name;
+    }
+  
+    public void setIngredients(List<Ingredient> ingredients){
+        this.ingredients = ingredients;
+    }
+
+    public void addIngredients(Ingredient ingredient){
+        this.ingredients.add(ingredient);
+    }
+
+    public void removeIngredients(Ingredient ingredient){
+        this.ingredients.remove(ingredient);
+    }
+
+    public List<Ingredient> getIngredients(){
+        return this.ingredients;
+    }
+
+    public static PizzaDto toDto(Pizza i) {
+      PizzaDto dto = new PizzaDto();
+      dto.setId(i.getId());
+      dto.setName(i.getName());
+  
+      return dto;
+    }
+  
+    public static Pizza fromDto(PizzaDto dto) {
+      Pizza pizza = new Pizza();
+      pizza.setId(dto.getId());
+      pizza.setName(dto.getName());
+  
+      return pizza;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj)
+          return true;
+      if (obj == null)
+          return false;
+      if (getClass() != obj.getClass())
+          return false;
+      Pizza other = (Pizza) obj;
+      if (id != other.id)
+          return false;
+      if (name == null) {
+          if (other.name != null)
+              return false;
+      } else if (!name.equals(other.name))
+          return false;
+      return true;
+    }
+  
+    @Override
+    public String toString() {
+      String res = "Pizza [id=" + id + ", name=" + name + "] ";
+      for (Ingredient i : ingredients ){
+        res+=i.toString();
+      }
+      return res;
+    }
+    	
+    public static PizzaCreateDto toCreateDto(Pizza pizza) {
+        PizzaCreateDto dto = new PizzaCreateDto();
+        dto.setName(pizza.getName());
+        
+        return dto;
+    }
+
+    public static Pizza fromPizzaCreateDto(PizzaCreateDto dto) {
+        Pizza pizza = new Pizza();
+        pizza.setName(dto.getName());
+
+        return pizza;
+    }
+  }
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dao/PizzaDao.java b/src/main/java/fr/ulille/iut/pizzaland/dao/PizzaDao.java
new file mode 100644
index 0000000..39a1d9d
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dao/PizzaDao.java
@@ -0,0 +1,56 @@
+package fr.ulille.iut.pizzaland.dao;
+
+import java.util.List;
+
+import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
+import org.jdbi.v3.sqlobject.statement.GetGeneratedKeys;
+import org.jdbi.v3.sqlobject.statement.SqlQuery;
+import org.jdbi.v3.sqlobject.statement.SqlUpdate;
+import org.jdbi.v3.sqlobject.transaction.Transaction;
+
+import fr.ulille.iut.pizzaland.beans.Pizza;
+public interface PizzaDao {
+
+  @SqlUpdate("CREATE TABLE IF NOT EXISTS pizzas (id INTEGER PRIMARY KEY, name VARCHAR UNIQUE NOT NULL)")
+  void createPizzaTable();
+
+  @SqlUpdate("CREATE TABLE IF NOT EXISTS pizzaIngredientAssociation(idIngredient INTEGER, idPizza INTEGER, constraint pk_pizzaIA Primary key(idIngredient,idPizza))")
+  void createAssociationTable();
+
+  @Transaction
+  default void createPizzaAndAssociationTable(){
+      createAssociationTable();
+      createPizzaTable();
+  }
+
+  @SqlUpdate("DROP TABLE IF EXISTS pizzas")
+  void dropPizzaTable();
+  @SqlUpdate("DROP TABLE IF EXISTS pizzaIngredientAssociation")
+  void dropIngredientAssociationTable();
+
+  @Transaction
+  default void deletePizzaAndAssociationTable(){
+      dropIngredientAssociationTable();
+      dropPizzaTable();
+  }
+
+  @SqlUpdate("INSERT INTO pizzas (name) VALUES (:name)")
+  @GetGeneratedKeys
+  long insert(String name);
+
+  @SqlQuery("SELECT * FROM pizzas")
+  @RegisterBeanMapper(Pizza.class)
+  List<Pizza> getAll();
+
+  @SqlQuery("SELECT * FROM pizzas WHERE id = :id")
+  @RegisterBeanMapper(Pizza.class)
+  Pizza findById(long id);
+  
+  @SqlQuery("SELECT * FROM pizzas WHERE name = :name")
+  @RegisterBeanMapper(Pizza.class)
+  Pizza findByName(String name);
+
+  @SqlUpdate("DELETE FROM pizzas WHERE id = :id")
+  void remove(long id);
+
+}
\ No newline at end of file
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java
index b2a0dfd..9d3de51 100644
--- a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java
@@ -12,4 +12,5 @@ public class IngredientCreateDto {
 	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 f649021..2ebee6d 100644
--- a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java
@@ -21,5 +21,7 @@ public class IngredientDto {
     public String getName() {
       return name;
     }
+
+    
   }
   
\ No newline at end of file
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaCreateDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaCreateDto.java
new file mode 100644
index 0000000..19cce89
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaCreateDto.java
@@ -0,0 +1,28 @@
+package fr.ulille.iut.pizzaland.dto;
+
+import java.util.List;
+
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+
+public class PizzaCreateDto {
+	private String name;
+    private List<Ingredient> ingredients; 
+    
+	public PizzaCreateDto() {}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+    }
+    	
+	public void setIngredients(List<Ingredient> ingredients){
+        this.ingredients = ingredients;
+    }
+
+    public List<Ingredient> getIngredients(){
+        return this.ingredients;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaDto.java
new file mode 100644
index 0000000..aae5865
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaDto.java
@@ -0,0 +1,45 @@
+package fr.ulille.iut.pizzaland.dto;
+
+import java.util.List;
+
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+
+public class PizzaDto {
+    private long id;
+    private String name;
+    private List<Ingredient> ingredients; 
+
+    public PizzaDto() {}
+  
+    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;
+    }
+
+    public void setIngredients(List<Ingredient> ingredients){
+        this.ingredients = ingredients;
+    }
+
+    public void addIngredients(Ingredient ingredient){
+        this.ingredients.add(ingredient);
+    }
+
+    public void removeIngredients(Ingredient ingredient){
+        this.ingredients.remove(ingredient);
+    }
+
+    public List<Ingredient> getIngredients(){
+        return this.ingredients;
+    }
+  }
\ No newline at end of file
diff --git a/src/main/java/fr/ulille/iut/pizzaland/resources/PizzaResource.java b/src/main/java/fr/ulille/iut/pizzaland/resources/PizzaResource.java
new file mode 100644
index 0000000..b462022
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/resources/PizzaResource.java
@@ -0,0 +1,118 @@
+package fr.ulille.iut.pizzaland.resources;
+
+import java.net.URI;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import fr.ulille.iut.pizzaland.beans.Pizza;
+import fr.ulille.iut.pizzaland.BDDFactory;
+import fr.ulille.iut.pizzaland.dao.PizzaDao;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import fr.ulille.iut.pizzaland.dto.PizzaCreateDto;
+import fr.ulille.iut.pizzaland.dto.PizzaDto;
+
+@Path("/pizzas")
+public class PizzaResource {
+    private static final Logger LOGGER = Logger.getLogger(PizzaResource.class.getName());
+
+    List<PizzaDto> listPizzas=new ArrayList<PizzaDto>();
+
+    private PizzaDao pizzas;
+  
+   
+    @Context
+    public UriInfo uriInfo;
+
+    public PizzaResource() {
+        pizzas = BDDFactory.buildDao(PizzaDao.class);
+        pizzas.createPizzaAndAssociationTable();
+      }
+
+      @GET
+      public List<PizzaDto> getAll() {
+        LOGGER.info("PizzaResource:getAll");
+        List<Pizza> lp = pizzas.getAll();
+        List<PizzaDto> l= new ArrayList<PizzaDto>();
+        for (Pizza pizza: lp){
+            l.add(Pizza.toDto(pizza));
+        }
+        return l;
+      }
+
+
+      @GET
+      @Path("{id}")
+      public PizzaDto getOnePizza(@PathParam("id") long id) {
+        LOGGER.info("getOnePizza(" + id + ")");
+        try {
+            Pizza pizza= pizzas.findById(id);
+            return Pizza.toDto(pizza);
+        }
+        catch ( Exception e ) {
+            // Cette exception générera une réponse avec une erreur 404
+            throw new WebApplicationException(Response.Status.NOT_FOUND);
+        }
+      }
+
+      
+
+@POST
+public Response createPizza(PizzaCreateDto pizzaCreateDto) {
+    Pizza existing = pizzas.findByName(pizzaCreateDto.getName());
+    if ( existing != null ) {
+        throw new WebApplicationException(Response.Status.CONFLICT);
+    }
+    
+    try {
+        Pizza pizza = Pizza.fromPizzaCreateDto(pizzaCreateDto);
+        long id = pizzas.insert(pizza.getName());
+        pizza.setId(id);
+        PizzaDto pizzaDto = Pizza.toDto(pizza);
+
+        URI uri = uriInfo.getAbsolutePathBuilder().path("" + id).build();
+
+        return Response.created(uri).entity(pizzaDto).build();
+    }
+    catch ( Exception e ) {
+        e.printStackTrace();
+        throw new WebApplicationException(Response.Status.NOT_ACCEPTABLE);
+    }
+}
+
+    @DELETE
+    @Path("{id}")
+    public Response deletePizza(@PathParam("id") long id) {
+        if ( pizzas.findById(id) == null ) {
+            throw new WebApplicationException(Response.Status.NOT_FOUND);
+        }
+
+        pizzas.remove(id);
+
+        return Response.status(Response.Status.ACCEPTED).build();
+    }
+
+    @GET
+    @Path("{id}/name")
+    public String getPizzaName(@PathParam("id") long id) {
+    Pizza pizza = pizzas.findById(id);
+	if ( pizza == null ) {
+		throw new WebApplicationException(Response.Status.NOT_FOUND);
+	}
+        
+	return pizza.getName();
+}
+
+
+}
\ No newline at end of file
diff --git a/src/main/resources/ingredients.json b/src/main/resources/ingredients.json
index fdc8446..78f1058 100644
--- a/src/main/resources/ingredients.json
+++ b/src/main/resources/ingredients.json
@@ -3,6 +3,7 @@
 { "name": "jambon"},
 { "name": "champignons"},
 { "name": "olives"},
+{ "name":"saumon"},
 { "name": "tomate"},
 { "name": "merguez"},
 { "name": "lardons"},
diff --git a/src/main/resources/pizza.json b/src/main/resources/pizza.json
new file mode 100644
index 0000000..4e81a2f
--- /dev/null
+++ b/src/main/resources/pizza.json
@@ -0,0 +1,5 @@
+[
+{"name":"calzone","ingredient":"tomate"},
+{"name":"savoyarde","ingredient":"fromage"},
+{"name":"nordique","ingredient":"saumon"}
+]
\ No newline at end of file
diff --git a/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java b/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java
index 5f1f971..8b8c7ee 100644
--- a/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java
+++ b/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java
@@ -71,7 +71,7 @@ public class IngredientResourceTest extends JerseyTest {
                 // On vérifie que la liste est bien vide 
                 assertEquals(0, ingredients.size());
         }
-
+        
         @Test
         public void testGetExistingIngredient() {
 
@@ -91,7 +91,7 @@ public class IngredientResourceTest extends JerseyTest {
 
         @Test
         public void testGetNotExistingPizza() {
-                Response response = target("/pizzas/125").request().get();
+                Response response = target("/ingredients/125").request().get();
                 assertEquals(Response.Status.NOT_FOUND.getStatusCode(),response.getStatus());
         }
 
diff --git a/src/test/java/fr/ulille/iut/pizzaland/PizzaResourceTest.java b/src/test/java/fr/ulille/iut/pizzaland/PizzaResourceTest.java
new file mode 100644
index 0000000..830519e
--- /dev/null
+++ b/src/test/java/fr/ulille/iut/pizzaland/PizzaResourceTest.java
@@ -0,0 +1,190 @@
+package fr.ulille.iut.pizzaland;
+
+import fr.ulille.iut.pizzaland.ApiV1;
+import fr.ulille.iut.pizzaland.dao.*;
+import fr.ulille.iut.pizzaland.dto.*;
+import fr.ulille.iut.pizzaland.beans.*;
+import fr.ulille.iut.pizzaland.resources.*;
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+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;
+import javax.ws.rs.core.Response;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+/*
+ * 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 PizzaResourceTest extends JerseyTest {
+        private static final Logger LOGGER = Logger.getLogger(PizzaResourceTest.class.getName());
+        private PizzaDao 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(PizzaDao.class);
+                dao.createPizzaAndAssociationTable();
+        }
+
+        @After
+        public void tearEnvDown() throws Exception {
+                dao.deletePizzaAndAssociationTable();
+        }
+
+        @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("/pizzas").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<PizzaDto> pizza;
+                pizza = response.readEntity(new GenericType<List<PizzaDto>>(){});
+
+                // On vérifie que la liste est bien vide 
+                assertEquals(0, pizza.size());
+        }
+
+        @Test
+        public void testGetExistingPizza() {
+
+                Pizza pizza = new Pizza();
+                pizza.setName("Chorizo");
+
+                long id = dao.insert(pizza.getName());
+                pizza.setId(id);
+
+                Response response = target("/pizzas/" + id).request().get();
+
+                assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+                Pizza result = Pizza.fromDto(response.readEntity(PizzaDto.class));
+                assertEquals(pizza, result);
+        }
+
+        @Test
+        public void testGetNotExistingPizza() {
+                Response response = target("/pizzas/125").request().get();
+                assertEquals(Response.Status.NOT_FOUND.getStatusCode(),response.getStatus());
+        }
+
+        @Test
+        public void testCreatePizza() {
+        PizzaCreateDto PizzaCreateDto = new PizzaCreateDto();
+        PizzaCreateDto.setName("Chorizo");
+
+        Response response = target("/pizzas")
+                .request()
+                .post(Entity.json(PizzaCreateDto));
+
+        // On vérifie le code de status à 201
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+
+        PizzaDto returnedEntity = response.readEntity(PizzaDto.class);
+
+        // On vérifie que le champ d'entête Location correspond à
+        // l'URI de la nouvelle entité
+        assertEquals(target("/pizzas/" +
+                        returnedEntity.getId()).getUri(), response.getLocation());
+                
+                // On vérifie que le nom correspond
+        assertEquals(returnedEntity.getName(), PizzaCreateDto.getName());
+        }
+
+        @Test
+        public void testCreateSamePizza() {
+        PizzaCreateDto pizzaCreateDto = new PizzaCreateDto();
+        pizzaCreateDto.setName("Chorizo");
+        dao.insert(pizzaCreateDto.getName());
+
+        Response response = target("/pizzas")
+                .request()
+                .post(Entity.json(pizzaCreateDto));
+
+        assertEquals(Response.Status.CONFLICT.getStatusCode(), response.getStatus());
+        }
+
+        @Test
+        public void testCreatePizzaWithoutName() {
+        PizzaCreateDto pizzaCreateDto = new PizzaCreateDto();
+
+        Response response = target("/pizzas")
+                .request()
+                .post(Entity.json(pizzaCreateDto));
+
+        assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+        }
+        ////////////////////////////
+        @Test
+        public void testDeleteExistingPizza() {
+        Pizza pizza = new Pizza();
+        pizza.setName("Chorizo");
+        long id = dao.insert(pizza.getName());
+        pizza.setId(id);
+
+        Response response = target("/pizzas/" + id).request().delete();
+
+        assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus());
+
+        Pizza result = dao.findById(id);
+        assertEquals(result, null);
+        }
+
+        @Test
+        public void testDeleteNotExistingPizza() {
+        Response response = target("/pizzas/125").request().delete();
+        assertEquals(Response.Status.NOT_FOUND.getStatusCode(),response.getStatus());
+        }
+
+        @Test
+        public void testGetPizzaName() {
+        Pizza pizza = new Pizza();
+        pizza.setName("mozzarella");
+        long id = dao.insert(pizza.getName());
+
+        Response response = target("pizzas/" + id + "/name").request().get();
+
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+        assertEquals("mozzarella", response.readEntity(String.class));
+        }
+
+        @Test
+        public void testGetNotExistingPizzaName() {
+        Response response = target("pizzas/125/name").request().get();
+
+        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
+        }
+
+        @Test
+        public void testGetPizzaIngredients(){
+                
+        }
+    }
-- 
GitLab