From 9d3430557caa7d193d1b0391a33157902fa94a19 Mon Sep 17 00:00:00 2001 From: Imanol Date: Thu, 7 Mar 2019 22:37:47 +0100 Subject: [PATCH] =?UTF-8?q?A=C3=B1ade=20funcionalidad=20de=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/mysql-with-inserts.sql | 2 +- db/mysql.sql | 2 +- .../java/es/uvigo/esei/daa/entities/Pet.java | 26 ++- .../uvigo/esei/daa/dataset/PetsDataset.java | 66 +++++++ .../uvigo/esei/daa/entities/PetUnitTest.java | 82 +++++++++ .../uvigo/esei/daa/matchers/IsEqualToPet.java | 56 ++++++ .../uvigo/esei/daa/rest/PetResourceTest.java | 170 ++++++++++++++++++ src/test/resources/datasets/dataset-add.xml | 6 + .../resources/datasets/dataset-delete.xml | 5 + .../resources/datasets/dataset-modify.xml | 5 + src/test/resources/datasets/dataset.dtd | 8 +- src/test/resources/datasets/dataset.xml | 5 + src/test/resources/db/hsqldb-drop.sql | 1 + src/test/resources/db/hsqldb.sql | 8 + 14 files changed, 435 insertions(+), 7 deletions(-) create mode 100644 src/test/java/es/uvigo/esei/daa/dataset/PetsDataset.java create mode 100644 src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java create mode 100644 src/test/java/es/uvigo/esei/daa/matchers/IsEqualToPet.java create mode 100644 src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java diff --git a/db/mysql-with-inserts.sql b/db/mysql-with-inserts.sql index 9ce53af..201521d 100644 --- a/db/mysql-with-inserts.sql +++ b/db/mysql-with-inserts.sql @@ -19,7 +19,7 @@ CREATE TABLE `daaexample`.`pets` ( `name` varchar(50) NOT NULL, `peopleID` int NOT NULL, PRIMARY KEY (`id`), - FOREIGN KEY (`peopleID`) REFERENCES people(id) + CONSTRAINT FK_PeoplePet FOREIGN KEY (`peopleID`) REFERENCES people(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa'; diff --git a/db/mysql.sql b/db/mysql.sql index 420a55b..fccfc56 100644 --- a/db/mysql.sql +++ b/db/mysql.sql @@ -19,7 +19,7 @@ CREATE TABLE `daaexample`.`pets` ( `name` varchar(50) NOT NULL, `peopleID` int NOT NULL, PRIMARY KEY (`id`), - FOREIGN KEY (`peopleID`) REFERENCES people(id) + CONSTRAINT FK_PeoplePet FOREIGN KEY (`peopleID`) REFERENCES people(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa'; diff --git a/src/main/java/es/uvigo/esei/daa/entities/Pet.java b/src/main/java/es/uvigo/esei/daa/entities/Pet.java index 2a1c3d1..59431ef 100644 --- a/src/main/java/es/uvigo/esei/daa/entities/Pet.java +++ b/src/main/java/es/uvigo/esei/daa/entities/Pet.java @@ -25,10 +25,6 @@ public class Pet { return id; } - public void setId(int id) { - this.id = id; - } - public String getName() { return name; } @@ -44,4 +40,26 @@ public class Pet { public void setPeopleID(int peopleID) { this.peopleID = requireNonNull(peopleID, "PeopleID can't be null"); } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + id; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof Pet)) + return false; + Pet other = (Pet) obj; + if (id != other.id) + return false; + return true; + } } diff --git a/src/test/java/es/uvigo/esei/daa/dataset/PetsDataset.java b/src/test/java/es/uvigo/esei/daa/dataset/PetsDataset.java new file mode 100644 index 0000000..d78b544 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/dataset/PetsDataset.java @@ -0,0 +1,66 @@ +package es.uvigo.esei.daa.dataset; + +import static java.util.Arrays.binarySearch; +import static java.util.Arrays.stream; + +import java.util.Arrays; +import java.util.function.Predicate; + +import es.uvigo.esei.daa.entities.Pet; + +public final class PetsDataset { + + private PetsDataset() {} + + public static Pet[] pets() { + return new Pet[] { + new Pet(1, "Test", 1), + new Pet(2, "Toby", 1), + new Pet(3, "Nala", 2), + new Pet(4, "Name", 4) + }; + } + + public static Pet[] petWithout(int ... ids) { + Arrays.sort(ids); + + final Predicate hasValidId = pet -> binarySearch(ids, pet.getId()) < 0; + + return stream(pets()).filter(hasValidId).toArray(Pet[]::new); + } + + public static Pet pet(int id) { + return stream(pets()) + .filter(pet -> pet.getId() == id) + .findAny() + .orElseThrow(IllegalArgumentException::new); + } + + public static int existentId() { + return 2; + } + + public static int nonExistentId() { + return 132; + } + + public static Pet existentPet() { + return pet(existentId()); + } + + public static Pet nonExistentPet() { + return new Pet(nonExistentId(), "Toby", 1); + } + + public static String newName() { + return "Test"; + } + + public static int newPeopleID() { + return 3; + } + + public static Pet newPet() { + return new Pet(pets().length + 1, newName(), newPeopleID()); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java b/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java new file mode 100644 index 0000000..e27a40e --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java @@ -0,0 +1,82 @@ +package es.uvigo.esei.daa.entities; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; + +public class PetUnitTest { + + @Test + public void testPetIntStringInt() { + final int id = 1; + final String name = "Test"; + final int peopleID = 1; + + final Pet pet = new Pet(id, name, peopleID); + + assertThat(pet.getId(), is(equalTo(id))); + assertThat(pet.getName(), is(equalTo(name))); + assertThat(pet.getPeopleID(), is(equalTo(peopleID))); + } + + @Test(expected = NullPointerException.class) + public void testPetNullName() { + new Pet(1, null, 1); + } + + @Test + public void testSetName() { + final int id = 1; + final int peopleID = 1; + + final Pet pet = new Pet(id, "Test", peopleID); + pet.setName("Another Name"); + + assertThat(pet.getId(), is(equalTo(id))); + assertThat(pet.getName(), is(equalTo("Another Name"))); + assertThat(pet.getPeopleID(), is(equalTo(peopleID))); + } + + @Test(expected = NullPointerException.class) + public void testSetNullName() { + final Pet pet = new Pet(1, "Test", 1); + + pet.setName(null); + } + + @Test + public void testSetPeopleID() { + final int id = 1; + final String name = "Test"; + + final Pet pet = new Pet(id, name, 2); + pet.setPeopleID(1); + + assertThat(pet.getId(), is(equalTo(id))); + assertThat(pet.getName(), is(equalTo(name))); + assertThat(pet.getPeopleID(), is(equalTo(1))); + } + + @Test + public void testEqualsObject() { + final Pet pet1 = new Pet(1, "Test 1", 1); + final Pet pet2 = new Pet(1, "Test 2", 2); + + assertTrue(pet1.equals(pet2)); + } + + @Test + public void testEqualsHashcode() { + EqualsVerifier.forClass(Pet.class) + .withIgnoredFields("name", "peopleID") + .suppress(Warning.STRICT_INHERITANCE) + .suppress(Warning.NONFINAL_FIELDS) + .verify(); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/matchers/IsEqualToPet.java b/src/test/java/es/uvigo/esei/daa/matchers/IsEqualToPet.java new file mode 100644 index 0000000..67db279 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/matchers/IsEqualToPet.java @@ -0,0 +1,56 @@ +package es.uvigo.esei.daa.matchers; + +import org.hamcrest.Factory; +import org.hamcrest.Matcher; + +import es.uvigo.esei.daa.entities.Pet; + +public class IsEqualToPet extends IsEqualToEntity { + + public IsEqualToPet(Pet entity) { + super(entity); + } + + @Override + protected boolean matchesSafely(Pet item) { + this.clearDescribeTo(); + + if(item == null) { + this.addTemplatedDescription("item", expected.toString()); + return false; + } else { + return checkAttribute("id", Pet::getId, item) + && checkAttribute("name", Pet::getName, item) + && checkAttribute("surname", Pet::getPeopleID, item); + } + } + + /** + * Factory method that creates a new {@link IsEqualToEntity} matcher with + * the provided {@link Pet} as the expected value. + * + * @param pet the expected pet. + * @return a new {@link IsEqualToEntity} matcher with the provided + * {@link Pet} as the expected value. + */ + @Factory + public static IsEqualToPet equalsToPet(Pet pet) { + return new IsEqualToPet(pet); + } + + /** + * Factory method that returns a new {@link Matcher} that includes several + * {@link IsEqualToPet} matchers, each one using an {@link Pet} of the + * provided ones as the expected value. + * + * @param pets the pets to be used as the expected values. + * @return a new {@link Matcher} that includes several + * {@link IsEqualToPet} matchers, each one using an {@link Pet} of the + * provided ones as the expected value. + * @see IsEqualToEntity#containsEntityInAnyOrder(java.util.function.Function, Object...) + */ + @Factory + public static Matcher> containsPetsInAnyOrder(Pet ... pets) { + return containsEntityInAnyOrder(IsEqualToPet::equalsToPet, pets); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java b/src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java new file mode 100644 index 0000000..1d2b406 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java @@ -0,0 +1,170 @@ +package es.uvigo.esei.daa.rest; + +import static es.uvigo.esei.daa.dataset.UsersDataset.adminLogin; +import static es.uvigo.esei.daa.dataset.UsersDataset.normalLogin; +import static es.uvigo.esei.daa.dataset.UsersDataset.userToken; +import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasBadRequestStatus; +import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasOkStatus; +import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasUnauthorized; +import static org.junit.Assert.assertThat; +import static es.uvigo.esei.daa.dataset.PetsDataset.*; +import static es.uvigo.esei.daa.matchers.IsEqualToPet.*; +import static javax.ws.rs.client.Entity.entity; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.equalTo; + +import java.io.IOException; +import java.util.List; + +import javax.sql.DataSource; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import com.github.springtestdbunit.DbUnitTestExecutionListener; +import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.github.springtestdbunit.annotation.ExpectedDatabase; + +import es.uvigo.esei.daa.DAAExampleTestApplication; +import es.uvigo.esei.daa.entities.Pet; +import es.uvigo.esei.daa.listeners.ApplicationContextBinding; +import es.uvigo.esei.daa.listeners.ApplicationContextJndiBindingTestExecutionListener; +import es.uvigo.esei.daa.listeners.DbManagement; +import es.uvigo.esei.daa.listeners.DbManagementTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:contexts/mem-context.xml") +@TestExecutionListeners({ + DbUnitTestExecutionListener.class, + DbManagementTestExecutionListener.class, + ApplicationContextJndiBindingTestExecutionListener.class +}) +@ApplicationContextBinding( + jndiUrl = "java:/comp/env/jdbc/daaexample", + type = DataSource.class +) +@DbManagement( + create = "classpath:db/hsqldb.sql", + drop = "classpath:db/hsqldb-drop.sql" +) +@DatabaseSetup("/datasets/dataset.xml") +@ExpectedDatabase("/datasets/dataset.xml") +public class PetResourceTest extends JerseyTest { + + @Override + protected Application configure() { + return new DAAExampleTestApplication(); + } + + @Override + protected void configureClient(ClientConfig config) { + super.configureClient(config); + + // Enables JSON transformation in client + config.register(JacksonJsonProvider.class); + config.property("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE); + } + + @Test + public void testListAll() throws IOException { + final Response response = target("pets").request() + .header("Authorization", "Basic " + userToken(adminLogin())) + .get(); + assertThat(response, hasOkStatus()); + + final List pets = response.readEntity(new GenericType>(){}); + assertThat(pets, containsPetsInAnyOrder(pets())); + } + + @Test + public void testListAllUnauthorized() throws IOException { + final Response response = target("pets").request() + .header("Authorization", "Basic " + userToken(normalLogin())) + .get(); + assertThat(response, hasUnauthorized()); + } + + @Test + public void testGet() throws IOException { + final Response response = target("pets/" + existentId()).request() + .header("Authorization", "Basic " + userToken(adminLogin())) + .get(); + assertThat(response, hasOkStatus()); + + final Pet pet = response.readEntity(Pet.class); + + assertThat(pet, is(equalsToPet(existentPet()))); + } + + @Test + public void testGetUnauthorized() throws IOException { + final Response response = target("pets/" + existentId()).request() + .header("Authorization", "Basic " + userToken(normalLogin())) + .get(); + assertThat(response, hasUnauthorized()); + } + + @Test + public void testGetInvalidId() throws IOException { + final Response response = target("pets/" + nonExistentId()).request() + .header("Authorization", "Basic " + userToken(adminLogin())) + .get(); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + public void testModifyName() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + + final Response response = target("pets/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(adminLogin())) + .put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + @ExpectedDatabase("/datasets/dataset-delete.xml") + public void testDelete() throws IOException { + final Response response = target("pets/" + existentId()).request() + .header("Authorization", "Basic " + userToken(adminLogin())) + .delete(); + + assertThat(response, hasOkStatus()); + + final Integer deletedId = response.readEntity(Integer.class); + + assertThat(deletedId, is(equalTo(existentId()))); + } + + @Test + public void testDeleteUnauthorized() throws IOException { + final Response response = target("pets/" + existentId()).request() + .header("Authorization", "Basic " + userToken(normalLogin())) + .delete(); + + assertThat(response, hasUnauthorized()); + } + + @Test + public void testDeleteInvalidId() throws IOException { + final Response response = target("pets/" + nonExistentId()).request() + .header("Authorization", "Basic " + userToken(adminLogin())) + .delete(); + + assertThat(response, hasBadRequestStatus()); + } +} diff --git a/src/test/resources/datasets/dataset-add.xml b/src/test/resources/datasets/dataset-add.xml index 9a75a99..86382db 100644 --- a/src/test/resources/datasets/dataset-add.xml +++ b/src/test/resources/datasets/dataset-add.xml @@ -16,4 +16,10 @@ + + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-delete.xml b/src/test/resources/datasets/dataset-delete.xml index e49223d..2f5732f 100644 --- a/src/test/resources/datasets/dataset-delete.xml +++ b/src/test/resources/datasets/dataset-delete.xml @@ -14,4 +14,9 @@ + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-modify.xml b/src/test/resources/datasets/dataset-modify.xml index 6e2dfc9..1eddcc0 100644 --- a/src/test/resources/datasets/dataset-modify.xml +++ b/src/test/resources/datasets/dataset-modify.xml @@ -15,4 +15,9 @@ + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset.dtd b/src/test/resources/datasets/dataset.dtd index e64500f..e827cca 100644 --- a/src/test/resources/datasets/dataset.dtd +++ b/src/test/resources/datasets/dataset.dtd @@ -1,7 +1,8 @@ - + + + diff --git a/src/test/resources/datasets/dataset.xml b/src/test/resources/datasets/dataset.xml index 3f48cc9..58ce036 100644 --- a/src/test/resources/datasets/dataset.xml +++ b/src/test/resources/datasets/dataset.xml @@ -15,4 +15,9 @@ + + + + + \ No newline at end of file diff --git a/src/test/resources/db/hsqldb-drop.sql b/src/test/resources/db/hsqldb-drop.sql index 31f8643..867d387 100644 --- a/src/test/resources/db/hsqldb-drop.sql +++ b/src/test/resources/db/hsqldb-drop.sql @@ -1,2 +1,3 @@ +DROP TABLE Pets IF EXISTS; DROP TABLE People IF EXISTS; DROP TABLE Users IF EXISTS; diff --git a/src/test/resources/db/hsqldb.sql b/src/test/resources/db/hsqldb.sql index a629441..5fd9bf9 100644 --- a/src/test/resources/db/hsqldb.sql +++ b/src/test/resources/db/hsqldb.sql @@ -10,4 +10,12 @@ CREATE TABLE users ( password VARCHAR(64) NOT NULL, role VARCHAR(5) NOT NULL, PRIMARY KEY (login) +); + +CREATE TABLE pets ( + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, + name varchar(50) NOT NULL, + peopleID int NOT NULL, + PRIMARY KEY (id), + CONSTRAINT FK_PeoplePet FOREIGN KEY (peopleID) REFERENCES people(id) ); \ No newline at end of file -- 2.18.1