...
 
Commits (13)
...@@ -18,7 +18,7 @@ CREATE TABLE `daaexample`.`pets` ( ...@@ -18,7 +18,7 @@ CREATE TABLE `daaexample`.`pets` (
`name` varchar(30), `name` varchar(30),
`kind` varchar(30), `kind` varchar(30),
`breed` varchar(30), `breed` varchar(30),
`onwer` int references people(id) `owner` int references people(id)
); );
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa'; GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa';
...@@ -37,3 +37,5 @@ INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('admin', '43f413b7 ...@@ -37,3 +37,5 @@ INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('admin', '43f413b7
INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('normal', '688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336'); INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('normal', '688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336');
INSERT INTO `daaexample`.`pets` (`name`, `kind`, `breed`, `owner`) VALUES ("Ron", "Can", "Moito", 1); INSERT INTO `daaexample`.`pets` (`name`, `kind`, `breed`, `owner`) VALUES ("Ron", "Can", "Moito", 1);
INSERT INTO `daaexample`.`pets` (`name`, `kind`, `breed`, `owner`) VALUES ("Paul", "Gato", "Alerxico", 2);
INSERT INTO `daaexample`.`pets` (`name`, `kind`, `breed`, `owner`) VALUES ("Punky", "Gato", "Alerxico", 2);
...@@ -177,13 +177,6 @@ ...@@ -177,13 +177,6 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>nl.jqno.equalsverifier</groupId> <groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId> <artifactId>equalsverifier</artifactId>
......
package es.uvigo.esei.daa.entities; package es.uvigo.esei.daa.entities;
import static java.util.Objects.requireNonNull;
public class Pet { public class Pet {
private int id; private int id;
...@@ -31,7 +33,7 @@ public class Pet { ...@@ -31,7 +33,7 @@ public class Pet {
} }
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = requireNonNull(name, "Name can't be null");;
} }
public String getKind() { public String getKind() {
...@@ -39,7 +41,7 @@ public class Pet { ...@@ -39,7 +41,7 @@ public class Pet {
} }
public void setKind(String kind) { public void setKind(String kind) {
this.kind = kind; this.kind = requireNonNull(kind, "Kind can't be null");;
} }
public String getBreed() { public String getBreed() {
...@@ -47,7 +49,7 @@ public class Pet { ...@@ -47,7 +49,7 @@ public class Pet {
} }
public void setBreed(String breed) { public void setBreed(String breed) {
this.breed = breed; this.breed = requireNonNull(breed, "Breed can't be null");;
} }
public int getOwner() { public int getOwner() {
......
class NewPerson extends React.Component {
addPerson() {
var name = this.refs.name.value;
var surname = this.refs.surname.value;
this.refs.name.value = "";
this.refs.surname.value = "";
var person = {'name': name, 'surname': surname};
$.ajax({
url: 'rest/people/',
type: 'POST',
data: person,
success: (response) => {
console.log('Person added!', response);
}
});
}
render() {
return (
<div>
<input type="text" ref="name" placeholder="Enter a person name" />
<input type="text" ref="surname" placeholder="Enter a person surname" />
<button type="button" className="btn btn-primary" onClick={this.addPerson.bind(this)}>Submit</button>
</div>
)
}
}
class PeopleList extends React.Component{
render() {
var people = this.props.people.map(person =>
<Person key={person.id} person={person}/>
);
return (
<div>
<NewPerson />
<table className="table table-striped">
<tbody>
<tr>
<th>#</th>
<th>Name</th>
<th>Surname</th>
<th></th>
<th></th>
<th></th>
</tr>
{people}
</tbody>
</table>
</div>
)
}
}
class Person extends React.Component{
constructor(props) {
super(props);
this.state = {editable: false, isModalOpen: false};
}
handleDelete(id) {
if (confirm('Está a punto de eliminar a una persona. ¿Está seguro de que desea continuar?')) {
$.ajax({
url: 'rest/people/' + id,
type: 'DELETE',
success(response) {
console.log('Person successfully removed');
}
});
}
}
handleEdit(){
if (this.state.editable) {
var id = this.refs.id.value;
var name = this.refs.name.value;
var surname = this.refs.surname.value;
var person = {'id': id, 'name': name, 'surname': surname};
}
$.ajax({
url: 'rest/people/' + id,
type: 'PUT',
data: person,
success: (response) => {
console.log('Person updated!', response);
}
});
this.setState({editable: !this.state.editable});
}
openModal() {
this.setState({isModalOpen: true});
}
closeModal() {
this.setState({isModalOpen: false });
}
render() {
var id = this.state.editable ? <input type='hidden' ref="id" defaultValue={this.props.person.id} /> : <span>{this.props.person.id}</span>;
var name = this.state.editable ? <input type='text' ref="name" defaultValue={this.props.person.name} /> : <span>{this.props.person.name}</span>;
var surname = this.state.editable ? <input type='text' ref="surname" defaultValue={this.props.person.surname} /> : <span>{this.props.person.surname}</span>;
return (
<tr>
<td>{id}</td>
<td>{name}</td>
<td>{surname}</td>
<td>
<a href="#" onClick={() => this.openModal()}>
<i className="fa fa-paw" aria-hidden="true"></i>
</a>
<Modal isOpen={this.state.isModalOpen} onClose={() => this.closeModal()}>
<PetsApp id={this.props.person.id} owner_name={this.props.person.name}/>
</Modal>
</td>
<td>
<a href="#" onClick={this.handleEdit.bind(this, this.props.person.id)}>
{this.state.editable ? 'Submit' : 'Edit' }
<i className="fa fa-edit" aria-hidden="true"></i>
</a>
</td>
<td>
<a href="#" onClick={this.handleDelete.bind(this, this.props.person.id)}>
<i className="fa fa-trash-o" aria-hidden="true"></i>
</a>
</td>
</tr>
)
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {people: []};
}
componentDidMount() {
$.ajax({
url: 'rest/people',
type: 'GET',
success: (response) => {
this.setState({people: response})
}
});
}
componentWillUpdate() {
$.ajax({
url: 'rest/people',
type: 'GET',
success: (response) => {
this.setState({people: response})
}
});
}
render() {
return (
<PeopleList people={this.state.people}/>
)
}
}
class NewPet extends React.Component {
constructor(props) {
super(props);
}
addPet() {
var name = this.refs.name.value;
var kind = this.refs.kind.value;
var breed = this.refs.breed.value;
var owner = this.props.owner;
this.refs.name.value = "";
this.refs.kind.value = "";
this.refs.breed.value = "";
var pet = {'name': name, 'kind': kind, 'breed': breed, 'owner': owner};
$.ajax({
url: 'rest/pets/',
type: 'POST',
data: pet,
success: (response) => {
console.log('Pet added!', response);
}
});
}
render() {
return (
<div>
<input type="text" ref="name" placeholder="Enter a pet name" />
<input type="text" ref="kind" placeholder="Enter a pet kind" />
<input type="text" ref="breed" placeholder="Enter a pet breed" />
<button type="button" className="btn btn-primary" onClick={this.addPet.bind(this)}>Submit</button>
</div>
)
}
}
class PetsList extends React.Component{
constructor(props) {
super(props);
}
render() {
var pets = this.props.pets.map(pet =>
<Pet key={pet.id} pet={pet}/>
);
return (
<div>
<center><h1>Pets de {this.props.owner_name}</h1></center>
<NewPet owner={this.props.owner}/>
<table className="table table-striped">
<tbody>
<tr>
<th>#</th>
<th>Name</th>
<th>Kind</th>
<th>breed</th>
<th>owner</th>
<th></th>
<th></th>
</tr>
{pets}
</tbody>
</table>
</div>
)
}
}
class Pet extends React.Component{
constructor(props) {
super(props);
this.state = {editable: false};
}
handleDelete(id) {
if (confirm('Está a punto de eliminar a una mascota. ¿Está seguro de que desea continuar?')) {
$.ajax({
url: 'rest/pets/' + id,
type: 'DELETE',
success(response) {
console.log('Pet successfully removed');
}
});
}
}
handleEdit(id){
if (this.state.editable) {
var id = id;
var name = this.refs.name.value;
var kind = this.refs.kind.value;
var breed = this.refs.breed.value;
var owner = this.refs.owner.value;
var pet = {'id': id, 'name': name, 'kind': kind, 'breed': breed, 'owner': owner};
}
$.ajax({
url: 'rest/pets/' + id,
type: 'PUT',
data: pet,
success: (response) => {
console.log('Pet updated!', response);
}
});
this.setState({editable: !this.state.editable});
}
render() {
var id = this.state.editable ? <input type='hidden' ref="id" defaultValue={this.props.pet.id} /> : <span>{this.props.pet.id}</span>;
var name = this.state.editable ? <input type='text' ref="name" defaultValue={this.props.pet.name} /> : <span>{this.props.pet.name}</span>;
var kind = this.state.editable ? <input type='text' ref="kind" defaultValue={this.props.pet.kind} /> : <span>{this.props.pet.kind}</span>;
var breed = this.state.editable ? <input type='text' ref="breed" defaultValue={this.props.pet.breed} /> : <span>{this.props.pet.breed}</span>;
var owner = this.state.editable ? <input type='hidden' ref="owner" defaultValue={this.props.pet.owner} /> : <span>{this.props.pet.owner}</span>;
return (
<tr>
<td>{id}</td>
<td>{name}</td>
<td>{kind}</td>
<td>{breed}</td>
<td>{owner}</td>
<td>
<a href="#" onClick={this.handleEdit.bind(this, this.props.pet.id)}>
{this.state.editable ? 'Submit' : 'Edit' }
<i className="fa fa-edit" aria-hidden="true"></i>
</a>
</td>
<td>
<a href="#" onClick={this.handleDelete.bind(this, this.props.pet.id)}>
<i className="fa fa-trash-o" aria-hidden="true"></i>
</a>
</td>
</tr>
)
}
}
class PetsApp extends React.Component {
constructor(props) {
super(props);
this.state = {pets: []};
}
componentDidMount() {
$.ajax({
url: 'rest/people/' + this.props.id + '/pets' ,
type: 'GET',
success: (response) => {
this.setState({pets: response})
}
});
}
componentWillUnmount() {
}
componentWillUpdate() {
$.ajax({
url: 'rest/people/' + this.props.id + '/pets' ,
type: 'GET',
success: (response) => {
this.setState({pets: response})
}
});
}
render() {
return (
<PetsList pets={this.state.pets} owner={this.props.id} owner_name={this.props.owner_name} />
)
}
}
ReactDOM.render(
<App />,
document.getElementById('people-container')
)
class Modal extends React.Component {
render() {
if (this.props.isOpen === false)
return null
let modalStyle = {
position: 'absolute',
top: '40%',
left: '50%',
transform: 'translate(-50%, -50%)',
zIndex: '9999',
background: '#fff'
}
let backdropStyle = {
position: 'absolute',
width: '100%',
height: '100%',
top: '0px',
left: '0px',
zIndex: '9998',
background: 'rgba(0, 0, 0, 0.3)'
}
return (
<div>
<div style={modalStyle}>{this.props.children}</div>
<div style={backdropStyle} onClick={e => this.close(e)}/>}
</div>
)
}
close(e) {
e.preventDefault()
if (this.props.onClose) {
this.props.onClose()
}
}
}
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;
var selfpets;
var formId = 'people-form';
var listId = 'people-list';
var formQuery = '#' + formId;
var listQuery = '#' + listId;
var petsFormId = 'pets-form';
var petsListId = 'pets-list';
var petsFormQuery = '#' + petsFormId;
var petsListQuery = '#' + petsListId;
function PeopleView(peopleDao, petsDAO, formContainerId, listContainerId) {
dao = peopleDao;
pets = petsDAO;
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;
});
petsView = new PetsView();
petsView.init();
$('#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);
console.log(row);
if (row !== undefined) {
var form = $(formQuery);
console.log(form);
console.log(row.find('td.name').text());
console.log(row.find('td.surname').text());
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());
}
}
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 + '">\
<tr>\
<th>Nombre</th>\
<th>Apellido</th>\
<th></th>\
<th></th>\
</tr>\
</table>'
);
}
var insertPeopleForm = function(parent) {
parent.append(
'<form id="' + formId + '">\
<input name="id" type="hidden" value=""/>\
<input name="name" type="text" value="" />\
<input name="surname" type="text" value=""/>\
<input id="btnSubmit" type="submit" value="Create"/>\
<input id="btnClear" type="reset" value="Limpiar"/>\
</form>'
);
}
var createPersonRow = function(person) {
return '<tr id="person-'+ person.id +'">\
<td class="name">' + person.name + '</td>\
<td class="surname">' + person.surname + '</td>\
<td>\
<a class="edit" href="#">Edit</a>\
</td>\
<td>\
<a class="delete" href="#">Delete</a>\
</td>\
<td>\
<a class="pets" href="#">View Pets</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);
$('input#btnSubmit').val('Modificar');
});
$('#person-' + person.id + ' a.delete').click(function() {
if (confirm('Está a punto de eliminar a una persona. ¿Está seguro de que desea continuar?')) {
dao.deletePerson(person.id,
function() {
$('tr#person-' + person.id).remove();
},
showErrorMessage
);
}
});
$('#person-' + person.id + ' a.pets').click(function() {
showPeoplePets(person);
});
}
var appendToTable = function(person) {
$(listQuery + ' > tbody:last')
.append(createPersonRow(person));
addRowListeners(person);
}
var showPeoplePets = function(person) {
pets.listPeoplePets(person, function(pets) {
deletePetsTable();
createPetsTable(person.name);
$.each(pets, function (key, pet) {
addPetToTable(pet);
});
});
}
var deletePetsTable = function(){
$(petsListQuery).remove();
}
var createPetsTable = function (owner){
$('div').append(
'<table class="table" id="' + petsListId + '">\
<tr class="owner">\
<th>Mascotas de: ' + owner + '</th>\
<th></th>\
<th></th>\
<th></th>\
<th></th>\
</tr>\
<tr>\
<th>Nombre</th>\
<th>Especie</th>\
<th>Raza</th>\
<th></th>\
<th></th>\
</tr>\
</table>'
);
}
var addPetToTable = function (pet){
$(petsListQuery + ' > tbody:last').append(petToRow(pet));
addPetListeners(pet);
}
var addPetListeners = function(pet) {
$('#pet-' + pet.id + ' a.editPet').click(function() {
petToForm(pet);
$('input#petsBtnSubmit').val('Modificar');
});
$('#pet-' + pet.id + ' a.deletePet').click(function() {
if(confirm("Está a punto de eliminar a una mascota. ¿Está seguro de que desea continuar?")) {
pets.deletePet(pet.id,
function () {
$('tr#pet-' + pet.id).remove();
},
showErrorMessage
);
}
});
}
var insertPetList = function(parent) {
parent.append(
'<table id="' + petsListId + '">\
<tr>\
<th>Nombre</th>\
<th>Especie</th>\
<th>Raza</th>\
<th></th>\
<th></th>\
</tr>\
</table>'
);
}
var insertPetForm = function(parent) {
parent.append(
'<form id="' + petsFormId + '">\
<input name="id" type="hidden" value=""/>\
<input name="name" type="text" value="" />\
<input name="kind" type="text" value=""/>\
<input name="breed" type="text" value=""/>\
<input name="owner" type="hidden" value=""/>\
<input id="petsBtnSubmit" type="submit" value="Create"/>\
<input id="btnClear" type="reset" value="Limpiar"/>\
</form>'
);
}
var createPetRow = function(pet) {
return '<tr id="pet-'+ pet.id +'">\
<td class="name">' + pet.name + '</td>\
<td class="kind">' + pet.kind + '</td>\
<td class="breed">' + pet.breed + '</td>\
<td class="owner">' + pet.owner + '</td>\
<td>\
<a class="edit" href="#">Edit</a>\
</td>\
<td>\
<a class="delete" href="#">Delete</a>\
</td>\
</tr>';
}
var petToRow = function(pet) {
console.log(pet);
return '<tr id="pet-' + pet.id + '">\
<td class="name">' + pet.name + '</td>\
<td class="kind">' + pet.kind + '</td>\
<td class="breed">' + pet.breed + '</td>\
<td id="owner" type="hidden" value="' + pet.owner + '">\
<td>\
<a class="editPet" href="#">Edit</a>\
</td>\
<td>\
<a class="deletePet" href="#">Delete</a>\
</td>\
</tr>';
}
function petToForm(pet) {
var form = $(petsFormQuery);
console.log(pet.id);
form.find('input[name="petId"]').val(pet.id);
form.find('input[name="petName"]').val(pet.name);
form.find('input[name="kind"]').val(pet.kind);
form.find('input[name="breed"]').val(pet.breed);
form.find('input[name="owner"]').val(pet.owner);
}
var petsForm = function() {
$("body").append(
'<form id="' + petsFormId + '">\
<input name="petId" type="hidden" value=""/>\
Nombre: <input name="petName" type="text" value="" />\
Especie: <input name="kind" type="text" value="" />\
Raza: <input name="breed" type="text" value="" />\
Propietario: <input name="owner" type="text" value="" />\
<input id="petsBtnSubmit" type="submit" value="Crear"/>\
<input id="btnClear" type="reset" value="Limpiar"/>\
</form>'
);
}
var formToPet = function() {
var form = $(petsFormQuery);
return {
'id': form.find('input[name="petId"]').val(),
'name': form.find('input[name="petName"]').val(),
'kind': form.find('input[name="kind"]').val(),
'breed': form.find('input[name="breed"]').val(),
'owner': form.find('input[name="owner"]').val()
};
};
function PetsView() {
selfpets = this;
this.init = function() {
petsForm();
$(petsFormQuery).submit(function(event) {
var pet = selfpets.getPetInForm();
if (selfpets.isEditing()) {
pets.modifyPet(pet,
function(pet) {
$('#pet-' + pet.id + ' td.name').text(pet.name);
$('#pet-' + pet.id + ' td.kind').text(pet.kind);
$('#pet-' + pet.id + ' td.breed').text(pet.breed);
$('#pet-' + pet.id + ' td.owner').text(pet.owner);
selfpets.resetForm();
},
showErrorMessage,
selfpets.enableForm
);
} else {
console.log("ola");
pets.addPet(pet,
function(pet) {
selfpets.resetForm();
},
showErrorMessage,
selfpets.enableForm
);
}
return false;
});
$('#btnClear').click(this.resetForm);
};
selfpets.getPetInForm = function() {
var form = $(petsFormQuery);
return {
'id': form.find('input[name="petId"]').val(),
'name': form.find('input[name="petName"]').val(),
'kind': form.find('input[name="kind"]').val(),
'breed': form.find('input[name="breed"]').val(),
'owner': form.find('input[name="owner"]').val()
};
};
selfpets.getPetInRow = function(id) {
var row = $('#pet-' + id);
if (row !== undefined) {
return {
'id': id,
'name': row.find('td.name').text(),
'kind': row.find('td.kind').text(),
'breed': row.find('td.breed').text(),
'owner': row.find('td.owner')
};
} else {
return undefined;
}
};
selfpets.editPet = function(id) {
var row = $('#pet-' + id);
if (row !== undefined) {
var form = $(petsFormQuery);
form.find('input[name="petId"]').val(id);
form.find('input[name="petName"]').val(row.find('td.petName').text());
form.find('input[name="kind"]').val(row.find('td.kind').text());
form.find('input[name="breed"]').val(row.find('td.breed').text());
form.find('input[name="owner"]').val(owner);
}
}
selfpets.isEditing = function() {
return $(petsFormQuery + ' input[name="petId"]').val() != "";
};
selfpets.disableForm = function() {
$(petsFormQuery + ' input').prop('disabled', true);
};
selfpets.enableForm = function() {
$(petsFormQuery + ' input').prop('disabled', false);
};
selfpets.resetForm = function() {
$(petsFormQuery)[0].reset();
$(petsFormQuery + ' input[name="petId"]').val('');
$('#petsBtnSubmit').val('Crear');
};
}
return PeopleView;
})();
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>DAA Example</title> <title>DAA Example</title>
</head>
<body>
<div id="people-container">
<h1>People</h1>
<a id="#logout" href="logout">Logout</a>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.2.0.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="js/dao/people.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script type="text/javascript" src="js/view/people.js"></script>
<script type="text/javascript" src="js/dao/pets.js"></script> </head>
<script type="text/javascript" src="js/view/pets.js"></script> <body>
<script type="text/javascript">
$(document).ready(function() { <div class="page-header">
var view = new PeopleView(new PeopleDAO(), new PetsDAO(), 'people-container', 'people-container'); <h1>People and Pets Manager <small>simple webapp to manage people and their pets</small></h1>
view.init(); </div>
});
</script> <div id="people-container">
</body> </div>
<a id="#logout" href="logout"><button type="button" class="btn btn-danger">Logout</button></a>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-select/0.9.1/react-select.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.23.1/babel.js"></script>
<script type="text/javascript" src="js/dao/people.js"></script>
<script type="text/javascript" src="js/dao/pets.js"></script>
<script type="text/babel" src="js/view/people-container.js"></script>
</body>
</html> </html>
\ No newline at end of file
package es.uvigo.esei.daa.dao;
import static es.uvigo.esei.daa.dataset.PetsDataset.*;
import static es.uvigo.esei.daa.matchers.IsEqualToPet.*;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import es.uvigo.esei.daa.entities.Pet;
import es.uvigo.esei.daa.listeners.ApplicationContextBinding;
import es.uvigo.esei.daa.listeners.ApplicationContextJndiBindingTestExecutionListener;
import es.uvigo.esei.daa.listeners.DbManagement;
import es.uvigo.esei.daa.listeners.DbManagementTestExecutionListener;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:contexts/mem-context.xml")
@TestExecutionListeners({
DbUnitTestExecutionListener.class,
DbManagementTestExecutionListener.class,
ApplicationContextJndiBindingTestExecutionListener.class
})
@ApplicationContextBinding(
jndiUrl = "java:/comp/env/jdbc/daaexample",
type = DataSource.class
)
@DbManagement(
create = "classpath:db/hsqldb.sql",
drop = "classpath:db/hsqldb-drop.sql"
)
@DatabaseSetup("/datasets/dataset.xml")
@ExpectedDatabase("/datasets/dataset.xml")
public class PetsDAOTest {
private PetsDAO dao;
@Before
public void setUp() throws Exception {
this.dao = new PetsDAO();
}
@Test
public void testList() throws DAOException {
assertThat(this.dao.list(), containsPetsInAnyOrder(pets()));
}
@Test
public void testGet() throws DAOException {
final Pet pet = this.dao.get(existentId());
assertThat(pet, is(equalsToPet(existentPet())));
}
@Test(expected = IllegalArgumentException.class)
public void testGetNonExistentId() throws DAOException {
this.dao.get(nonExistentId());
}
@Test
@ExpectedDatabase("/datasets/dataset-delete.xml")
public void testDelete() throws DAOException {
this.dao.delete(existentId());
assertThat(this.dao.list(), containsPetsInAnyOrder(petWithout(existentId())));
}
@Test(expected = IllegalArgumentException.class)
public void testDeleteNonExistentId() throws DAOException {
this.dao.delete(nonExistentId());
}
@Test
@ExpectedDatabase("/datasets/dataset-modify.xml")
public void testModify() throws DAOException {
final Pet pet = existentPet();
pet.setId(newId());
pet.setName(newName());
pet.setKind(newKind());
pet.setBreed(newBreed());
pet.setOwner(newOwner());
this.dao.modify(pet);
final Pet persistentPet = this.dao.get(pet.getId());
assertThat(persistentPet, is(equalsToPet(pet)));
}
@Test(expected = IllegalArgumentException.class)
public void testModifyNonExistentId() throws DAOException {
this.dao.modify(nonExistentPet());
}
@Test(expected = IllegalArgumentException.class)
public void testModifyNullPet() throws DAOException {
this.dao.modify(null);
}
@Test
@ExpectedDatabase("/datasets/dataset-add.xml")
public void testAdd() throws DAOException {
final Pet pet = this.dao.add(new Pet(newId(), newName(), newKind(), newBreed(), newOwner()));
assertThat(pet, is(equalsToPet(newPet())));
final Pet persistentPet = this.dao.get(pet.getId());
assertThat(persistentPet, is(equalsToPet(newPet())));
}
@Test(expected = IllegalArgumentException.class)
public void testAddNullPet() throws DAOException {
this.dao.add(null);
}
}
package es.uvigo.esei.daa.dao;
import static es.uvigo.esei.daa.dataset.PetsDataset.*;
import static es.uvigo.esei.daa.matchers.IsEqualToPet.*;
import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reset;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.sql.SQLException;
import org.junit.Test;
import com.mysql.jdbc.Statement;
import es.uvigo.esei.daa.entities.Pet;
import es.uvigo.esei.daa.util.DatabaseQueryUnitTest;
public class PetsDAOUnitTest extends DatabaseQueryUnitTest {
@Test
public void testList() throws Exception {
final Pet[] pets = pets();
for (Pet pet : pets) {
expectPetRow(pet);
}
expect(result.next()).andReturn(false);
result.close();
replayAll();
final PetsDAO petsDAO = new PetsDAO();
assertThat(petsDAO.list(), containsPetsInAnyOrder(pets));
}
@Test(expected = DAOException.class)
public void testListUnexpectedException() throws Exception {
expect(result.next()).andThrow(new SQLException());
result.close();
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.list();
}
@Test
public void testGet() throws Exception {
final Pet existentPet = existentPet();
expectPetRow(existentPet);
result.close();
replayAll();
final PetsDAO petsDAO = new PetsDAO();
assertThat(petsDAO.get(existentId()), is(equalTo(existentPet)));
}
@Test(expected = IllegalArgumentException.class)
public void testGetMissing() throws Exception {
expect(result.next()).andReturn(false);
result.close();
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.get(existentId());
}
@Test(expected = DAOException.class)
public void testGetUnexpectedException() throws Exception {
expect(result.next()).andThrow(new SQLException());
result.close();
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.get(existentId());
}
@Test
public void testAdd() throws Exception {
final Pet pet = newPet();
reset(connection);
expect(connection.prepareStatement(anyString(), eq(Statement.RETURN_GENERATED_KEYS)))
.andReturn(statement);
expect(statement.executeUpdate()).andReturn(1);
connection.close();
replayAll();
final PetsDAO petsDAO = new PetsDAO();
final Pet newPet = petsDAO.add(new Pet(pet.getId(), pet.getName(), pet.getKind(), pet.getBreed(), pet.getOwner()));
assertThat(newPet, is(equalsToPet(pet)));
}
@Test(expected = IllegalArgumentException.class)
public void testAddNullPet() throws Exception {
replayAll();
final PetsDAO petsDAO = new PetsDAO();
resetAll(); // No expectations
petsDAO.add(null);
}
@Test
public void testDelete() throws Exception {
expect(statement.executeUpdate()).andReturn(1);
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.delete(existentId());
}
@Test(expected = IllegalArgumentException.class)
public void testDeleteInvalidId() throws Exception {
expect(statement.executeUpdate()).andReturn(0);
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.delete(existentId());
}
@Test(expected = DAOException.class)
public void testDeleteUnexpectedException() throws Exception {
expect(statement.executeUpdate()).andThrow(new SQLException());
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.delete(existentId());
}
@Test
public void testModify() throws Exception {
expect(statement.executeUpdate()).andReturn(1);
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.modify(existentPet());
}
@Test(expected = IllegalArgumentException.class)
public void testModifyNullPet() throws Exception {
replayAll();
final PetsDAO petsDAO = new PetsDAO();
resetAll(); // No expectations
petsDAO.modify(null);
}
@Test(expected = IllegalArgumentException.class)
public void testModifyZeroUpdatedRows() throws Exception {
expect(statement.executeUpdate()).andReturn(0);
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.modify(existentPet());
}
@Test(expected = DAOException.class)
public void testModifyUnexpectedException() throws Exception {
expect(statement.executeUpdate()).andThrow(new SQLException());
replayAll();
final PetsDAO petsDAO = new PetsDAO();
petsDAO.modify(existentPet());
}
private void expectPetRow(Pet pet) throws SQLException {
expect(result.next()).andReturn(true);
expect(result.getInt("id")).andReturn(pet.getId());
expect(result.getString("name")).andReturn(pet.getName());
expect(result.getString("kind")).andReturn(pet.getKind());
expect(result.getString("breed")).andReturn(pet.getBreed());
expect(result.getInt("owner")).andReturn(pet.getOwner());
}
}
package es.uvigo.esei.daa.dataset;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.stream;
import java.util.Arrays;
import java.util.function.Predicate;
import es.uvigo.esei.daa.entities.Pet;
public final class PetsDataset {
private PetsDataset() {}
public static Pet[] pets() {
return new Pet[] {
new Pet(1, "Ron", "Can", "Moito", 1),
new Pet(2, "Paul", "Gato", "Alerxico", 2),
new Pet(3, "Punky", "Gato", "Alerxico", 2)
};
}
public static Pet[] petWithout(int ... ids) {
Arrays.sort(ids);
final Predicate<Pet> hasValidId = pet ->
binarySearch(ids, pet.getId()) < 0;
return stream(pets())
.filter(hasValidId)
.toArray(Pet[]::new);
}
public static Pet pet(int id) {
return stream(pets())
.filter(pet -> pet.getId() == id)
.findAny()
.orElseThrow(IllegalArgumentException::new);
}
public static int existentId() {
return 1;
}
public static int nonExistentId() {
return 1234;
}
public static Pet existentPet() {
return pet(existentId());
}
public static Pet nonExistentPet() {
return new Pet(nonExistentId(), "Cospe", "Gaivota", "Pepera", 1);
}
public static int newId() {
return 4;
}
public static String newName() {
return "Cospe";
}
public static String newKind() {
return "Gaivota";
}
public static String newBreed() {
return "Pepera";
}
public static int newOwner() {
return 1;
}
public static Pet newPet() {
return new Pet(pets().length + 1, newName(), newKind(), newBreed(), newOwner());
}
}
package es.uvigo.esei.daa.entities;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Test;
public class PetUnitTest {
@Test
public void testPetIntStringStringStringInt() {
final int id = 1;
final String name = "Ron";
final String kind = "Can";
final String breed = "Moito";
final int owner = 1;
final Pet pet = new Pet(id, name, kind, breed, owner);
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getKind(), is(equalTo(kind)));
assertThat(pet.getBreed(), is(equalTo(breed)));
assertThat(pet.getOwner(), is(equalTo(owner)));
}
@Test(expected = NullPointerException.class)
public void testPetIntStringStringStringIntNullName() {
new Pet(1, null, "Can", "Moito", 1);
}
@Test(expected = NullPointerException.class)
public void testPetIntStringStringStringIntNullKind() {
new Pet(1, "Ron", null, "Moito", 1);
}
@Test(expected = NullPointerException.class)
public void testPetIntStringStringStringIntNullBreed() {
new Pet(1, "Ron", "Can", null, 1);
}
@Test
public void testSetName() {
final int id = 1;
final String kind = "Can";
final String breed = "Moito";
final int owner = 1;
final Pet pet = new Pet(id, "Ron", kind, breed, owner);
pet.setName("Blas");
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo("Blas")));
assertThat(pet.getKind(), is(equalTo(kind)));
assertThat(pet.getBreed(), is(equalTo(breed)));
assertThat(pet.getOwner(), is(equalTo(owner)));
}
@Test(expected = NullPointerException.class)
public void testSetNullName() {
final Pet pet = new Pet(1, "Ron", "Can", "Moito", 1);
pet.setName(null);
}
@Test
public void testSetKind() {
final int id = 1;
final String name = "Ron";
final String breed = "Moito";
final int owner = 1;
final Pet pet = new Pet(id, name, "Can", breed, owner);
pet.setKind("Gato");
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getKind(), is(equalTo("Gato")));
assertThat(pet.getBreed(), is(equalTo(breed)));
assertThat(pet.getOwner(), is(equalTo(owner)));
}
@Test(expected = NullPointerException.class)
public void testSetNullKind() {
final Pet pet = new Pet(1, "Ron", "Can", "Moito", 1);
pet.setKind(null);
}
@Test
public void testSetBreed() {
final int id = 1;
final String name = "Ron";
final String kind = "Can";
final int owner = 1;
final Pet pet = new Pet(id, name, kind, "Moito", owner);
pet.setBreed("Pouco");
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getKind(), is(equalTo(kind)));
assertThat(pet.getBreed(), is(equalTo("Pouco")));
assertThat(pet.getOwner(), is(equalTo(owner)));
}
@Test(expected = NullPointerException.class)
public void testSetNullBreed() {
final Pet pet = new Pet(1, "Ron", "Can", "Moito", 1);
pet.setBreed(null);
}
}
package es.uvigo.esei.daa.matchers;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import es.uvigo.esei.daa.entities.Pet;
public class IsEqualToPet extends IsEqualToEntity<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("kind", Pet::getKind, actual)
&& checkAttribute("breed", Pet::getBreed, actual)
&& checkAttribute("owner", Pet::getOwner, actual);
}
}
/**
* Factory method that creates a new {@link IsEqualToEntity} matcher with
* the provided {@link Pet} as the expected value.
*
* @param pet the expected person.
* @return a new {@link IsEqualToEntity} matcher with the provided
* {@link Pet} as the expected value.
*/
@Factory
public static IsEqualToPet equalsToPet(Pet pet) {
return new IsEqualToPet(pet);
}
/**
* Factory method that returns a new {@link Matcher} that includes several
* {@link IsEqualToPet} matchers, each one using an {@link Pet} of the
* provided ones as the expected value.
*
* @param pets the pets to be used as the expected values.
* @return a new {@link Matcher} that includes several
* {@link IsEqualToPet} matchers, each one using an {@link Pet} of the
* provided ones as the expected value.
* @see IsEqualToEntity#containsEntityInAnyOrder(java.util.function.Function, Object...)
*/
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsInAnyOrder(Pet ... pets) {
return containsEntityInAnyOrder(IsEqualToPet::equalsToPet, pets);
}
}
package es.uvigo.esei.daa.rest;
import static es.uvigo.esei.daa.dataset.PetsDataset.*;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasBadRequestStatus;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasOkStatus;
import static es.uvigo.esei.daa.matchers.IsEqualToPet.*;
import static javax.ws.rs.client.Entity.entity;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.util.List;
import javax.sql.DataSource;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import es.uvigo.esei.daa.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;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:contexts/mem-context.xml")
@TestExecutionListeners({
DbUnitTestExecutionListener.class,
DbManagementTestExecutionListener.class,
ApplicationContextJndiBindingTestExecutionListener.class
})
@ApplicationContextBinding(
jndiUrl = "java:/comp/env/jdbc/daaexample",
type = DataSource.class
)
@DbManagement(
create = "classpath:db/hsqldb.sql",
drop = "classpath:db/hsqldb-drop.sql"
)
@DatabaseSetup("/datasets/dataset.xml")
@ExpectedDatabase("/datasets/dataset.xml")
public class 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().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().get();
assertThat(response, hasOkStatus());
final Pet pet = response.readEntity(Pet.class);
assertThat(pet, is(equalsToPet(existentPet())));
}
@Test
public void testGetInvalidId() throws IOException {
final Response response = target("pets/" + nonExistentId()).request().get();
assertThat(response, hasBadRequestStatus());
}
@Test
@ExpectedDatabase("/datasets/dataset-add.xml")
public void testAdd() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("kind", newKind());
form.param("breed", newBreed());
form.param("owner", Integer.toString(newOwner()));
final Response response = target("pets")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasOkStatus());
final Pet pet = response.readEntity(Pet.class);
assertThat(pet, is(equalsToPet(newPet())));
}
@Test
public void testAddMissingName() throws IOException {
final Form form = new Form();
form.param("kind", newKind());
form.param("breed", newBreed());
form.param("owner", Integer.toString(newOwner()));
final Response response = target("pets")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testAddMissingKind() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("breed", newBreed());
form.param("owner", Integer.toString(newOwner()));
final Response response = target("pets")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testAddMissingBreed() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("kind", newKind());
form.param("owner", Integer.toString(newOwner()));
final Response response = target("pets")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
@ExpectedDatabase("/datasets/dataset-modify.xml")
public void testModify() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("kind", newKind());
form.param("breed", newBreed());
form.param("owner", Integer.toString(newOwner()));
final Response response = target("pets/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasOkStatus());
final Pet modifiedPet = response.readEntity(Pet.class);
final Pet pet = existentPet();
pet.setName(newName());
pet.setKind(newKind());
pet.setBreed(newBreed());
pet.setOwner(newOwner());
assertThat(modifiedPet, is(equalsToPet(pet)));
}
@Test
public void testModifyName() throws IOException {
final Form form = new Form();
form.param("name", newName());
final Response response = target("pets/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testModifyKind() throws IOException {
final Form form = new Form();
form.param("kind", newKind());
final Response response = target("pets/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testModifyBreed() throws IOException {
final Form form = new Form();
form.param("breed", newBreed());
final Response response = target("pets/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testModifyInvalidId() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("kind", newKind());
form.param("breed", newBreed());
form.param("owner", Integer.toString(newOwner()));
final Response response = target("pets/" + nonExistentId())
.request(MediaType.APPLICATION_JSON_TYPE)
.put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
@ExpectedDatabase("/datasets/dataset-delete.xml")
public void testDelete() throws IOException {
final Response response = target("pets/" + existentId()).request().delete();
assertThat(response, hasOkStatus());
final Integer deletedId = response.readEntity(Integer.class);
assertThat(deletedId, is(equalTo(existentId())));
}
@Test
public void testDeleteInvalidId() throws IOException {
final Response response = target("pets/" + nonExistentId()).request().delete();
assertThat(response, hasBadRequestStatus());
}
}
package es.uvigo.esei.daa.rest;
import static es.uvigo.esei.daa.dataset.PetsDataset.*;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasBadRequestStatus;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasInternalServerErrorStatus;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasOkStatus;
import static es.uvigo.esei.daa.matchers.IsEqualToPet.*;
import static java.util.Arrays.asList;
import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.List;
import javax.ws.rs.core.Response;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import es.uvigo.esei.daa.dao.DAOException;
import es.uvigo.esei.daa.dao.PetsDAO;
import es.uvigo.esei.daa.entities.Pet;
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
@SuppressWarnings("unchecked")
public void testList() throws Exception {
final List<Pet> pet = asList(pets());
expect(daoMock.list()).andReturn(pet);
replay(daoMock);
final Response response = resource.list();
assertThat(response, hasOkStatus());
assertThat((List<Pet>) response.getEntity(), containsPetsInAnyOrder(pets()));
}
@Test
public void testListDAOException() throws Exception {
expect(daoMock.list()).andThrow(new DAOException());
replay(daoMock);
final Response response = resource.list();
assertThat(response, hasInternalServerErrorStatus());
}
@Test
public void testGet() throws Exception {
final Pet pet = existentPet();
expect(daoMock.get(pet.getId())).andReturn(pet);
replay(daoMock);
final Response response = resource.get(pet.getId());
assertThat(response, hasOkStatus());
assertThat((Pet) response.getEntity(), is(equalsToPet(pet)));
}
@Test
public void testGetDAOException() throws Exception {
expect(daoMock.get(anyInt())).andThrow(new DAOException());
replay(daoMock);
final Response response = resource.get(existentId());
assertThat(response, hasInternalServerErrorStatus());
}
@Test
public void testGetIllegalArgumentException() throws Exception {
expect(daoMock.get(anyInt())).andThrow(new IllegalArgumentException());
replay(daoMock);
final Response response = resource.get(existentId());
assertThat(response, hasBadRequestStatus());
}
@Test
public void testDelete() throws Exception {
daoMock.delete(anyInt());
replay(daoMock);
final Response response = resource.delete(1);
assertThat(response, hasOkStatus());
}
@Test
public void testDeleteDAOException() throws Exception {
daoMock.delete(anyInt());
expectLastCall().andThrow(new DAOException());
replay(daoMock);
final Response response = resource.delete(1);
assertThat(response, hasInternalServerErrorStatus());
}
@Test
public void testDeleteIllegalArgumentException() throws Exception {
daoMock.delete(anyInt());
expectLastCall().andThrow(new IllegalArgumentException());
replay(daoMock);
final Response response = resource.delete(1);
assertThat(response, hasBadRequestStatus());
}
@Test
public void testModify() throws Exception {
final Pet pet = existentPet();
pet.setId(newId());
pet.setName(newName());
pet.setKind(newKind());
pet.setBreed(newBreed());
pet.setOwner(newOwner());
daoMock.modify(pet);
replay(daoMock);
final Response response = resource.modify(
pet.getId(), pet.getName(), pet.getKind(), pet.getBreed(), pet.getOwner());
assertThat(response, hasOkStatus());
assertEquals(pet, response.getEntity());
}
@Test
public void testModifyDAOException() throws Exception {
daoMock.modify(anyObject());
expectLastCall().andThrow(new DAOException());
replay(daoMock);
final Response response = resource.modify(existentId(), newName(), newKind(), newBreed(), newOwner());
assertThat(response, hasInternalServerErrorStatus());
}
@Test
public void testModifyIllegalArgumentException() throws Exception {
daoMock.modify(anyObject());
expectLastCall().andThrow(new IllegalArgumentException());
replay(daoMock);
final Response response = resource.modify(existentId(), newName(), newKind(), newBreed(), newOwner());
assertThat(response, hasBadRequestStatus());
}
@Test
public void testModifyNullPointerException() throws Exception {
daoMock.modify(anyObject());
expectLastCall().andThrow(new NullPointerException());
replay(daoMock);
final Response response = resource.modify(existentId(), newName(), newKind(), newBreed(), newOwner());
assertThat(response, hasBadRequestStatus());
}
@Test
public void testAdd() throws Exception {
expect(daoMock.add(newPet()))
.andReturn(newPet());
replay(daoMock);
final Response response = resource.add(newName(), newKind(), newBreed(), newOwner());
assertThat(response, hasOkStatus());
assertThat((Pet) response.getEntity(), is(equalsToPet(newPet())));
}
@Test
public void testAddDAOException() throws Exception {
expect(daoMock.add(newPet()))
.andThrow(new DAOException());
replay(daoMock);
final Response response = resource.add(newName(), newKind(), newBreed(), newOwner());
assertThat(response, hasInternalServerErrorStatus());
}
@Test
public void testAddIllegalArgumentException() throws Exception {
expect(daoMock.add(newPet()))
.andThrow(new IllegalArgumentException());
replay(daoMock);
final Response response = resource.add(newName(), newKind(), newBreed(), newOwner());
assertThat(response, hasBadRequestStatus());
}
}
...@@ -6,12 +6,14 @@ import org.junit.runners.Suite.SuiteClasses; ...@@ -6,12 +6,14 @@ import org.junit.runners.Suite.SuiteClasses;
import es.uvigo.esei.daa.dao.PeopleDAOTest; import es.uvigo.esei.daa.dao.PeopleDAOTest;
import es.uvigo.esei.daa.rest.PeopleResourceTest; import es.uvigo.esei.daa.rest.PeopleResourceTest;
import es.uvigo.esei.daa.rest.PetsResourceTest;
import es.uvigo.esei.daa.rest.UsersResourceTest; import es.uvigo.esei.daa.rest.UsersResourceTest;
@SuiteClasses({ @SuiteClasses({
PeopleDAOTest.class, PeopleDAOTest.class,
PeopleResourceTest.class, PeopleResourceTest.class,
UsersResourceTest.class UsersResourceTest.class,
PetsResourceTest.class
}) })
@RunWith(Suite.class) @RunWith(Suite.class)
public class IntegrationTestSuite { public class IntegrationTestSuite {
......
...@@ -5,13 +5,17 @@ import org.junit.runners.Suite; ...@@ -5,13 +5,17 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
import es.uvigo.esei.daa.dao.PeopleDAOUnitTest; import es.uvigo.esei.daa.dao.PeopleDAOUnitTest;
import es.uvigo.esei.daa.dao.PetsDAOUnitTest;
import es.uvigo.esei.daa.entities.PersonUnitTest; import es.uvigo.esei.daa.entities.PersonUnitTest;
import es.uvigo.esei.daa.rest.PeopleResourceUnitTest; import es.uvigo.esei.daa.rest.PeopleResourceUnitTest;
import es.uvigo.esei.daa.rest.PetsResourceUnitTest;
@SuiteClasses({ @SuiteClasses({
PersonUnitTest.class, PersonUnitTest.class,
PeopleDAOUnitTest.class, PeopleDAOUnitTest.class,
PeopleResourceUnitTest.class PeopleResourceUnitTest.class,
PetsDAOUnitTest.class,
PetsResourceUnitTest.class
}) })
@RunWith(Suite.class) @RunWith(Suite.class)
public class UnitTestSuite { public class UnitTestSuite {
......
...@@ -16,4 +16,9 @@ ...@@ -16,4 +16,9 @@
<users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" /> <users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" />
<users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" /> <users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" />
<pets id="1" name="Ron" kind="Can" breed="Moito" owner="1" />
<pets id="2" name="Paul" kind="Gato" breed="Alerxico" owner="2" />
<pets id="3" name="Punky" kind="Gato" breed="Alerxico" owner="2" />
<pets id="4" name="Cospe" kind="Gaivota" breed="Pepera" owner="1" />
</dataset> </dataset>
\ No newline at end of file
...@@ -14,4 +14,7 @@ ...@@ -14,4 +14,7 @@
<users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" /> <users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" />
<users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" /> <users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" />
<pets id="1" name="Ron" kind="Can" breed="Moito" owner="1" />
<pets id="2" name="Paul" kind="Gato" breed="Alerxico" owner="2" />
</dataset> </dataset>
\ No newline at end of file
...@@ -15,4 +15,8 @@ ...@@ -15,4 +15,8 @@
<users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" /> <users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" />
<users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" /> <users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" />
<pets id="1" name="Ron" kind="Can" breed="Moito" owner="1" />
<pets id="2" name="Paul" kind="Gato" breed="Alerxico" owner="2" />
<pets id="3" name="Punky" kind="Gato" breed="Alerxico" owner="2" />
</dataset> </dataset>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT dataset (people*, users*)> <!ELEMENT dataset (people*, users*, pets*)>
<!ELEMENT people EMPTY> <!ELEMENT people EMPTY>
<!ELEMENT users EMPTY> <!ELEMENT users EMPTY>
<!ELEMENT pets EMPTY>
<!ATTLIST people <!ATTLIST people
id CDATA #IMPLIED id CDATA #IMPLIED
name CDATA #IMPLIED name CDATA #IMPLIED
...@@ -11,3 +12,10 @@ ...@@ -11,3 +12,10 @@
login CDATA #IMPLIED login CDATA #IMPLIED
password CDATA #IMPLIED password CDATA #IMPLIED
> >
<!ATTLIST pets
id CDATA #IMPLIED
name CDATA #IMPLIED
kind CDATA #IMPLIED
breed CDATA #IMPLIED
owner CDATA #IMPLIED
>
\ No newline at end of file
...@@ -15,4 +15,8 @@ ...@@ -15,4 +15,8 @@
<users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" /> <users login="admin" password="43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70" />
<users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" /> <users login="normal" password="688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336" />
<pets id="1" name="Ron" kind="Can" breed="Moito" owner="1" />
<pets id="2" name="Paul" kind="Gato" breed="Alerxico" owner="2" />
<pets id="3" name="Punky" kind="Gato" breed="Alerxico" owner="2" />
</dataset> </dataset>
\ No newline at end of file
DROP TABLE People IF EXISTS; DROP TABLE People IF EXISTS;
DROP TABLE Users IF EXISTS; DROP TABLE Users IF EXISTS;
DROP TABLE pets IF exists;
\ No newline at end of file