Commit 1fca9d13 authored by DavidSholito's avatar DavidSholito

Añadido test entidad Pet

parent caf1c466
<?xml version="1.0" encoding="UTF-8"?>
<project-shared-configuration>
<!--
This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
-->
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!--
Properties that influence various parts of the IDE, especially code formatting and the like.
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
That way multiple projects can share the same settings (useful for formatting rules for example).
Any value defined here will override the pom.xml file value but is only applicable to the current project.
-->
<org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>ide</org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>
</properties>
</project-shared-configuration>
......@@ -182,6 +182,13 @@
<artifactId>equalsverifier</artifactId>
<version>${equalsverifier.version}</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
</dependencies>
<reporting>
......@@ -305,6 +312,7 @@
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
......
......@@ -11,6 +11,7 @@ import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import es.uvigo.esei.daa.rest.PeopleResource;
import es.uvigo.esei.daa.rest.PetsResource;
import es.uvigo.esei.daa.rest.UsersResource;
/**
......@@ -26,7 +27,8 @@ public class DAAExampleApplication extends Application {
public Set<Class<?>> getClasses() {
return Stream.of(
PeopleResource.class,
UsersResource.class
UsersResource.class,
PetsResource.class
).collect(toSet());
}
......
......@@ -231,4 +231,3 @@ public class PetsDAO extends DAO{
}
package es.uvigo.esei.daa.rest;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import es.uvigo.esei.daa.dao.DAOException;
import es.uvigo.esei.daa.dao.PetsDAO;
import es.uvigo.esei.daa.entities.Pet;
@Path("/pets")
@Produces(MediaType.APPLICATION_JSON)
public class PetsResource {
private final static Logger LOG = Logger.getLogger(PetsResource.class.getName());
private final PetsDAO dao;
/**
* Constructs a new instance of {@link PetsResource}.
*/
public PetsResource() {
this(new PetsDAO());
}
// Needed for testing purposes
PetsResource(PetsDAO dao) {
this.dao = dao;
}
/**
* Returns a pet with the provided identifier.
*
* @param owner the identifier of the pet's owner to retrieve.
* @param id the identifier of the pet to retrieve.
* @return a 200 OK response with a pet that has the provided identifier.
* If the identifier does not corresponds with any pet, a 400 Bad Request
* response with an error message will be returned. If an error happens
* while retrieving the list, a 500 Internal Server Error response with an
* error message will be returned.
*/
@GET
@Path("/{id}")
public Response listWithOwner(
@PathParam("id") int id
) {
try {
return Response.ok(this.dao.listWithOwner(id)).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid owner id in get method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error listing pets with owner", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
/**
* Returns the complete list of pets stored in the system.
*
* @return a 200 OK response with the complete list of pets stored in the
* system. If an error happens while retrieving the list, a 500 Internal
* Server Error response with an error message will be returned.
*/
@GET
public Response list() {
try {
return Response.ok(this.dao.list()).build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
return Response.serverError().entity(e.getMessage()).build();
}
}
/**
* Creates a new person in the system.
*
* @param name the name of the new person.
* @param surname the surname of the new person.
* @return a 200 OK response with a person that has been created. If the
* name or the surname are not provided, a 400 Bad Request response with an
* error message will be returned. If an error happens while retrieving the
* list, a 500 Internal Server Error response with an error message will be
* returned.
*/
@POST
public Response add(
@FormParam("owner") int owner,
@FormParam("name") String name,
@FormParam("weight") Float weight
) {
try {
final Pet newPet = this.dao.add(owner, name, weight);
return Response.ok(newPet).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in add method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error adding a pet", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
/**
* Modifies the data of a person.
*
* @param id identifier of the person to modify.
* @param name the new name of the person.
* @param surname the new surname of the person.
* @return a 200 OK response with a person that has been modified. If the
* identifier does not corresponds with any user or the name or surname are
* not provided, a 400 Bad Request response with an error message will be
* returned. If an error happens while retrieving the list, a 500 Internal
* Server Error response with an error message will be returned.
*/
@PUT
@Path("/{id}")
public Response modify(
@PathParam("id") int id,
@FormParam("owner") int owner,
@FormParam("name") String name,
@FormParam("weight") Float weight
) {
try {
final Pet modifiedPet = new Pet(id, owner, name, weight);
this.dao.modify(modifiedPet);
return Response.ok(modifiedPet).build();
} catch (NullPointerException npe) {
final String message = String.format("Invalid data for pet (owner: %s, name: %s, weight: %s)", owner, name, weight);
LOG.log(Level.FINE, message);
return Response.status(Response.Status.BAD_REQUEST)
.entity(message)
.build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in modify method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error modifying a pet", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
/**
* Deletes a person from the system.
*
* @param id the identifier of the person to be deleted.
* @return a 200 OK response with the identifier of the person that has
* been deleted. If the identifier does not corresponds with any user, a 400
* Bad Request response with an error message will be returned. If an error
* happens while retrieving the list, a 500 Internal Server Error response
* with an error message will be returned.
*/
@DELETE
@Path("/{id}")
public Response delete(
@PathParam("id") int id
) {
try {
this.dao.delete(id);
return Response.ok(id).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in delete method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error deleting a pet", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
}
......@@ -60,6 +60,20 @@
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Area</web-resource-name>
<url-pattern>/rest/pets/*</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<!-- Security roles referenced by this web application -->
<security-role>
<role-name>ADMIN</role-name>
......
var PetsDAO = (function() {
var resourcePath = "rest/pets/";
var requestByAjax = function(data, done, fail, always) {
done = typeof done !== 'undefined' ? done : function() {};
fail = typeof fail !== 'undefined' ? fail : function() {};
always = typeof always !== 'undefined' ? always : function() {};
let authToken = localStorage.getItem('authorization-token');
if (authToken !== null) {
data.beforeSend = function(xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + authToken);
};
}
$.ajax(data).done(done).fail(fail).always(always);
};
function PetsDAO() {
this.listPets = function(done, fail, always) {
requestByAjax({
url : resourcePath,
type : 'GET'
}, done, fail, always);
};
this.addPet = function(pet, done, fail, always) {
requestByAjax({
url : resourcePath,
type : 'POST',
data : pet
}, done, fail, always);
};
this.modifyPet = function(pet, done, fail, always) {
requestByAjax({
url : resourcePath + pet.id,
type : 'PUT',
data : pet
}, done, fail, always);
};
this.deletePet = function(id, done, fail, always) {
requestByAjax({
url : resourcePath + id,
type : 'DELETE',
}, done, fail, always);
};
this.listPetsWithOwner = function(ownerId, done, fail, always) {
requestByAjax({
url : resourcePath + ownerId,
type : 'GET',
}, done, fail, always);
};
}
return PetsDAO;
})();
\ No newline at end of file
var PeopleView = (function() {
var dao;
var pets;
// Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery.
var self;
......@@ -9,14 +9,19 @@ var PeopleView = (function() {
var formQuery = '#' + formId;
var listQuery = '#' + listId;
function PeopleView(peopleDao, formContainerId, listContainerId) {
function PeopleView(peopleDao, petsView, formContainerId, listContainerId) {
dao = peopleDao;
pets = petsView;
self = this;
this.init = function() {
insertPeopleForm($('#' + formContainerId));
insertPeopleList($('#' + listContainerId));
this.init = function() {
dao.listPeople(function(people) {
$.each(people, function(key, person) {
appendToTable(person);
......@@ -123,6 +128,12 @@ var PeopleView = (function() {
$(formQuery + ' input[name="id"]').val('');
$('#btnSubmit').val('Crear');
};
this.detachForms = function(person) {
$(formQuery).remove();
$(listQuery).remove();
$('#titulo').text('Mascotas de ' + person.name + ' ' + person.surname);
};
};
var insertPeopleList = function(parent) {
......@@ -131,8 +142,8 @@ var PeopleView = (function() {
<thead>\
<tr class="row">\
<th class="col-sm-4">Nombre</th>\
<th class="col-sm-5">Apellido</th>\
<th class="col-sm-3">&nbsp;</th>\
<th class="col-sm-4">Apellido</th>\
<th class="col-sm-4">&nbsp;</th>\
</tr>\
</thead>\
<tbody>\
......@@ -149,10 +160,10 @@ var PeopleView = (function() {
<div class="col-sm-4">\
<input name="name" type="text" value="" placeholder="Nombre" class="form-control" required/>\
</div>\
<div class="col-sm-5">\
<div class="col-sm-4">\
<input name="surname" type="text" value="" placeholder="Apellido" class="form-control" required/>\
</div>\
<div class="col-sm-3">\
<div class="col-sm-4">\
<input id="btnSubmit" type="submit" value="Crear" class="btn btn-primary" />\
<input id="btnClear" type="reset" value="Limpiar" class="btn" />\
</div>\
......@@ -161,13 +172,15 @@ var PeopleView = (function() {
);
};
var createPersonRow = function(person) {
return '<tr id="person-'+ person.id +'" class="row">\
<td class="name col-sm-4">' + person.name + '</td>\
<td class="surname col-sm-5">' + person.surname + '</td>\
<td class="col-sm-3">\
<td class="surname col-sm-4">' + person.surname + '</td>\
<td class="col-sm-4">\
<a class="edit btn btn-primary" href="#">Editar</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\
<a class="pet btn btn-secondary" href="#">Mascotas</a>\
</td>\
</tr>';
};
......@@ -184,6 +197,11 @@ var PeopleView = (function() {
$('#person-' + person.id + ' a.delete').click(function() {
self.deletePerson(person.id);
});
$('#person-' + person.id + ' a.pet').click(function() {
self.detachForms(person);
pets.init(self, person);
});
};
var appendToTable = function(person) {
......@@ -192,5 +210,6 @@ var PeopleView = (function() {
addRowListeners(person);
};
return PeopleView;
})();
var PetsView = (function() {
var dao;
var owner;
var people;
// Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery.
var self;
var formId = 'pets-form';
var listId = 'pets-list';
var formQuery = '#' + formId;
var listQuery = '#' + listId;
function PetsView(petsDao, formContainerId, listContainerId) {
dao = petsDao;
self = this;
this.init = function(peopleView, person) {
people = peopleView;
owner = person;
insertPetForm($('#' + formContainerId));
insertPetList($('#' + listContainerId));
dao.listPetsWithOwner(owner.id, function(pets) {
$.each(pets, function(key, pet) {
appendToTable(pet);
});
},
function() {
alert('No has sido posible acceder al listado de mascotas.');
});
// La acción por defecto de enviar formulario (submit) se sobreescribe
// para que el envío sea a través de AJAX
$(formQuery).submit(function(event) {
var pet = self.getPetInForm();
if (self.isEditing()) {
dao.modifyPet(pet,
function(pet) {
$('#pet-' + pet.id + ' td.owner').text(pet.owner);
$('#pet-' + pet.id + ' td.name').text(pet.name);
$('#pet-' + pet.id + ' td.weight').text(pet.weight);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
} else {
dao.addPet(pet,
function(pet) {
appendToTable(pet);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
}
return false;
});
$('#btnClear').click(this.resetForm);
$('#btnReturn').click(returnToPeople);
};
this.getPetInForm = function() {
var form = $(formQuery);
return {
'id': form.find('input[name="id"]').val(),
'owner': owner.id,
'name': form.find('input[name="name"]').val(),
'weight': form.find('input[name="weight"]').val()
};
};
this.getPetInRow = function(id) {
var row = $('#pet-' + id);
if (row !== undefined) {
return {
'id': id,
'owner': owner.id,
'name': row.find('td.name').text(),
'surname': row.find('td.weight').text()
};
} else {
return undefined;
}
};
this.editPet = function(id,owner) {
var row = $('#pet-' + id);
if (row !== undefined) {
var form = $(formQuery);
form.find('input[name="id"]').val(id);
form.find('input[name="owner"]').val(owner);
form.find('input[name="name"]').val(row.find('td.name').text());
form.find('input[name="weight"]').val(row.find('td.weight').text());
$('input#btnSubmit').val('Modificar');
}
};
this.deletePet = function(id) {
if (confirm('Está a punto de eliminar a una mascota. ¿Está seguro de que desea continuar?')) {
dao.deletePet(id,
function() {
$('tr#pet-' + id).remove();
},
showErrorMessage
);
}
};
this.isEditing = function() {
return $(formQuery + ' input[name="id"]').val() != "";
};
this.disableForm = function() {
$(formQuery + ' input').prop('disabled', true);
};
this.enableForm = function() {
$(formQuery + ' input').prop('disabled', false);
};
this.resetForm = function() {
$(formQuery)[0].reset();
$(formQuery + ' input[name="id"]').val('');
$('#btnSubmit').val('Crear');
};
this.detachForms = function() {
$(formQuery).detach();
$(listQuery).detach();
$('#titulo').text('Personas');
};
};
var insertPetList = function(parent) {
parent.append(
'<table id="' + listId + '" class="table">\
<thead>\
<tr class="row">\
<th class="col-sm-4">Nombre Mascota</th>\
<th class="col-sm-5">Peso</th>\
<th class="col-sm-3">&nbsp;</th>\
</tr>\
</thead>\
<tbody>\
</tbody>\
</table>'
);
};
var insertPetForm = function(parent) {
parent.append(
'<form id="' + formId + '" class="mb-5 mb-10">\
<input name="id" type="hidden" value=""/>\
<input name="owner" type="hidden" value="' + owner + '"/>\
<div class="row">\
<div class="col-sm-4">\
<input name="name" type="text" value="" placeholder="Nombre Mascota" class="form-control" required/>\
</div>\
<div class="col-sm-4">\
<input name="weight" type="text" value="" placeholder="Peso" class="form-control" required/>\
</div>\
<div class="col-sm-4">\
<input id="btnSubmit" type="submit" value="Crear" class="btn btn-primary" />\
<input id="btnClear" type="reset" value="Limpiar" class="btn" />\
<input id="btnReturn" type="button" value="Volver" class="btn btn-dark" />\
</div>\
</div>\
</form>'
);
};
var createPetRow = function(pet) {
return '<tr id="pet-'+ pet.id +'" class="row">\
<td class="name col-sm-4">' + pet.name + '</td>\
<td class="weight col-sm-5">' + pet.weight + '</td>\
<td class="col-sm-3">\
<a class="edit btn btn-primary" href="#">Editar</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\
</td>\
</tr>';
};
var showErrorMessage = function(jqxhr, textStatus, error) {
alert(textStatus + ": " + error);
};
var addRowListeners = function(pet) {
$('#pet-' + pet.id + ' a.edit').click(function() {
self.editPet(pet.id, pet.owner);
});
$('#pet-' + pet.id + ' a.delete').click(function() {
self.deletePet(pet.id);
});
};
var appendToTable = function(pet) {
$(listQuery + ' > tbody:last')
.append(createPetRow(pet));
addRowListeners(pet);
};
var returnToPeople = function() {
self.detachForms();
people.init();
};
return PetsView;
})();
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
......@@ -22,7 +21,7 @@
<div class="container">
<div id="people-container">
<h1 class="display-5 mt-3 mb-3">Personas</h1>
<h1 class="display-5 mt-3 mb-3" id="titulo">Personas</h1>
</div>
</div>
......@@ -30,6 +29,8 @@
src="http://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="js/dao/people.js"></script>
<script type="text/javascript" src="js/view/people.js"></script>
<script type="text/javascript" src="js/dao/pets.js"></script>
<script type="text/javascript" src="js/view/pets.js"></script>
<script type="text/javascript" src="js/login.js"></script>
<script type="text/javascript">
$(document).ready(
......@@ -39,7 +40,7 @@
doLogout();
});
var view = new PeopleView(new PeopleDAO(),
var view = new PeopleView(new PeopleDAO(), new PetsView(new PetsDAO(), 'people-container', 'people-container'),
'people-container', 'people-container'
);
......
package es.uvigo.esei.daa.entities;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.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 testPetIntIntStringFloat() {
final int id = 1;
final int owner = 1;
final String name = "Perica";
final float weight = 2.15f;
final Pet pet = new Pet(id, owner, name, weight);
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getOwner(), is(equalTo(owner)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getWeight(), is(equalTo(weight)));
}
@Test(expected = NullPointerException.class)
public void testPetIntIntStringFloatNullOwner() {
new Pet(1, (Integer)null, "Perica", 2.30f);
}
@Test(expected = NullPointerException.class)
public void testPetIntIntStringFloatNullName() {
new Pet(1, 1, null, 2.30f);
}
@Test(expected = NullPointerException.class)
public void testPetIntIntStringFloatNullWeight() {
new Pet(1, 1, "Perica", (Float)null);
}
@Test
public void testSetName() {
final int id = 1;
final int owner = 1;
final float weight = 2.15f;
final Pet pet = new Pet(id, owner, "Perica", weight);
pet.setName("Pintitas");
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getOwner(), is(equalTo(owner)));
assertThat(pet.getName(), is(equalTo("Pintitas")));
assertThat(pet.getWeight(), is(equalTo(weight)));
}
@Test
public void testSetWeight() {
final int id = 1;
final int owner = 1;
final String name = "Perica";
final Pet pet = new Pet(id, owner, "Perica", 2.15f);
pet.setWeight(3.3f);
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getOwner(), is(equalTo(owner)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getWeight(), is(equalTo(3.3f)));
}
@Test(expected = NullPointerException.class)
public void testSetNullName() {
final Pet pet = new Pet(1, 1, "John", 2.15f);
pet.setName(null);
}
@Test(expected = NullPointerException.class)
public void testSetNullWeight() {
final Pet pet = new Pet(1, 1, "John", 2.15f);
pet.setWeight((Float)null);
}
@Test
public void testEqualsObject() {
final Pet petA = new Pet(1, 1, "Name A", 2.15f);
final Pet petB = new Pet(1, 1, "Name B", 3.65f);
assertTrue(petA.equals(petB));
}
/*
@Test
public void testEqualsHashcode() {
EqualsVerifier.forClass(Person.class)
.withIgnoredFields("name", "surname")
.suppress(Warning.STRICT_INHERITANCE)
.suppress(Warning.NONFINAL_FIELDS)
.verify();
}
*/
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment