diff --git a/src/test/java/es/uvigo/esei/daa/dao/PetsDAOTest.java b/src/test/java/es/uvigo/esei/daa/dao/PetsDAOTest.java new file mode 100644 index 0000000000000000000000000000000000000000..21de371411ff932525a57a627d18723cf1a20314 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/dao/PetsDAOTest.java @@ -0,0 +1,126 @@ +package es.uvigo.esei.daa.dao; +import javax.sql.DataSource; + +import es.uvigo.esei.daa.entities.Pet; +import org.junit.Before; +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 static es.uvigo.esei.daa.dataset.PeopleDataset.nonExistentId; +import static es.uvigo.esei.daa.dataset.PetsDataset.*; +import com.github.springtestdbunit.DbUnitTestExecutionListener; +import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.github.springtestdbunit.annotation.ExpectedDatabase; + +import static es.uvigo.esei.daa.matchers.IsEqualToPet.containsPetsInAnyOrder; +import static es.uvigo.esei.daa.matchers.IsEqualToPet.equalsToPet; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +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-pet.xml") +@ExpectedDatabase("/datasets/dataset-pet.xml") +public class PetsDAOTest { + private PetDAO dao; + + @Before + public void setUp() throws Exception { + this.dao = new PetDAO(); + } + + @Test + public void testList() throws DAOException { + assertThat(this.dao.list(), containsPetsInAnyOrder(pets())); + } + + @Test + public void testGet() throws DAOException { + final Pet pet = this.dao.get(existentId()); + assertThat(pet, is(equalsToPet(existentPet()))); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetNonExistentId() throws DAOException { + this.dao.get(nonExistentId()); + } + @Test + @ExpectedDatabase("/datasets/dataset-pet-delete.xml") + public void testDelete() throws DAOException { + this.dao.delete(existentId()); + } + + @Test(expected = IllegalArgumentException.class) + public void testDeleteNonExistentId() throws DAOException { + this.dao.delete(nonExistentId()); + } + + @Test + @ExpectedDatabase("/datasets/dataset-pet-modify.xml") + public void testModify() throws DAOException { + final Pet pet = existentPet(); + pet.setName(newName()); + pet.setType(newType()); + pet.setPerson(newPerson()); + + this.dao.modify(pet); + + final Pet persistentPerson = this.dao.get(pet.getId()); + + assertThat(persistentPerson, is(equalsToPet(pet))); + } + + @Test(expected = IllegalArgumentException.class) + public void testModifyNonExistentId() throws DAOException { + this.dao.modify(nonExistentPet()); + } + + @Test(expected = IllegalArgumentException.class) + public void testModifyNullPet() throws DAOException { + this.dao.modify(null); + } + + @Test + @ExpectedDatabase("/datasets/dataset-pet-add.xml") + public void testAdd() throws DAOException { + final Pet pet = this.dao.add(newName(), newType(),newPerson()); + + assertThat(pet, is(equalsToPet(newPet()))); + + final Pet persistentPet = this.dao.get(pet.getId()); + + assertThat(persistentPet, is(equalsToPet(newPet()))); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddNullName() throws DAOException { + this.dao.add(null, newType(),newPerson()); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddNullType() throws DAOException { + this.dao.add(newName(), null,newPerson()); + } + +} diff --git a/src/test/java/es/uvigo/esei/daa/dao/PetsDAOUnitTest.java b/src/test/java/es/uvigo/esei/daa/dao/PetsDAOUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6c35f12f586facfbde0ea39864ab01e320795258 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/dao/PetsDAOUnitTest.java @@ -0,0 +1,267 @@ +package es.uvigo.esei.daa.dao; + +import java.sql.SQLException; + +import org.junit.Test; + +import com.mysql.jdbc.Statement; + +import es.uvigo.esei.daa.entities.Pet; +import es.uvigo.esei.daa.util.DatabaseQueryUnitTest; + +import static es.uvigo.esei.daa.dataset.PetsDataset.*; +import static es.uvigo.esei.daa.matchers.IsEqualToPet.containsPetsInAnyOrder; +import static es.uvigo.esei.daa.matchers.IsEqualToPet.equalsToPet; +import static org.easymock.EasyMock.expect; + +import static org.easymock.EasyMock.anyString; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.reset; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class PetsDAOUnitTest extends DatabaseQueryUnitTest { + @Test + public void testList() throws Exception { + final Pet[] pets = pets(); + + for (Pet pet : pets) { + expectPetRow(pet); + } + expect(result.next()).andReturn(false); + result.close(); + + replayAll(); + final PetDAO petsDAO = new PetDAO(); + + assertThat(petsDAO.list(), containsPetsInAnyOrder(pets)); + } + + @Test(expected = DAOException.class) + public void testListUnexpectedException() throws Exception { + expect(result.next()).andThrow(new SQLException()); + result.close(); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.list(); + } + + @Test + public void testGet() throws Exception { + final Pet existentPet = existentPet(); + + expectPetRow(existentPet); + result.close(); + + replayAll(); + + final PetDAO petDAO = new PetDAO(); + Pet prueba = petDAO.get(existentId()); + System.out.println(prueba.getId()); + System.out.println(existentPet.getId()); + System.out.println(prueba.getName()); + System.out.println(existentPet.getName()); + System.out.println(existentPet.getType()); + System.out.println(prueba.getType()); + System.out.println(prueba.getPerson()); + System.out.println(existentPet.getPerson()); + + System.out.println(prueba.equals(existentPet)); + + assertThat(prueba, is(equalTo(existentPet))); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetMissing() throws Exception { + expect(result.next()).andReturn(false); + result.close(); + + replayAll(); + + final PetDAO petsDao = new PetDAO(); + petsDao.get(existentId()); + } + + @Test(expected = DAOException.class) + public void testGetUnexpectedException() throws Exception { + expect(result.next()).andThrow(new SQLException()); + result.close(); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.get(existentId()); + } + + @Test + public void testAdd() throws Exception { + final Pet pet = newPet(); + reset(connection); + expect(connection.prepareStatement(anyString(), eq(Statement.RETURN_GENERATED_KEYS))) + .andReturn(statement); + expect(statement.executeUpdate()).andReturn(1); + expect(statement.getGeneratedKeys()).andReturn(result); + + // Key retrieval + expect(result.next()).andReturn(true); + expect(result.getInt(1)).andReturn(pet.getId()); + connection.close(); + result.close(); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + final Pet newPet = petsDAO.add(pet.getName(), pet.getType(),pet.getPerson()); + + assertThat(newPet, is(equalsToPet(pet))); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddNullName() throws Exception { + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + + resetAll(); // No expectations + + petsDAO.add(null, newType(),newPerson()); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddNullType() throws Exception { + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + + resetAll(); // No expectations + + petsDAO.add(newName(), null,newPerson()); + } + + @Test(expected = DAOException.class) + public void testAddZeroUpdatedRows() throws Exception { + reset(connection); + expect(connection.prepareStatement(anyString(), eq(1))) + .andReturn(statement); + expect(statement.executeUpdate()).andReturn(0); + connection.close(); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.add(newName(), newType(), newPerson()); + } + + @Test(expected = DAOException.class) + public void testAddNoGeneratedKey() throws Exception { + reset(connection); + expect(connection.prepareStatement(anyString(), eq(1))) + .andReturn(statement); + expect(statement.executeUpdate()).andReturn(1); + expect(statement.getGeneratedKeys()).andReturn(result); + expect(result.next()).andReturn(false); + result.close(); + connection.close(); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.add(newName(), newType(),newPerson()); + } + + @Test(expected = DAOException.class) + public void testAddUnexpectedException() throws Exception { + reset(connection); + expect(connection.prepareStatement(anyString(), eq(1))) + .andReturn(statement); + expect(statement.executeUpdate()).andThrow(new SQLException()); + connection.close(); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.add(newName(), newType(),newPerson()); + } + + @Test + public void testDelete() throws Exception { + expect(statement.executeUpdate()).andReturn(1); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.delete(existentId()); + } + + @Test(expected = IllegalArgumentException.class) + public void testDeleteInvalidId() throws Exception { + expect(statement.executeUpdate()).andReturn(0); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.delete(existentId()); + } + + @Test(expected = DAOException.class) + public void testDeleteUnexpectedException() throws Exception { + expect(statement.executeUpdate()).andThrow(new SQLException()); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.delete(existentId()); + } + + @Test + public void testModify() throws Exception { + expect(statement.executeUpdate()).andReturn(1); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.modify(existentPet()); + } + + @Test(expected = IllegalArgumentException.class) + public void testModifyNullPet() throws Exception { + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + + resetAll(); // No expectations + + petsDAO.modify(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testModifyZeroUpdatedRows() throws Exception { + expect(statement.executeUpdate()).andReturn(0); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.modify(existentPet()); + } + + @Test(expected = DAOException.class) + public void testModifyUnexpectedException() throws Exception { + expect(statement.executeUpdate()).andThrow(new SQLException()); + + replayAll(); + + final PetDAO petsDAO = new PetDAO(); + petsDAO.modify(existentPet()); + } + + private void expectPetRow(Pet pet) throws SQLException { + expect(result.next()).andReturn(true); + expect(result.getInt("id")).andReturn(pet.getId()); + expect(result.getString("name")).andReturn(pet.getName()); + expect(result.getString("type")).andReturn(pet.getType()); + expect(result.getInt("person")).andReturn(pet.getPerson()); + } +} 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 0000000000000000000000000000000000000000..dab3b76e7602949a6bb46b13df7bf38c95199821 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/dataset/PetsDataset.java @@ -0,0 +1,80 @@ +package es.uvigo.esei.daa.dataset; + +import es.uvigo.esei.daa.entities.Pet; + +import java.util.Arrays; +import java.util.function.Predicate; + +import static java.util.Arrays.binarySearch; +import static java.util.Arrays.stream; + +public class PetsDataset { + private PetsDataset(){} + + public static Pet[] pets(){ + return new Pet[]{ + new Pet(1,"perro1","dog",1), + new Pet(2,"perro2","dog",2), + new Pet(3,"perro3","dog",3), + new Pet(4,"perro4","dog",4), + new Pet(5,"perro5","dog",5), + new Pet(6,"perro6","dog",6), + new Pet(7,"perro7","dog",7), + new Pet(8,"perro8","dog",8), + new Pet(9,"perro9","dog",9), + new Pet(10,"perro10","dog",10) + }; + } + public static Pet[] petsWithout(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 5; + } + public static int existentOwner(){ + return 5; + } + + public static int nonExistentId() { + return 1234; + } + + public static Pet existentPet() { + return pet(existentId()); + } + + public static Pet nonExistentPet() { + return new Pet(nonExistentId(), "perro1", "dog",1); + } + + public static String newName() { + return "perro11"; + } + + public static String newType() { + return "dog"; + } + public static int newPerson() { + return 11; + } + + public static Pet newPet() { + return new Pet(pets().length + 1, newName(), newType(),newPerson()); + } +} + + 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 0000000000000000000000000000000000000000..84a5bbec789db5d3a362a3051e6f1f2c8bdf418c --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java @@ -0,0 +1,81 @@ +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 testPetIntStringStringInt(){ + final int id = 1; + final String name = "Boby"; + final String type = "dog"; + final int person = 1; + + final Pet pet = new Pet(id,name,type,person); + + assertThat(pet.getId(),is(equalTo(id))); + assertThat(pet.getName(),is(equalTo(name))); + assertThat(pet.getType(),is(equalTo(type))); + assertThat(pet.getPerson(),is(equalTo(person))); + } + + @Test(expected = NullPointerException.class) + public void testPetIntStringStringIntNullName() { + new Pet(1, null, "dog",1); + } + + @Test(expected = NullPointerException.class) + public void testPetIntStringStringIntNullType() { + new Pet(1, "Boby", null,1); + } + + @Test(expected = NullPointerException.class) + public void testPetIntStringStringIntNullPerson() { + Integer person = null; + new Pet(1, "John", "dog",person); + } + + @Test + public void testSetName() { + final int id = 1; + final String type = "Dog"; + + final Pet pet = new Pet(id, "Boby", type,id); + pet.setName("Juan"); + + assertThat(pet.getId(), is(equalTo(id))); + assertThat(pet.getName(), is(equalTo("Juan"))); + assertThat(pet.getType(), is(equalTo(type))); + } + + @Test(expected = NullPointerException.class) + public void testSetNullType() { + final Pet pet = new Pet(1, "Boby", "Dog",1); + + pet.setType(null); + } + + @Test + public void testEqualsObject() { + final Pet petA = new Pet(1, "Name A", "Surname A",1); + final Pet petB = new Pet(1, "Name B", "Surname B",1); + + assertTrue(petA.equals(petB)); + } + + @Test + public void testEqualsHashcode() { + EqualsVerifier.forClass(Pet.class) + .withIgnoredFields("name", "type", "person") + .suppress(Warning.STRICT_INHERITANCE) + .suppress(Warning.NONFINAL_FIELDS) + .verify(); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java b/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java index b2144df2ce1c5c1aaebd61932c0334430991cddc..685f86d69d0268249546c29541b8991a3359445e 100644 --- a/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java +++ b/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java @@ -59,6 +59,11 @@ public class AuthorizationFilter implements ContainerRequestFilter { } else { requestContext.setSecurityContext(new UserSecurityContext(user)); } + if (isPetsPath(requestContext) && !user.getRole().equals("ADMIN")) { + requestContext.abortWith(createResponse()); + } else { + requestContext.setSecurityContext(new UserSecurityContext(user)); + } } else { requestContext.abortWith(createResponse()); } @@ -75,6 +80,11 @@ public class AuthorizationFilter implements ContainerRequestFilter { final List pathSegments = context.getUriInfo().getPathSegments(); return !pathSegments.isEmpty() && pathSegments.get(0).getPath().equals("people"); } + + private static boolean isPetsPath(ContainerRequestContext context) { + final List pathSegments = context.getUriInfo().getPathSegments(); + return !pathSegments.isEmpty() && pathSegments.get(0).getPath().equals("pets"); + } private static Response createResponse() { return Response.status(Status.UNAUTHORIZED) 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 0000000000000000000000000000000000000000..b78267fbd4a57b4471b2892d5d30f4f2e95c15d6 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/matchers/IsEqualToPet.java @@ -0,0 +1,56 @@ +package es.uvigo.esei.daa.matchers; + +import es.uvigo.esei.daa.entities.Pet; +import org.hamcrest.Factory; +import org.hamcrest.Matcher; + +public class IsEqualToPet extends IsEqualToEntity { + public IsEqualToPet(Pet entity) { + super(entity); + } + + @Override + protected boolean matchesSafely(Pet actual) { + this.clearDescribeTo(); + + if (actual == null) { + this.addTemplatedDescription("actual", expected.toString()); + return false; + } else { + return checkAttribute("id", Pet::getId, actual) + && checkAttribute("name", Pet::getName, actual) + && checkAttribute("type", Pet::getType, actual) + && checkAttribute("person", Pet::getPerson, actual); + } + } + + /** + * 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/PeopleResourceTest.java b/src/test/java/es/uvigo/esei/daa/rest/PeopleResourceTest.java index 4cbc8be87daee45673830bfebfed6171a9135df9..cd58d9c5155626cb3a0983945e761a3317858708 100644 --- a/src/test/java/es/uvigo/esei/daa/rest/PeopleResourceTest.java +++ b/src/test/java/es/uvigo/esei/daa/rest/PeopleResourceTest.java @@ -97,9 +97,12 @@ public class PeopleResourceTest extends JerseyTest { @Test public void testListUnauthorized() throws IOException { + final Response response = target("people").request() .header("Authorization", "Basic " + userToken(normalLogin())) .get(); + + assertThat(response, hasUnauthorized()); } diff --git a/src/test/java/es/uvigo/esei/daa/rest/PetsResourceTest.java b/src/test/java/es/uvigo/esei/daa/rest/PetsResourceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1a9d9861b89ad9cb446048162a193be8a81452ce --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/rest/PetsResourceTest.java @@ -0,0 +1,324 @@ +package es.uvigo.esei.daa.rest; + +import static es.uvigo.esei.daa.dataset.PetsDataset.*; +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 es.uvigo.esei.daa.matchers.IsEqualToPet.containsPetsInAnyOrder; +import static es.uvigo.esei.daa.matchers.IsEqualToPet.equalsToPet; +import static javax.ws.rs.client.Entity.entity; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.List; + +import javax.sql.DataSource; +import javax.ws.rs.client.Entity; +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 es.uvigo.esei.daa.entities.Pet; +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.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-pet.xml") +@ExpectedDatabase("/datasets/dataset-pet.xml") +public class PetsResourceTest 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 testList() throws IOException { + final Response response = target("pets").request() + .header("Authorization", "Basic " + userToken(adminLogin())) + .get(); + assertThat(response, hasOkStatus()); + + final List pet = response.readEntity(new GenericType>(){}); + + assertThat(pet, containsPetsInAnyOrder(pets())); + } + + @Test + public void testListUnauthorized() 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 + @ExpectedDatabase("/datasets/dataset-pet-add.xml") + public void testAdd() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + form.param("type", newType()); + form.param("person", String.valueOf(newPerson())); + + final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(adminLogin())) + .post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + assertThat(response, hasOkStatus()); + + final Pet pet = response.readEntity(Pet.class); + System.out.println(pet.getId()); + System.out.println(newPet().getId()); + System.out.println(); + + assertThat(pet, is(equalsToPet(newPet()))); + } + + @Test + public void testAddUnauthorized() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + form.param("type", newType()); + form.param("person", String.valueOf(newPerson())); + + final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(normalLogin())) + .post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertThat(response, hasUnauthorized()); + } + + @Test + public void testAddMissingName() throws IOException { + final Form form = new Form(); + form.param("type", newType()); + form.param("person",String.valueOf(newPerson())); + + final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(adminLogin())) + .post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + public void testAddMissingType() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + form.param("type",newType()); + + final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(adminLogin())) + .post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + public void testAddMissingPerson() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + form.param("type",newType()); + + final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(adminLogin())) + .post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + @ExpectedDatabase("/datasets/dataset-pet-modify.xml") + public void testModify() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + form.param("type", newType()); + form.param("person",String.valueOf(newPerson())); + + 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, hasOkStatus()); + + final Pet modifiedPet = response.readEntity(Pet.class); + + final Pet pet = existentPet(); + pet.setName(newName()); + pet.setType(newType()); + pet.setPerson(newPerson()); + + assertThat(modifiedPet, is(equalsToPet(pet))); + } + + @Test + public void testModifyUnauthorized() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + form.param("type", newType()); + form.param("person",String.valueOf(newPerson())); + + final Response response = target("pets/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(normalLogin())) + .put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertThat(response, hasUnauthorized()); + } + + @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 + public void testModifySurname() throws IOException { + final Form form = new Form(); + form.param("type", newType()); + + 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 + public void testModifyPerson() throws IOException { + final Form form = new Form(); + form.param("person", String.valueOf(newPerson())); + + 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 + public void testModifyInvalidId() throws IOException { + final Form form = new Form(); + form.param("name", newName()); + form.param("type", newType()); + form.param("person",String.valueOf(newPerson())); + + final Response response = target("pets/" + nonExistentId()).request(MediaType.APPLICATION_JSON_TYPE) + .header("Authorization", "Basic " + userToken(adminLogin())) + .put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + @ExpectedDatabase("/datasets/dataset-pet-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/java/es/uvigo/esei/daa/rest/PetsResourceUnitTest.java b/src/test/java/es/uvigo/esei/daa/rest/PetsResourceUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3b3a4945e0ed69b8c488db3cf51cfccc2482c739 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/rest/PetsResourceUnitTest.java @@ -0,0 +1,252 @@ +package es.uvigo.esei.daa.rest; + +import es.uvigo.esei.daa.dao.DAOException; +import es.uvigo.esei.daa.dao.PetDAO; +import es.uvigo.esei.daa.entities.PersonUnitTest; +import es.uvigo.esei.daa.entities.Pet; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.core.Response; +import java.util.List; + +import static es.uvigo.esei.daa.dataset.PetsDataset.*; +import static es.uvigo.esei.daa.matchers.HasHttpStatus.*; +import static es.uvigo.esei.daa.matchers.IsEqualToPet.containsPetsInAnyOrder; +import static es.uvigo.esei.daa.matchers.IsEqualToPet.equalsToPet; +import static java.util.Arrays.asList; +import static org.easymock.EasyMock.anyInt; +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.anyString; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +public class PetsResourceUnitTest { + private PetDAO daoMock; + private PetsResource resource; + + @Before + public void setUp() throws Exception{ + daoMock = createMock(PetDAO.class); + resource = new PetsResource(daoMock); + } + + @After + public void tearDown() throws Exception { + try { + verify(daoMock); + } finally { + daoMock = null; + resource = null; + } + } + + @Test + @SuppressWarnings("unchecked") + public void testList() throws Exception { + final List pets = asList(pets()); + + expect(daoMock.list()).andReturn(pets); + + replay(daoMock); + + final Response response = resource.list(null); + + assertThat(response, hasOkStatus()); + assertThat((List) response.getEntity(), containsPetsInAnyOrder(pets())); + } + + @Test + @SuppressWarnings("unchecked") + public void testListPetsPerson() throws Exception { + final List pets = asList(pets()); + Integer person = existentOwner(); + expect(daoMock.listForPeople(person)).andReturn(pets); + + replay(daoMock); + + final Response response = resource.list(person); + + assertThat(response, hasOkStatus()); + assertThat((List) response.getEntity(), containsPetsInAnyOrder(pets())); + } + + @Test + public void testListDAOException() throws Exception { + expect(daoMock.list()).andThrow(new DAOException()); + + replay(daoMock); + + final Response response = resource.list(null); + + assertThat(response, hasInternalServerErrorStatus()); + } + + @Test + public void testGet() throws Exception { + final Pet pet = existentPet(); + + expect(daoMock.get(pet.getId())).andReturn(pet); + + replay(daoMock); + + final Response response = resource.get(pet.getId()); + + assertThat(response, hasOkStatus()); + assertThat((Pet) response.getEntity(), is(equalsToPet(pet))); + } + + @Test + public void testGetDAOException() throws Exception { + expect(daoMock.get(anyInt())).andThrow(new DAOException()); + + replay(daoMock); + + final Response response = resource.get(existentId()); + + assertThat(response, hasInternalServerErrorStatus()); + } + + @Test + public void testGetIllegalArgumentException() throws Exception { + expect(daoMock.get(anyInt())).andThrow(new IllegalArgumentException()); + + replay(daoMock); + + final Response response = resource.get(existentId()); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + public void testDelete() throws Exception { + daoMock.delete(anyInt()); + + replay(daoMock); + + final Response response = resource.delete(1); + + assertThat(response, hasOkStatus()); + } + + @Test + public void testDeleteDAOException() throws Exception { + daoMock.delete(anyInt()); + expectLastCall().andThrow(new DAOException()); + + replay(daoMock); + + final Response response = resource.delete(1); + + assertThat(response, hasInternalServerErrorStatus()); + } + + @Test + public void testDeleteIllegalArgumentException() throws Exception { + daoMock.delete(anyInt()); + expectLastCall().andThrow(new IllegalArgumentException()); + replay(daoMock); + + final Response response = resource.delete(1); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + public void testModify() throws Exception { + final Pet pet = existentPet(); + pet.setName(newName()); + pet.setType(newType()); + pet.setPerson(newPerson()); + + + daoMock.modify(pet); + + replay(daoMock); + + final Response response = resource.modify( + pet.getId(), pet.getName(), pet.getType(),pet.getPerson()); + + assertThat(response, hasOkStatus()); + assertEquals(pet, response.getEntity()); + } + + @Test + public void testModifyDAOException() throws Exception { + daoMock.modify(anyObject()); + expectLastCall().andThrow(new DAOException()); + + replay(daoMock); + + final Response response = resource.modify(existentId(), newName(), newType(),newPerson()); + + assertThat(response, hasInternalServerErrorStatus()); + } + + @Test + public void testModifyIllegalArgumentException() throws Exception { + daoMock.modify(anyObject()); + expectLastCall().andThrow(new IllegalArgumentException()); + + replay(daoMock); + + final Response response = resource.modify(existentId(), newName(), newType(),newPerson()); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + public void testModifyNullPointerException() throws Exception { + daoMock.modify(anyObject()); + expectLastCall().andThrow(new NullPointerException()); + + replay(daoMock); + + final Response response = resource.modify(existentId(), newName(), newType(),newPerson()); + + assertThat(response, hasBadRequestStatus()); + } + + @Test + public void testAdd() throws Exception { + expect(daoMock.add(newName(), newType(),newPerson())) + .andReturn(newPet()); + replay(daoMock); + + + final Response response = resource.add(newName(), newType(),newPerson()); + + assertThat(response, hasOkStatus()); + assertThat((Pet) response.getEntity(), is(equalsToPet(newPet()))); + } + + @Test + public void testAddDAOException() throws Exception { + expect(daoMock.add(anyString(), anyString(),anyInt())) + .andThrow(new DAOException()); + replay(daoMock); + + final Response response = resource.add(newName(), newType(),newPerson()); + + assertThat(response, hasInternalServerErrorStatus()); + } + + @Test + public void testAddIllegalArgumentException() throws Exception { + expect(daoMock.add(anyString(), anyString(),anyInt())) + .andThrow(new IllegalArgumentException()); + replay(daoMock); + + final Response response = resource.add(newName(), newType(),newPerson()); + + assertThat(response, hasBadRequestStatus()); + } +} + diff --git a/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java b/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java index 822c83f44b63c0c998e6b17c1ab25bddbd750a63..2d8ee15dc383b67464f134ea53f8930ad9e371ae 100644 --- a/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java +++ b/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java @@ -1,5 +1,7 @@ package es.uvigo.esei.daa.suites; +import es.uvigo.esei.daa.dao.PetsDAOTest; +import es.uvigo.esei.daa.rest.PetsResourceTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @@ -9,9 +11,11 @@ import es.uvigo.esei.daa.rest.PeopleResourceTest; import es.uvigo.esei.daa.rest.UsersResourceTest; @SuiteClasses({ - PeopleDAOTest.class, - PeopleResourceTest.class, - UsersResourceTest.class + PeopleDAOTest.class, + PetsResourceTest.class, + PeopleResourceTest.class, + PetsDAOTest.class, + UsersResourceTest.class }) @RunWith(Suite.class) public class IntegrationTestSuite { diff --git a/src/test/java/es/uvigo/esei/daa/suites/UnitTestSuite.java b/src/test/java/es/uvigo/esei/daa/suites/UnitTestSuite.java index a21ca3663b624f6cf2ea326a347de55ae8f96ca9..4659e383e528056b02ec6c371fff511e0e2ff3df 100644 --- a/src/test/java/es/uvigo/esei/daa/suites/UnitTestSuite.java +++ b/src/test/java/es/uvigo/esei/daa/suites/UnitTestSuite.java @@ -1,5 +1,8 @@ package es.uvigo.esei.daa.suites; +import es.uvigo.esei.daa.dao.PetsDAOUnitTest; +import es.uvigo.esei.daa.entities.PetUnitTest; +import es.uvigo.esei.daa.rest.PetsResourceUnitTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @@ -9,9 +12,12 @@ import es.uvigo.esei.daa.entities.PersonUnitTest; import es.uvigo.esei.daa.rest.PeopleResourceUnitTest; @SuiteClasses({ - PersonUnitTest.class, - PeopleDAOUnitTest.class, - PeopleResourceUnitTest.class + PersonUnitTest.class, + PetUnitTest.class, + PeopleDAOUnitTest.class, + PetsDAOUnitTest.class, + PeopleResourceUnitTest.class, + PetsResourceUnitTest.class }) @RunWith(Suite.class) public class UnitTestSuite { diff --git a/src/test/resources/datasets/dataset-add.xml b/src/test/resources/datasets/dataset-add.xml index 9a75a999a98510f7d6d32992877e71772e8f536c..922e77f325215ac3f78fbdd00bb8a3ffe3b79310 100644 --- a/src/test/resources/datasets/dataset-add.xml +++ b/src/test/resources/datasets/dataset-add.xml @@ -14,6 +14,17 @@ + + + + + + + + + + + \ 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 e49223db335c0f49f7d78cdcb3f27e80e14d30da..7164bdf207d120a435caac88a58e7f797bb0fe40 100644 --- a/src/test/resources/datasets/dataset-delete.xml +++ b/src/test/resources/datasets/dataset-delete.xml @@ -12,6 +12,17 @@ + + + + + + + + + + + \ 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 6e2dfc903798c9e26431fbaf42bea176a05fc59c..9cbe5bcb5c2c7634328bde9cdb588435aee6754d 100644 --- a/src/test/resources/datasets/dataset-modify.xml +++ b/src/test/resources/datasets/dataset-modify.xml @@ -13,6 +13,17 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-pet-add.xml b/src/test/resources/datasets/dataset-pet-add.xml new file mode 100644 index 0000000000000000000000000000000000000000..76a1681ae9da2050ec3b637d8cd71baee675bc6e --- /dev/null +++ b/src/test/resources/datasets/dataset-pet-add.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-pet-delete.xml b/src/test/resources/datasets/dataset-pet-delete.xml new file mode 100644 index 0000000000000000000000000000000000000000..f0bf287dfa4e9ee0144808f200552259d7f2ed49 --- /dev/null +++ b/src/test/resources/datasets/dataset-pet-delete.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-pet-modify.xml b/src/test/resources/datasets/dataset-pet-modify.xml new file mode 100644 index 0000000000000000000000000000000000000000..7c9ccb52d60a797de75296b80d4abafc2d7b2f51 --- /dev/null +++ b/src/test/resources/datasets/dataset-pet-modify.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-pet.xml b/src/test/resources/datasets/dataset-pet.xml new file mode 100644 index 0000000000000000000000000000000000000000..6923ca54cdce0b0e3d1d1de804d1d42b0576e3ec --- /dev/null +++ b/src/test/resources/datasets/dataset-pet.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset.dtd b/src/test/resources/datasets/dataset.dtd index e64500f9760310832c4352657d6b41454a653582..6d11f73d9fb36de99622386ba0368625a3d0a4f9 100644 --- a/src/test/resources/datasets/dataset.dtd +++ b/src/test/resources/datasets/dataset.dtd @@ -1,7 +1,8 @@ - + + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset.xml b/src/test/resources/datasets/dataset.xml index 3f48cc9b6888070b9fb5b4c42bee31f8eae267b6..79a346d0bcff31fe94eccf36996ee9c1cc719f07 100644 --- a/src/test/resources/datasets/dataset.xml +++ b/src/test/resources/datasets/dataset.xml @@ -13,6 +13,17 @@ + + + + + + + + + + + \ 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 31f86431b16948308e44087e73b488fc3043628a..7bc45bd0568d0a2cb5c05c579e00f285d5fc73db 100644 --- a/src/test/resources/db/hsqldb-drop.sql +++ b/src/test/resources/db/hsqldb-drop.sql @@ -1,2 +1,3 @@ DROP TABLE People IF EXISTS; DROP TABLE Users IF EXISTS; +DROP TABLE Pets IF EXISTS; diff --git a/src/test/resources/db/hsqldb.sql b/src/test/resources/db/hsqldb.sql index a62944149d65c732b38a85ca9455f804265fd185..26391050cf46759890fbea8d01e4f3889d86bc79 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) -); \ No newline at end of file +); + +CREATE TABLE pets( + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, + name VARCHAR(50) NOT NULL, + type VARCHAR(50) NOT NULL, + person int NOT NULL, + PRIMARY KEY (id) +) \ No newline at end of file