...
 
Commits (13)
......@@ -15,3 +15,8 @@ WebContent
# Testing
/servers
C:\\nppdf32Log\\debuglog.txt
#Santi
.idea/*
example.iml
......@@ -14,6 +14,18 @@ CREATE TABLE `daaexample`.`users` (
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`pet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner` VARCHAR(50) NOT NULL,
`name` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_pet_person` (`owner`),
CONSTRAINT `FK_pet_person` FOREIGN KEY (`owner`) REFERENCES `people` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa';
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Antón','Pérez');
......@@ -30,3 +42,5 @@ INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('admin', '713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca','ADMIN');
INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('normal', '7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83','USER');
INSERT INTO `daaexample`.`pet` (`id`, `owner`, `name`)
VALUES ('1', '1', 'Tom'), ('2', '1', 'Jerry');
......@@ -14,4 +14,14 @@ CREATE TABLE `daaexample`.`users` (
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`pet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner` int(11) NOT NULL,
`name` VARCHAR (50) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_pet_person` (`owner`),
CONSTRAINT `FK_pet_person` FOREIGN KEY (`owner`) REFERENCES `people` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa';
......@@ -5,7 +5,7 @@
<groupId>es.uvigo.esei.daa</groupId>
<artifactId>example</artifactId>
<packaging>war</packaging>
<version>0.1.11</version>
<version>0.1.12</version>
<name>DAA Example</name>
<licenses>
......
package es.uvigo.esei.daa;
import static java.util.stream.Collectors.toSet;
import es.uvigo.esei.daa.rest.PeopleResource;
import es.uvigo.esei.daa.rest.PetsResource;
import es.uvigo.esei.daa.rest.UsersResource;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import es.uvigo.esei.daa.rest.PeopleResource;
import es.uvigo.esei.daa.rest.UsersResource;
import static java.util.stream.Collectors.toSet;
/**
* Configuration of the REST application. This class includes the resources and
......@@ -26,7 +26,8 @@ public class DAAExampleApplication extends Application {
public Set<Class<?>> getClasses() {
return Stream.of(
PeopleResource.class,
UsersResource.class
UsersResource.class,
PetsResource.class
).collect(toSet());
}
......
package es.uvigo.esei.daa.dao;
import es.uvigo.esei.daa.entities.Pet;
import java.sql.*;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PetsDAO extends DAO {
private final static Logger LOG = Logger.getLogger(PetsDAO.class.getName());
public Pet get(int id) throws DAOException, IllegalArgumentException {
try (final Connection conn = this.getConnection()) {
final String query = "SELECT * FROM pet WHERE id=?";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, id);
try (final ResultSet result = statement.executeQuery()) {
if (result.next()) {
return rowToEntity(result);
} else {
throw new IllegalArgumentException("Invalid id");
}
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error getting a person", e);
throw new DAOException(e);
}
}
private Pet rowToEntity(ResultSet row) throws SQLException {
return new Pet(
row.getInt("id"),
row.getInt("owner"),
row.getString("name")
);
}
public void delete(int id)
throws DAOException, IllegalArgumentException {
try (final Connection conn = this.getConnection()) {
final String query = "DELETE FROM pet WHERE id=?";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, id);
if (statement.executeUpdate() != 1) {
throw new IllegalArgumentException("Invalid id");
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error deleting a pet", e);
throw new DAOException(e);
}
}
public List<Pet> list(int owner) throws DAOException {
try (final Connection conn = this.getConnection()) {
final String query = "SELECT * FROM pet WHERE owner = ?";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, owner);
try (final ResultSet result = statement.executeQuery()) {
final List<Pet> pets = new LinkedList<>();
while (result.next()) {
pets.add(rowToEntity(result));
}
return pets;
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
throw new DAOException(e);
}
}
public void modify(Pet pet)
throws DAOException, IllegalArgumentException {
if (pet == null) {
throw new IllegalArgumentException("pet can't be null");
}
try (Connection conn = this.getConnection()) {
final String query = "UPDATE pet SET name=?, owner=? WHERE id=?";
try (PreparedStatement statement = conn.prepareStatement(query)) {
statement.setString(1, pet.getName());
statement.setInt(2, pet.getOwner());
statement.setInt(3, pet.getId());
if (statement.executeUpdate() != 1) {
throw new IllegalArgumentException("name and owner can't be null");
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error modifying a pet", e);
throw new DAOException();
}
}
public Pet add(String name, int owner)
throws DAOException, IllegalArgumentException {
if (name == null) {
throw new IllegalArgumentException("name and owner can't be null");
}
try (Connection conn = this.getConnection()) {
final String query = "INSERT INTO pet VALUES(null, ?, ?)";
try (PreparedStatement statement = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, name);
statement.setInt(2, owner);
if (statement.executeUpdate() == 1) {
try (ResultSet resultKeys = statement.getGeneratedKeys()) {
if (resultKeys.next()) {
return new Pet(resultKeys.getInt(1), owner, name);
} else {
LOG.log(Level.SEVERE, "Error retrieving inserted id");
throw new SQLException("Error retrieving inserted id");
}
}
} else {
LOG.log(Level.SEVERE, "Error inserting value");
throw new SQLException("Error inserting value");
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error adding a pet", e);
throw new DAOException(e);
}
}
}
package es.uvigo.esei.daa.entities;
public class Pet {
private int id;
private String name;
private int owner;
// Constructor needed for the JSON conversion
Pet() {}
/**
* Constructs a new instance of {@link Pet}
*
* @param id idintefier of the pet
* @param name name of the pet
* @param owner identifier of the pet ownet
*/
public Pet(int id, int owner, String name) {
this.id = id;
this.name = name;
this.owner = owner;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getOwner() {
return owner;
}
public void setOwner(int owner) {
this.owner = owner;
}
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof Pet)) return false;
if (!super.equals(object)) return false;
Pet pet = (Pet) object;
return getId() == pet.getId() &&
getOwner() == pet.getOwner() &&
java.util.Objects.equals(getName(), pet.getName());
}
public int hashCode() {
return java.util.Objects.hash(super.hashCode(), getId(), getName(), getOwner());
}
}
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.PeopleDAO;
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.
*
*
* @author Miguel Reboiro Jato.
*/
@Path("/people")
@Produces(MediaType.APPLICATION_JSON)
public class PeopleResource {
private final static Logger LOG = Logger.getLogger(PeopleResource.class.getName());
private final PeopleDAO dao;
/**
* Constructs a new instance of {@link PeopleResource}.
*/
public PeopleResource() {
this(new PeopleDAO());
}
// Needed for testing purposes
PeopleResource(PeopleDAO 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
@Path("/{id}")
public Response get(
@PathParam("id") int id
) {
try {
final Person person = this.dao.get(id);
return Response.ok(person).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid person id in get method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error getting a person", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
/**
* Returns the complete list of people stored in the system.
*
* @return a 200 OK response with the complete list of people 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 people", 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("name") String name,
@FormParam("surname") String surname
) {
try {
final Person newPerson = this.dao.add(name, surname);
return Response.ok(newPerson).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid person 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 person", 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("name") String name,
@FormParam("surname") String surname
) {
try {
final Person modifiedPerson = new Person(id, name, surname);
this.dao.modify(modifiedPerson);
return Response.ok(modifiedPerson).build();
} catch (NullPointerException npe) {
final String message = String.format("Invalid data for person (name: %s, surname: %s)", name, surname);
LOG.log(Level.FINE, message);
return Response.status(Response.Status.BAD_REQUEST)
.entity(message)
.build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid person 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 person", 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 person 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 person", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
private final static Logger LOG = Logger.getLogger(PeopleResource.class.getName());
private final PeopleDAO dao;
/**
* Constructs a new instance of {@link PeopleResource}.
*/
public PeopleResource() {
this(new PeopleDAO());
}
// Needed for testing purposes
PeopleResource(PeopleDAO 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
@Path("/{id}")
public Response get(
@PathParam("id") int id
) {
try {
final Person person = this.dao.get(id);
return Response.ok(person).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid person id in get method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error getting a person", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
/**
* Returns the complete list of people stored in the system.
*
* @return a 200 OK response with the complete list of people 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 people", 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("name") String name,
@FormParam("surname") String surname
) {
try {
final Person newPerson = this.dao.add(name, surname);
return Response.ok(newPerson).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid person 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 person", 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("name") String name,
@FormParam("surname") String surname
) {
try {
final Person modifiedPerson = new Person(id, name, surname);
this.dao.modify(modifiedPerson);
return Response.ok(modifiedPerson).build();
} catch (NullPointerException npe) {
final String message = String.format("Invalid data for person (name: %s, surname: %s)", name, surname);
LOG.log(Level.FINE, message);
return Response.status(Response.Status.BAD_REQUEST)
.entity(message)
.build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid person 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 person", 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 person 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 person", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
}
package es.uvigo.esei.daa.rest;
import es.uvigo.esei.daa.dao.DAOException;
import es.uvigo.esei.daa.dao.PetsDAO;
import es.uvigo.esei.daa.entities.Pet;
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 pets.
*
* @author sgvilar.
*/
@Path("/pets")
@Produces(MediaType.APPLICATION_JSON)
public class PetsResource {
private final static Logger LOG = Logger.getLogger(PetsResource.class.getName());
private final PetsDAO dao;
public PetsResource() {
this(new PetsDAO());
}
PetsResource(PetsDAO dao) {
this.dao = dao;
}
@GET
@Path("/{id}")
public Response get(
@PathParam("id") int id
) {
try {
final Pet pet = this.dao.get(id);
return Response.ok(pet).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in get method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error getting a pet", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
@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();
}
}
@GET
@Path("/owner/{owner}")
public Response list(@PathParam("owner") int owner) {
try {
return Response.ok(this.dao.list(owner)).build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
return Response.serverError().entity(e.getMessage()).build();
}
}
@PUT
@Path("/{id}")
public Response modify(
@PathParam("id") int id,
@FormParam("name") String name,
@FormParam("owner") int owner
) {
try {
final Pet modifiedPet = new Pet(id, owner, name);
this.dao.modify(modifiedPet);
return Response.ok(modifiedPet).build();
} catch (NullPointerException npe) {
final String message = String.format("Invalid data for pet (name: %s, owner: %s)", name, owner);
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();
}
}
@POST
public Response add(
@FormParam("name") String name,
@FormParam("owner") int owner
) {
try {
final Pet newPet = this.dao.add(name, owner);
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();
}
}
}
......@@ -5,7 +5,7 @@ var PeopleDAO = (function() {
fail = typeof fail !== 'undefined' ? fail : function() {};
always = typeof always !== 'undefined' ? always : function() {};
let authToken = localStorage.getItem('authorization-token');
var authToken = localStorage.getItem('authorization-token');
if (authToken !== null) {
data.beforeSend = function(xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + authToken);
......@@ -23,7 +23,7 @@ var PeopleDAO = (function() {
}, done, fail, always);
};
this.addPerson = function(person, done, fail, always) {
this.addPet = function (person, done, fail, always) {
requestByAjax({
url : resourcePath,
type : 'POST',
......@@ -31,7 +31,7 @@ var PeopleDAO = (function() {
}, done, fail, always);
};
this.modifyPerson = function(person, done, fail, always) {
this.modifyPet = function (person, done, fail, always) {
requestByAjax({
url : resourcePath + person.id,
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 dao;
// Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery.
var self;
var formId = 'people-form';
var listId = 'people-list';
var formQuery = '#' + formId;
var listQuery = '#' + listId;
function PeopleView(peopleDao, formContainerId, listContainerId) {
dao = peopleDao;
self = this;
insertPeopleForm($('#' + formContainerId));
insertPeopleList($('#' + listContainerId));
this.init = function() {
dao.listPeople(function(people) {
$.each(people, function(key, person) {
appendToTable(person);
});
});
// 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 person = self.getPersonInForm();
if (self.isEditing()) {
dao.modifyPerson(person,
function(person) {
$('#person-' + person.id + ' td.name').text(person.name);
$('#person-' + person.id + ' td.surname').text(person.surname);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
} else {
dao.addPerson(person,
function(person) {
appendToTable(person);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
}
return false;
});
$('#btnClear').click(this.resetForm);
};
this.getPersonInForm = function() {
var form = $(formQuery);
return {
'id': form.find('input[name="id"]').val(),
'name': form.find('input[name="name"]').val(),
'surname': form.find('input[name="surname"]').val()
};
};
this.getPersonInRow = function(id) {
var row = $('#person-' + id);
if (row !== undefined) {
return {
'id': id,
'name': row.find('td.name').text(),
'surname': row.find('td.surname').text()
};
} else {
return undefined;
}
};
this.editPerson = function(id) {
var row = $('#person-' + 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="surname"]').val(row.find('td.surname').text());
$('input#btnSubmit').val('Modificar');
}
};
this.deletePerson = function(id) {
if (confirm('Está a punto de eliminar a una persona. ¿Está seguro de que desea continuar?')) {
dao.deletePerson(id,
function() {
$('tr#person-' + 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');
};
};
var insertPeopleList = function(parent) {
parent.append(
'<table id="' + listId + '" class="table">\
var PeopleView = (function () {
var dao;
// Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery.
var self;
var formId = 'people-form';
var listId = 'people-list';
var formQuery = '#' + formId;
var listQuery = '#' + listId;
function PeopleView(peopleDao, formContainerId, listContainerId) {
dao = peopleDao;
self = this;
insertPeopleForm($('#' + formContainerId));
insertPeopleList($('#' + listContainerId));
this.init = function () {
dao.listPeople(function (people) {
$.each(people, function (key, person) {
appendToTable(person);
});
},
function () {
alert('No has sido posible acceder al listado de personas.');
});
// 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 person = self.getPersonInForm();
if (self.isEditing()) {
dao.modifyPet(person,
function (person) {
$('#person-' + person.id + ' td.name').text(person.name);
$('#person-' + person.id + ' td.surname').text(person.surname);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
} else {
dao.addPet(person,
function (person) {
appendToTable(person);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
}
return false;
});
$('#btnClear').click(this.resetForm);
};
this.getPersonInForm = function () {
var form = $(formQuery);
return {
'id': form.find('input[name="id"]').val(),
'name': form.find('input[name="name"]').val(),
'surname': form.find('input[name="surname"]').val()
};
};
this.getPersonInRow = function (id) {
var row = $('#person-' + id);
if (row !== undefined) {
return {
'id': id,
'name': row.find('td.name').text(),
'surname': row.find('td.surname').text()
};
} else {
return undefined;
}
};
this.editPerson = function (id) {
var row = $('#person-' + 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="surname"]').val(row.find('td.surname').text());
$('input#btnSubmit').val('Modificar');
}
};
this.deletePerson = function (id) {
if (confirm('Está a punto de eliminar a una persona. ¿Está seguro de que desea continuar?')) {
dao.deletePet(id,
function () {
$('tr#person-' + id).remove();
},
showErrorMessage
);
}
};
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() != "";
};
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 insertPeopleList = function (parent) {
parent.append(
'<table id="' + listId + '" class="table">\
<thead>\
<tr class="row">\
<th class="col-sm-4">Nombre</th>\
......@@ -135,12 +150,12 @@ var PeopleView = (function() {
<tbody>\
</tbody>\
</table>'
);
};
);
};
var insertPeopleForm = function(parent) {
parent.append(
'<form id="' + formId + '" class="mb-5 mb-10">\
var insertPeopleForm = 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">\
......@@ -155,39 +170,46 @@ var PeopleView = (function() {
</div>\
</div>\
</form>'
);
};
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">\
<a class="edit btn btn-primary" href="#">Editar</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\
);
};
var createPersonRow = function (person) {
return '<tr id="person-' + person.id + '" class="row">\
<td class="name col-sm-6 col-md-3">' + person.name + '</td>\
<td class="surname col-sm-6 col-md-4">' + person.surname + '</td>\
<td class="col-sm-12 col-md-5">\
<a class="show-pets btn btn-primary" href="#">Mascotas</a>\
<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(person) {
$('#person-' + person.id + ' a.edit').click(function() {
self.editPerson(person.id);
});
$('#person-' + person.id + ' a.delete').click(function() {
self.deletePerson(person.id);
});
};
var appendToTable = function(person) {
$(listQuery + ' > tbody:last')
.append(createPersonRow(person));
addRowListeners(person);
};
return PeopleView;
};
var showErrorMessage = function (jqxhr, textStatus, error) {
alert(textStatus + ": " + error);
};
var addRowListeners = function (person) {
$('#person-' + person.id + ' a.edit').click(function () {
self.editPerson(person.id);
});
$('#person-' + person.id + ' a.delete').click(function () {
self.deletePerson(person.id);
});
$('#person-' + person.id + ' a.show-pets').click(function () {
self.showPets(person.id);
});
};
var appendToTable = function (person) {
$(listQuery + ' > tbody:last')
.append(createPersonRow(person));
addRowListeners(person);
};
return PeopleView;
})();
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;
})();
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<title>DAA Example</title>
<title>DAA Example</title>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
<header>
<div class="navbar navbar-dark bg-dark box-shadow">
<div class="container d-flex justify-content-between">
<a href="#" class="navbar-brand d-flex align-items-center">
<strong>DAA Example</strong>
</a>
<button id="logout" class="btn btn-dark">Cerrar sesión</button>
</div>
</div>
</header>
<header>
<div class="navbar navbar-dark bg-dark box-shadow">
<div class="container d-flex justify-content-between">
<a href="#" class="navbar-brand d-flex align-items-center">
<strong>DAA Example</strong>
</a>
<button id="logout" class="btn btn-dark">Cerrar sesión</button>
</div>
</div>
</header>
<div class="container">
<div id="people-container">
<h1 class="display-5 mt-3 mb-3">Personas</h1>
</div>
</div>
<script type="text/javascript"
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/login.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
$('#logout').click(function(event) {
event.preventDefault();
doLogout();
});
<div class="container">
<div id="people-container">
<h1 class="display-5 mt-3 mb-3">Personas</h1>
</div>
<div id="pet-container">
<h1 class="display-5 mt-3 mb-3">Mascotas</h1>
</div>
</div>
var view = new PeopleView(new PeopleDAO(),
'people-container', 'people-container'
);
<script type="text/javascript"
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(
function () {
$('#logout').click(function (event) {
event.preventDefault();
doLogout();
});
document.getElementById("pet-container").style.display = "none";
document.getElementById('people-container').style.display = 'block';
view.init();
});
</script>
var view = new PeopleView(new PeopleDAO(),
'people-container', 'people-container'
);
view.init();
});
</script>
</body>
</html>
\ No newline at end of file
package es.uvigo.esei.daa.dataset;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.stream;
import es.uvigo.esei.daa.entities.Person;
import java.util.Arrays;
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 {
private PeopleDataset() {}
......@@ -45,7 +45,7 @@ public final class PeopleDataset {
}
public static int existentId() {
return 5;
return 1;
}
public static int nonExistentId() {
......
package es.uvigo.esei.daa.dataset;
import es.uvigo.esei.daa.entities.Pet;
import static java.util.Arrays.stream;
public final class PetsDataset {
private PetsDataset() {
}
public static Pet[] pets() {
return new Pet[]{
new Pet(1, 1, "Tom"),
new Pet(2, 1, "Jerry")
};
}
public static Pet pet(int id) {
return stream(pets())
.filter(p -> p.getId() == id)
.findAny()
.orElseThrow(IllegalArgumentException::new);
}
public static int existentId() {
return 1;
}
public static Pet existentPet() {
return pet(existentId());
}
public static String newName() { return "Nibbles";}
public static int newOwner() {
return 2;
}
public static Pet newPet() {
return new Pet(pets().length + 1, newOwner(), newName());
}
}
package es.uvigo.esei.daa.matchers;
import es.uvigo.esei.daa.entities.Person;
import es.uvigo.esei.daa.entities.Pet;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
public class IsEqualToPet extends IsEqualToEntity<Pet> {
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("owner", Pet::getOwner, actual);
}
}
/**
* Factory method that creates a new {@link IsEqualToEntity} matcher with
* the provided {@link Person} as the expected value.
*
* @param pet the expected pet.
* @return a new {@link IsEqualToEntity} matcher with the provided
* {@link Person} 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 Person} 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 Person} of the
* provided ones as the expected value.
* @see IsEqualToEntity#containsEntityInAnyOrder(java.util.function.Function, Object...)
*/
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsInAnyOrder(Pet ... pets) {
return containsEntityInAnyOrder(IsEqualToPet::equalsToPet, pets);
}
}
package es.uvigo.esei.daa.rest;
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.DAAExampleApplication;
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;
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 javax.sql.DataSource;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.List;
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.userToken;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasOkStatus;
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;
@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") // Puede variar
@ExpectedDatabase("/datasets/dataset.xml") // Puede variar
public class PetsResourceTest extends JerseyTest {
@Override
protected Application configure() {
return new DAAExampleApplication();
}
@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> pets = response.readEntity(new GenericType<List<Pet>>() {
});
assertThat(pets, containsPetsInAnyOrder(pets()));
}
@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())));
}
}
package es.uvigo.esei.daa.rest;
import es.uvigo.esei.daa.dao.DAOException;
import es.uvigo.esei.daa.dao.PetsDAO;
import es.uvigo.esei.daa.entities.Pet;
import org.hamcrest.CoreMatchers;
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.PeopleDataset.existentPerson;
import static es.uvigo.esei.daa.dataset.PeopleDataset.newName;
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.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class PetsResourceUnitTest {
private PetsDAO daoMock;
private PetsResource resource;
@Before
public void setUp() throws Exception {
daoMock = createMock(PetsDAO.class);
resource = new PetsResource(daoMock);
}
@After
public void tearDown() throws Exception {
try {
verify(daoMock);
} finally {
daoMock = null;
resource = null;
}
}
@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
@SuppressWarnings("unchecked")
public void testList() throws Exception {
final List<Pet> pets = asList(pets());
expect(daoMock.list(existentPerson().getId())).andReturn(pets);
replay(daoMock);
final Response response = resource.list(existentPet().getId());
assertThat(response, hasOkStatus());
assertThat((List<Pet>) response.getEntity(), containsPetsInAnyOrder(pets()));
}
@Test
public void testListDAOException() throws Exception {
expect(daoMock.list(existentPerson().getId())).andThrow(new DAOException());
replay(daoMock);
final Response response = resource.list(existentPerson().getId());
assertThat(response, hasInternalServerErrorStatus());
}
@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.setOwner(newOwner());
daoMock.modify(pet);
replay(daoMock);
final Response response = resource.modify(
pet.getId(), pet.getName(), pet.getOwner());
assertThat(response, hasOkStatus());
assertEquals(pet, response.getEntity());
}
@Test
public void testAdd() throws Exception {
expect(daoMock.add(newName(), newOwner()))
.andReturn(newPet());
replay(daoMock);
final Response response = resource.add(newName(), newOwner());
assertThat(response, hasOkStatus());
assertThat((Pet) response.getEntity(), CoreMatchers.is(equalsToPet(newPet())));
}
@Test
public void testAddDAOException() throws Exception {
expect(daoMock.add(anyString(), anyInt()))
.andThrow(new DAOException());
replay(daoMock);
final Response response = resource.add(newName(), newOwner());
assertThat(response, hasInternalServerErrorStatus());
}
@Test
public void testAddIllegalArgumentException() throws Exception {
expect(daoMock.add(anyString(), anyInt()))
.andThrow(new IllegalArgumentException());
replay(daoMock);
final Response response = resource.add(newName(), newOwner());
assertThat(response, hasBadRequestStatus());
}
}
package es.uvigo.esei.daa.suites;
import es.uvigo.esei.daa.rest.PetsResourceUnitTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
......@@ -11,7 +12,8 @@ import es.uvigo.esei.daa.rest.UsersResourceTest;
@SuiteClasses({
PeopleDAOTest.class,
PeopleResourceTest.class,
UsersResourceTest.class
UsersResourceTest.class,
PetsResourceUnitTest.class
})
@RunWith(Suite.class)
public class IntegrationTestSuite {
......
......@@ -14,6 +14,11 @@
<people id="10" name="Juan" surname="Jiménez" />
<people id="11" name="John" surname="Doe" />
<pets id="1" owner="1" name="Tom"/>
<pets id="2" owner="1" name="Jerry"/>
<pets id="3" owner="2" name="Nibbles"/>
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
</dataset>
\ No newline at end of file
......@@ -12,6 +12,8 @@
<people id="9" name="Julia" surname="Justa" />
<people id="10" name="Juan" surname="Jiménez" />
<pets id="2" owner="1" name="Jerry"/>
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
</dataset>
\ No newline at end of file
......@@ -13,6 +13,10 @@
<people id="9" name="Julia" surname="Justa" />
<people id="10" name="Juan" surname="Jiménez" />
<pets id="1" owner="2" name="Nibbles"/>
<pets id="2" owner="1" name="Jerry"/>
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
</dataset>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT dataset (people*, users*)>
<!ELEMENT people EMPTY>
<!ELEMENT users EMPTY>
<!ATTLIST people
id CDATA #IMPLIED
name CDATA #IMPLIED
surname CDATA #IMPLIED
>
<!ATTLIST users
login CDATA #IMPLIED
password CDATA #IMPLIED
role CDATA #IMPLIED
>
<!ELEMENT dataset (people*, users*, pets*)>
<!ELEMENT people EMPTY>
<!ELEMENT users EMPTY>
<!ELEMENT pets EMPTY>
<!ATTLIST people
id CDATA #IMPLIED
name CDATA #IMPLIED
surname CDATA #IMPLIED
>
<!ATTLIST pets
id CDATA #IMPLIED
name CDATA #IMPLIED
owner CDATA #IMPLIED
>
<!ATTLIST users
login CDATA #IMPLIED
password CDATA #IMPLIED
role CDATA #IMPLIED
>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dataset SYSTEM "dataset.dtd">
<dataset>
<people id="1" name="Antón" surname="Álvarez" />
<people id="2" name="Ana" surname="Amargo" />
......@@ -13,6 +12,10 @@
<people id="9" name="Julia" surname="Justa" />
<people id="10" name="Juan" surname="Jiménez" />
<pets id="1" owner="1" name="Tom"/>
<pets id="2" owner="1" name="Jerry"/>
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
</dataset>
\ No newline at end of file
CREATE DATABASE `daaexample`;
CREATE TABLE `daaexample`.`people` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`surname` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`users` (
`login` varchar(100) NOT NULL,
`password` varchar(64) NOT NULL,
`role` varchar(10) NOT NULL,
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`pet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner` VARCHAR(50) NOT NULL,
`name` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_pet_person` (`owner`),
CONSTRAINT `FK_pet_person` FOREIGN KEY (`owner`) REFERENCES `people` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa';
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Antón','Pérez');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Manuel','Martínez');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Laura','Reboredo');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Perico','Palotes');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Ana','María');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'María','Nuevo');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Alba','Fernández');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Asunción','Jiménez');
-- The password for each user is its login suffixed with "pass". For example, user "admin" has the password "adminpass".
INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('admin', '713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca','ADMIN');
INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('normal', '7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83','USER');
INSERT INTO `daaexample`.`pet` (`id`, `owner`, `name`)
VALUES ('1', '1', 'Tom'), ('2', '1', 'Jerry');
CREATE DATABASE `daaexample`;
CREATE TABLE `daaexample`.`people` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`surname` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`users` (
`login` varchar(100) NOT NULL,
`password` varchar(64) NOT NULL,
`role` varchar(10) NOT NULL,
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`pet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner` int(11) NOT NULL,
`name` VARCHAR (50) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_pet_person` (`owner`),
CONSTRAINT `FK_pet_person` FOREIGN KEY (`owner`) REFERENCES `people` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa';