Commit d2ccccea authored by Santi's avatar Santi

Completes list of pets by owner

parent 2e5babc8
...@@ -57,14 +57,14 @@ public class PetsDAO extends DAO { ...@@ -57,14 +57,14 @@ public class PetsDAO extends DAO {
LOG.log(Level.SEVERE, "Error deleting a pet", e); LOG.log(Level.SEVERE, "Error deleting a pet", e);
throw new DAOException(e); throw new DAOException(e);
} }
} }
public List<Pet> list() throws DAOException { public List<Pet> list(int owner) throws DAOException {
try (final Connection conn = this.getConnection()) { try (final Connection conn = this.getConnection()) {
final String query = "SELECT * FROM pet"; final String query = "SELECT * FROM pet WHERE owner = ?";
try (final PreparedStatement statement = conn.prepareStatement(query)) { try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, owner);
try (final ResultSet result = statement.executeQuery()) { try (final ResultSet result = statement.executeQuery()) {
final List<Pet> pets = new LinkedList<>(); final List<Pet> pets = new LinkedList<>();
......
package es.uvigo.esei.daa.rest; 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.DAOException;
import es.uvigo.esei.daa.dao.PeopleDAO; import es.uvigo.esei.daa.dao.PeopleDAO;
import es.uvigo.esei.daa.entities.Person; import es.uvigo.esei.daa.entities.Person;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* REST resource for managing people. * REST resource for managing people.
* *
......
...@@ -22,21 +22,15 @@ public class PetsResource { ...@@ -22,21 +22,15 @@ public class PetsResource {
private final PetsDAO dao; private final PetsDAO dao;
public PetsResource() {
this(new PetsDAO());
}
PetsResource(PetsDAO dao) { PetsResource(PetsDAO dao) {
this.dao = dao; this.dao = dao;
} }
/**
* Returns a person with the provided identifier.
*
* @param id the identifier of the person to retrieve.
* @return a 200 OK response with a person that has the provided identifier.
* 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.
*/
@GET @GET
@Path("/{id}") @Path("/{id}")
public Response get( public Response get(
...@@ -88,9 +82,10 @@ public class PetsResource { ...@@ -88,9 +82,10 @@ public class PetsResource {
@GET @GET
public Response list() { @Path("/owner/{owner}")
public Response list(@PathParam("owner") int owner) {
try { try {
return Response.ok(this.dao.list()).build(); return Response.ok(this.dao.list(owner)).build();
} catch (DAOException e) { } catch (DAOException e) {
LOG.log(Level.SEVERE, "Error listing pets", e); LOG.log(Level.SEVERE, "Error listing pets", e);
return Response.serverError().entity(e.getMessage()).build(); return Response.serverError().entity(e.getMessage()).build();
......
...@@ -5,7 +5,7 @@ var PeopleDAO = (function() { ...@@ -5,7 +5,7 @@ var PeopleDAO = (function() {
fail = typeof fail !== 'undefined' ? fail : function() {}; fail = typeof fail !== 'undefined' ? fail : function() {};
always = typeof always !== 'undefined' ? always : function() {}; always = typeof always !== 'undefined' ? always : function() {};
let authToken = localStorage.getItem('authorization-token'); var authToken = localStorage.getItem('authorization-token');
if (authToken !== null) { if (authToken !== null) {
data.beforeSend = function(xhr) { data.beforeSend = function(xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + authToken); xhr.setRequestHeader('Authorization', 'Basic ' + authToken);
...@@ -23,7 +23,7 @@ var PeopleDAO = (function() { ...@@ -23,7 +23,7 @@ var PeopleDAO = (function() {
}, done, fail, always); }, done, fail, always);
}; };
this.addPerson = function(person, done, fail, always) { this.addPet = function (person, done, fail, always) {
requestByAjax({ requestByAjax({
url : resourcePath, url : resourcePath,
type : 'POST', type : 'POST',
...@@ -31,7 +31,7 @@ var PeopleDAO = (function() { ...@@ -31,7 +31,7 @@ var PeopleDAO = (function() {
}, done, fail, always); }, done, fail, always);
}; };
this.modifyPerson = function(person, done, fail, always) { this.modifyPet = function (person, done, fail, always) {
requestByAjax({ requestByAjax({
url : resourcePath + person.id, url : resourcePath + person.id,
type : 'PUT', type : 'PUT',
......
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 () {
};
var 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 (owner, done, fail, always) {
requestByAjax({
url: resourcePath + "owner/" + owner,
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);
};
}
return PetsDAO;
})();
\ No newline at end of file
var PeopleView = (function() { var PeopleView = (function () {
var dao; var dao;
// Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery. // Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery.
...@@ -16,24 +16,24 @@ var PeopleView = (function() { ...@@ -16,24 +16,24 @@ var PeopleView = (function() {
insertPeopleForm($('#' + formContainerId)); insertPeopleForm($('#' + formContainerId));
insertPeopleList($('#' + listContainerId)); insertPeopleList($('#' + listContainerId));
this.init = function() { this.init = function () {
dao.listPeople(function(people) { dao.listPeople(function (people) {
$.each(people, function(key, person) { $.each(people, function (key, person) {
appendToTable(person); appendToTable(person);
}); });
}, },
function() { function () {
alert('No has sido posible acceder al listado de personas.'); alert('No has sido posible acceder al listado de personas.');
}); });
// La acción por defecto de enviar formulario (submit) se sobreescribe // La acción por defecto de enviar formulario (submit) se sobreescribe
// para que el envío sea a través de AJAX // para que el envío sea a través de AJAX
$(formQuery).submit(function(event) { $(formQuery).submit(function (event) {
var person = self.getPersonInForm(); var person = self.getPersonInForm();
if (self.isEditing()) { if (self.isEditing()) {
dao.modifyPerson(person, dao.modifyPet(person,
function(person) { function (person) {
$('#person-' + person.id + ' td.name').text(person.name); $('#person-' + person.id + ' td.name').text(person.name);
$('#person-' + person.id + ' td.surname').text(person.surname); $('#person-' + person.id + ' td.surname').text(person.surname);
self.resetForm(); self.resetForm();
...@@ -42,8 +42,8 @@ var PeopleView = (function() { ...@@ -42,8 +42,8 @@ var PeopleView = (function() {
self.enableForm self.enableForm
); );
} else { } else {
dao.addPerson(person, dao.addPet(person,
function(person) { function (person) {
appendToTable(person); appendToTable(person);
self.resetForm(); self.resetForm();
}, },
...@@ -58,7 +58,7 @@ var PeopleView = (function() { ...@@ -58,7 +58,7 @@ var PeopleView = (function() {
$('#btnClear').click(this.resetForm); $('#btnClear').click(this.resetForm);
}; };
this.getPersonInForm = function() { this.getPersonInForm = function () {
var form = $(formQuery); var form = $(formQuery);
return { return {
'id': form.find('input[name="id"]').val(), 'id': form.find('input[name="id"]').val(),
...@@ -67,7 +67,7 @@ var PeopleView = (function() { ...@@ -67,7 +67,7 @@ var PeopleView = (function() {
}; };
}; };
this.getPersonInRow = function(id) { this.getPersonInRow = function (id) {
var row = $('#person-' + id); var row = $('#person-' + id);
if (row !== undefined) { if (row !== undefined) {
...@@ -81,7 +81,7 @@ var PeopleView = (function() { ...@@ -81,7 +81,7 @@ var PeopleView = (function() {
} }
}; };
this.editPerson = function(id) { this.editPerson = function (id) {
var row = $('#person-' + id); var row = $('#person-' + id);
if (row !== undefined) { if (row !== undefined) {
...@@ -95,10 +95,10 @@ var PeopleView = (function() { ...@@ -95,10 +95,10 @@ var PeopleView = (function() {
} }
}; };
this.deletePerson = function(id) { this.deletePerson = function (id) {
if (confirm('Está a punto de eliminar a una persona. ¿Está seguro de que desea continuar?')) { if (confirm('Está a punto de eliminar a una persona. ¿Está seguro de que desea continuar?')) {
dao.deletePerson(id, dao.deletePet(id,
function() { function () {
$('tr#person-' + id).remove(); $('tr#person-' + id).remove();
}, },
showErrorMessage showErrorMessage
...@@ -106,26 +106,38 @@ var PeopleView = (function() { ...@@ -106,26 +106,38 @@ var PeopleView = (function() {
} }
}; };
this.isEditing = function() { this.showPets = function (id) {
document.getElementById('people-container').style.display = 'none';
document.getElementById('pet-container').style.display = 'block';
var view = new PetsView(id, new PetsDAO(),
'pet-container', 'pet-container'
);
view.init();
}
this.isEditing = function () {
return $(formQuery + ' input[name="id"]').val() != ""; return $(formQuery + ' input[name="id"]').val() != "";
}; };
this.disableForm = function() { this.disableForm = function () {
$(formQuery + ' input').prop('disabled', true); $(formQuery + ' input').prop('disabled', true);
}; };
this.enableForm = function() { this.enableForm = function () {
$(formQuery + ' input').prop('disabled', false); $(formQuery + ' input').prop('disabled', false);
}; };
this.resetForm = function() { this.resetForm = function () {
$(formQuery)[0].reset(); $(formQuery)[0].reset();
$(formQuery + ' input[name="id"]').val(''); $(formQuery + ' input[name="id"]').val('');
$('#btnSubmit').val('Crear'); $('#btnSubmit').val('Crear');
}; };
}; };
var insertPeopleList = function(parent) { var insertPeopleList = function (parent) {
parent.append( parent.append(
'<table id="' + listId + '" class="table">\ '<table id="' + listId + '" class="table">\
<thead>\ <thead>\
...@@ -141,7 +153,7 @@ var PeopleView = (function() { ...@@ -141,7 +153,7 @@ var PeopleView = (function() {
); );
}; };
var insertPeopleForm = function(parent) { var insertPeopleForm = function (parent) {
parent.append( parent.append(
'<form id="' + formId + '" class="mb-5 mb-10">\ '<form id="' + formId + '" class="mb-5 mb-10">\
<input name="id" type="hidden" value=""/>\ <input name="id" type="hidden" value=""/>\
...@@ -161,32 +173,39 @@ var PeopleView = (function() { ...@@ -161,32 +173,39 @@ var PeopleView = (function() {
); );
}; };
var createPersonRow = function(person) { var createPersonRow = function (person) {
return '<tr id="person-'+ person.id +'" class="row">\ return '<tr id="person-' + person.id + '" class="row">\
<td class="name col-sm-4">' + person.name + '</td>\ <td class="name col-sm-6 col-md-3">' + person.name + '</td>\
<td class="surname col-sm-5">' + person.surname + '</td>\ <td class="surname col-sm-6 col-md-4">' + person.surname + '</td>\
<td class="col-sm-3">\ <td class="col-sm-12 col-md-5">\
<a class="edit btn btn-primary" href="#">Editar</a>\ <a class="show-pets btn btn-primary" href="#">Mascotas</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\ <a class="edit btn btn-warning" href="#">Editar</a>\
<a class="delete btn btn-danger" href="#">Eliminar</a>\
</td>\ </td>\
</tr>'; </tr>';
}; };
var showErrorMessage = function(jqxhr, textStatus, error) { var showErrorMessage = function (jqxhr, textStatus, error) {
alert(textStatus + ": " + error); alert(textStatus + ": " + error);
}; };
var addRowListeners = function(person) { var addRowListeners = function (person) {
$('#person-' + person.id + ' a.edit').click(function() { $('#person-' + person.id + ' a.edit').click(function () {
self.editPerson(person.id); self.editPerson(person.id);
}); });
$('#person-' + person.id + ' a.delete').click(function() { $('#person-' + person.id + ' a.delete').click(function () {
self.deletePerson(person.id); self.deletePerson(person.id);
}); });
$('#person-' + person.id + ' a.show-pets').click(function () {
self.showPets(person.id);
});
}; };
var appendToTable = function(person) { var appendToTable = function (person) {
$(listQuery + ' > tbody:last') $(listQuery + ' > tbody:last')
.append(createPersonRow(person)); .append(createPersonRow(person));
addRowListeners(person); addRowListeners(person);
......
var PetsView = (function () {
var dao;
// 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(owner, petsDao, formContainerId, listContainerId) {
dao = petsDao;
self = this;
insertPetsForm($('#' + formContainerId));
insertPetsList($('#' + listContainerId));
this.init = function () {
dao.listPets(owner, 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.name').text(pet.name);
$('#pet-' + pet.id + ' td.owner').text(pet.owner);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
} else {
dao.addPet(pet,
function (pet) {
appendToTable(pet);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
}
return false;
});
$('#btnClear').click(this.resetForm);
};
this.getPetInForm = function () {
var form = $(formQuery);
return {
'id': form.find('input[name="id"]').val(),
'name': form.find('input[name="name"]').val(),
'owner': form.find('input[name="owner"]').val()
};
};
this.getPetInRow = function (id) {
var row = $('#pet-' + id);
if (row !== undefined) {
return {
'id': id,
'name': row.find('td.name').text(),
'owner': row.find('td.owner').text()
};
} else {
return undefined;
}
};
this.editPet = function (id) {
var row = $('#pet-' + id);
if (row !== undefined) {
var form = $(formQuery);
form.find('input[name="id"]').val(id);
form.find('input[name="name"]').val(row.find('td.name').text());
form.find('input[name="owner"]').val(row.find('td.owner').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.showPets = function (id) {
}
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');
};
};
var insertPetsList = function (parent) {
parent.append(
'<table id="' + listId + '" class="table">\
<thead>\
<tr class="row">\
<th class="col-sm-4">Nombre</th>\
<th class="col-sm-5">Propietario</th>\
<th class="col-sm-3">&nbsp;</th>\
</tr>\
</thead>\
<tbody>\
</tbody>\
</table>'
);
};
var insertPetsForm = function (parent) {
parent.append(
'<form id="' + formId + '" class="mb-5 mb-10">\
<input name="id" type="hidden" value=""/>\
<div class="row">\
<div class="col-sm-4">\
<input name="name" type="text" value="" placeholder="Nombre" class="form-control" required/>\
</div>\
<div class="col-sm-5">\
<input name="owner" type="text" value="" placeholder="Dueño" class="form-control" required/>\
</div>\
<div class="col-sm-3">\
<input id="btnSubmit" type="submit" value="Crear" class="btn btn-primary" />\
<input id="btnClear" type="reset" value="Limpiar" class="btn" />\
</div>\
</div>\
</form>'
);
};
var createPetRow = function (pet) {
return '<tr id="pet-' + pet.id + '" class="row">\
<td class="name col-sm-6 col-md-3">' + pet.name + '</td>\
<td class="owner col-sm-6 col-md-4">' + pet.owner + '</td>\
<td class="col-sm-12 col-md-5">\
<a class="edit btn btn-warning" href="#">Editar</a>\
<a class="delete btn btn-danger" 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-' + pet.id + ' a.delete').click(function () {
self.deletePet(pet.id);
});
};
var appendToTable = function (pet) {
$(listQuery + ' > tbody:last')
.append(createPetRow(pet));
addRowListeners(pet);
};
return PetsView;
})();
package es.uvigo.esei.daa.dataset; package es.uvigo.esei.daa.dataset;
import static java.util.Arrays.binarySearch; import es.uvigo.esei.daa.entities.Person;
import static java.util.Arrays.stream;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Predicate; import java.util.function.Predicate;
import es.uvigo.esei.daa.entities.Person; import static java.util.Arrays.binarySearch;
import static java.util.Arrays.stream;
public final class PeopleDataset { public final class PeopleDataset {
private PeopleDataset() {} private PeopleDataset() {}
...@@ -45,7 +45,7 @@ public final class PeopleDataset { ...@@ -45,7 +45,7 @@ public final class PeopleDataset {
} }
public static int existentId() { public static int existentId() {
return 5; return 1;
} }
public static int nonExistentId() { public static int nonExistentId() {
......
...@@ -11,6 +11,7 @@ import org.junit.Test; ...@@ -11,6 +11,7 @@ import org.junit.Test;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.List; import java.util.List;
import static es.uvigo.esei.daa.dataset.PeopleDataset.existentPerson;
import static es.uvigo.esei.daa.dataset.PeopleDataset.newName; import static es.uvigo.esei.daa.dataset.PeopleDataset.newName;
import static es.uvigo.esei.daa.dataset.PetsDataset.*; import static es.uvigo.esei.daa.dataset.PetsDataset.*;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.*; import static es.uvigo.esei.daa.matchers.HasHttpStatus.*;
...@@ -61,13 +62,13 @@ public class PetsResourceUnitTest { ...@@ -61,13 +62,13 @@ public class PetsResourceUnitTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testList() throws Exception { public void testList() throws Exception {
final List<Pet> people = asList(pets()); final List<Pet> pets = asList(pets());
expect(daoMock.list()).andReturn(people); expect(daoMock.list(existentPerson().getId())).andReturn(pets);
replay(daoMock); replay(daoMock);
final Response response = resource.list(); final Response response = resource.list(existentPet().getId());
assertThat(response, hasOkStatus()); assertThat(response, hasOkStatus());
assertThat((List<Pet>) response.getEntity(), containsPetsInAnyOrder(pets())); assertThat((List<Pet>) response.getEntity(), containsPetsInAnyOrder(pets()));
...@@ -76,11 +77,11 @@ public class PetsResourceUnitTest { ...@@ -76,11 +77,11 @@ public class PetsResourceUnitTest {
@Test @Test
public void testListDAOException() throws Exception { public void testListDAOException() throws Exception {
expect(daoMock.list()).andThrow(new DAOException()); expect(daoMock.list(existentPerson().getId())).andThrow(new DAOException());
replay(daoMock); replay(daoMock);
final Response response = resource.list(); final Response response = resource.list(existentPerson().getId());
assertThat(response, hasInternalServerErrorStatus()); assertThat(response, hasInternalServerErrorStatus());
} }
......
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