diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Pet.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Pet.java index 97e5bea..7a6569f 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Pet.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Pet.java @@ -16,12 +16,16 @@ @EqualsAndHashCode(callSuper = false) @NoArgsConstructor @AllArgsConstructor -public abstract class Pet extends UriEntity { +public class Pet extends UriEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; + @Column(unique=true) + @NotBlank + private String chip; + @NotBlank private String name; @@ -33,16 +37,13 @@ public abstract class Pet extends UriEntity { private Integer size; - private String chip; - private String sex; private String race; - private boolean dangerous; + private boolean isDangerous; @OneToOne - @NotNull @JsonIdentityReference(alwaysAsId = true) private Adoptions adoptions; diff --git a/src/main/java/cat/udl/eps/softarch/demo/repository/PetRepository.java b/src/main/java/cat/udl/eps/softarch/demo/repository/PetRepository.java index 0e4cbc5..c1ac6f5 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/repository/PetRepository.java +++ b/src/main/java/cat/udl/eps/softarch/demo/repository/PetRepository.java @@ -3,8 +3,14 @@ import cat.udl.eps.softarch.demo.domain.Pet; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; import org.springframework.data.rest.core.annotation.RepositoryRestResource; @RepositoryRestResource public interface PetRepository extends CrudRepository, PagingAndSortingRepository { + + Pet findByName(@Param("name") String name); + + Pet findByChip(@Param("chip") String name); + } diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeletePetStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeletePetStepDefs.java new file mode 100644 index 0000000..d598976 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/DeletePetStepDefs.java @@ -0,0 +1,49 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.Pet; +import cat.udl.eps.softarch.demo.repository.PetRepository; +import io.cucumber.java.en.And; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; + +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + + +public class DeletePetStepDefs { + @Autowired + private StepDefs stepDefs; + + @Autowired + private PetRepository petRepository; + + @When("^I delete the pet with chip \"([^\"]*)\"$") + public void iDeleteAPetWithChip(String chip) throws Exception { + Pet pet = petRepository.findByChip(chip); + + stepDefs.result = stepDefs.mockMvc.perform( + delete("/pets/{id}", (pet != null) ? pet.getId() : "999") + .contentType(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(pet)) + .characterEncoding(StandardCharsets.UTF_8) + .accept(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()); + } + + @And("^The pet with chip \"([^\"]*)\" has been deleted$") + public void thePetWithChipHasBeenDeleted(String chip) { + Pet pet = petRepository.findByChip(chip); + assertThat(pet).isNull(); + } + + @And("^The pet with chip \"([^\"]*)\" has not been deleted$") + public void thePetWithChipHasNotBeenDeleted(String chip) { + Pet pet = petRepository.findByChip(chip); + assertThat(pet).isNotNull(); + } +} diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/GetPetStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/GetPetStepDefs.java new file mode 100644 index 0000000..0a53f06 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/GetPetStepDefs.java @@ -0,0 +1,34 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.Pet; +import cat.udl.eps.softarch.demo.repository.PetRepository; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; + +import java.nio.charset.StandardCharsets; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +public class GetPetStepDefs { + @Autowired + private StepDefs stepDefs; + + @Autowired + private PetRepository petRepository; + + @When("^I retrieve the pet with chip \"([^\"]*)\"$") + public void iRetrievePetWithChip(String chip) throws Exception { + Pet pet = petRepository.findByChip(chip); + + stepDefs.result = stepDefs.mockMvc.perform( + get("/pets/{id}", (pet != null) ? pet.getId() : "999") + .contentType(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(pet)) + .characterEncoding(StandardCharsets.UTF_8) + .accept(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()); + } +} diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RegisterPetStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RegisterPetStepDefs.java new file mode 100644 index 0000000..217d2a7 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RegisterPetStepDefs.java @@ -0,0 +1,124 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.Cat; +import cat.udl.eps.softarch.demo.domain.Pet; +import cat.udl.eps.softarch.demo.domain.Shelter; +import cat.udl.eps.softarch.demo.repository.PetRepository; +import cat.udl.eps.softarch.demo.repository.ShelterRepository; +import io.cucumber.cucumberexpressions.Transformer; +import io.cucumber.java.ParameterType; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.checkerframework.checker.formatter.qual.Format; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +public class RegisterPetStepDefs { + + @Autowired + private StepDefs stepDefs; + + @Autowired + private PetRepository petRepository; + + @Autowired + private ShelterRepository shelterRepository; + public static String newResourceUri; + + public static LocalDate dateValue(String value) { + return LocalDate.parse(value, DateTimeFormatter.ofPattern("dd-MM-yyyy")); + } + + @ParameterType(name= "boolean", value = "true|True|TRUE|false|False|FALSE") + public Boolean booleanValue(String value) { + return Boolean.valueOf(value); + } + + @When("I register a new pet with name {string}, date of birth {string}, isAdopted {boolean}, colour {string}, sex {string}, chip {string}, race {string}, isDangerous {boolean}, at the shelter named {string}") + public void iRegisterANewPetWithData(String name, String dateOfBirth, boolean adoptionStatus, String colour, String sex, String chip, String race, boolean isDangerous, String shelterName) throws Exception { + Pet pet = new Pet(); + pet.setName(name); + pet.setDateOfBirth(dateValue(dateOfBirth)); + pet.setAdopted(adoptionStatus); + pet.setColour(colour); + pet.setSex(sex); + pet.setChip(chip); + pet.setRace(race); + pet.setDangerous(isDangerous); + + Shelter shelter = shelterRepository.findByName(shelterName); + pet.setShelter(shelter); + + + stepDefs.result = stepDefs.mockMvc.perform( + post("/pets") + .contentType(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(pet)) + .characterEncoding(StandardCharsets.UTF_8) + .accept(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()); + + newResourceUri = stepDefs.result.andReturn().getResponse().getHeader("Location"); + + } + + @Then("It has been created a pet with name {string}, date of birth {string}, isAdopted {boolean}, colour {string}, sex {string}, chip {string}, race {string}, isDangerous {boolean}, at the shelter named {string}") + public void itHasBeenCreatedAPetWithData(String name, String dateOfBirth, boolean adoptionStatus, String colour, String sex, String chip, String race, boolean isDangerous, String shelterName) { + Pet createdPet = petRepository.findByChip(chip); + Shelter shelter = shelterRepository.findByName(shelterName); + assertThat(createdPet).isNotNull(); + assertThat(createdPet.getName()).isEqualTo(name); + assertThat(createdPet.getDateOfBirth()).isEqualTo(dateValue(dateOfBirth)); + assertThat(createdPet.isAdopted()).isEqualTo(adoptionStatus); + assertThat(createdPet.getColour()).isEqualTo(colour); + assertThat(createdPet.getSex()).isEqualTo(sex); + assertThat(createdPet.getChip()).isEqualTo(chip); + assertThat(createdPet.getRace()).isEqualTo(race); + assertThat(createdPet.isDangerous()).isEqualTo(isDangerous); + assertThat(createdPet.getShelter()).isEqualTo(shelter); + } + + @Then("It has not been created a pet with chip {string}") + public void itHasNotBeenCreatedAPetWithChip(String chip) { + Pet pet = petRepository.findByChip(chip); + assertThat(pet).isNull(); + } + + @Then("It has not been created a pet with name {string}") + public void itHasNotBeenCreatedAPetWithName(String name) { + Pet pet = petRepository.findByName(name); + assertThat(pet).isNull(); + } + + @Given("There is a registered pet with name {string}, date of birth {string}, isAdopted {boolean}, colour {string}, sex {string}, chip {string}, race {string}, isDangerous {boolean}, at the shelter named {string}") + public void thereIsARegisteredPetWithData(String name, String dateOfBirth, boolean adoptionStatus, String colour, String sex, String chip, String race, boolean isDangerous, String shelterName) { + Pet pet = new Pet(); + pet.setName(name); + pet.setDateOfBirth(dateValue(dateOfBirth)); + pet.setAdopted(adoptionStatus); + pet.setColour(colour); + pet.setSex(sex); + pet.setChip(chip); + pet.setRace(race); + pet.setDangerous(isDangerous); + + Shelter shelter = shelterRepository.findByName(shelterName); + pet.setShelter(shelter); + + petRepository.save(pet); + + Pet petResult = petRepository.findByName(name); + assertThat(petResult).isNotNull(); + } +} + diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/UpdatePetStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/UpdatePetStepDefs.java new file mode 100644 index 0000000..28f93b1 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/UpdatePetStepDefs.java @@ -0,0 +1,65 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.Pet; +import cat.udl.eps.softarch.demo.repository.PetRepository; +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +public class UpdatePetStepDefs { + @Autowired + private StepDefs stepDefs; + + @Autowired + private PetRepository petRepository; + + @When("^I update the pet with chip \"([^\"]*)\" and new attributes:$") + public void iUpdatePetWithChip(String chip, DataTable table) throws Exception { + List> attributesList = table.asMaps(String.class, String.class); + + // Assuming only one row of attributes is provided, so taking the first map from the list + Map attributes = attributesList.get(0); + + // Fetch attributes from the map + String name = attributes.get("name"); + String dateOfBirth = attributes.get("dateOfBirth"); + String isAdopted = attributes.get("isAdopted"); + String colour = attributes.get("colour"); + String size = attributes.get("size"); + String sex = attributes.get("sex"); + String race = attributes.get("race"); + String isDangerous = attributes.get("isDangerous"); + + Pet pet = petRepository.findByChip(chip); + if (pet != null) { + if (name != null) pet.setName(name); + if (dateOfBirth != null) pet.setDateOfBirth(LocalDate.parse(dateOfBirth, DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + if (isAdopted != null) pet.setAdopted(Boolean.parseBoolean(isAdopted)); + if (colour != null) pet.setColour(colour); + if (size != null) pet.setColour(size); + if (sex != null) pet.setSex(sex); + if (race != null) pet.setRace(race); + if (isDangerous != null) pet.setDangerous(Boolean.parseBoolean(isDangerous)); + } + + stepDefs.result = stepDefs.mockMvc.perform( + patch("/pets/{id}", (pet != null) ? pet.getId() : "999") + .contentType(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(pet)) + .characterEncoding(StandardCharsets.UTF_8) + .accept(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()); + + } +} diff --git a/src/test/resources/features/DeletePet.feature b/src/test/resources/features/DeletePet.feature new file mode 100644 index 0000000..9a71d1f --- /dev/null +++ b/src/test/resources/features/DeletePet.feature @@ -0,0 +1,30 @@ +Feature: Delete Pet + In order to maintain pet data + As a user with appropriate permissions + I want to be able to delete a pet + + Background: + Given There is a registered user with username "username" and password "password" and email "user@email.com" + And There is a registered shelter with name "shelter1", email "shelter1@gmail.com", mobile "666 55 44 33" + And There is a registered pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + + Scenario: Delete existing pet + Given I can login with username "username" and password "password" + # And I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + When I delete the pet with chip "1234" + Then The response code is 200 + And The pet with chip "1234" has been deleted + + Scenario: Delete pet when I am not logged in + Given I'm not logged in + When I delete the pet with chip "1234" + Then The response code is 401 + And The pet with chip "1234" has not been deleted + + Scenario: Delete non-existent pet + Given I can login with username "username" and password "password" + # And I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + When I delete the pet with chip "9999" + Then The response code is 404 + + diff --git a/src/test/resources/features/GetPet.feature b/src/test/resources/features/GetPet.feature new file mode 100644 index 0000000..3a6104a --- /dev/null +++ b/src/test/resources/features/GetPet.feature @@ -0,0 +1,24 @@ +Feature: Get Pet + In order to retrieve pet information + As a user with appropriate permissions + I want to be able to get pet details + + Background: + Given There is a registered user with username "username" and password "password" and email "user@email.com" + And There is a registered shelter with name "shelter1", email "shelter1@gmail.com", mobile "666 55 44 33" + + Scenario: Get existing pet details + Given I can login with username "username" and password "password" + And There is a registered pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + When I retrieve the pet with chip "1234" + Then The response code is 200 + + Scenario: Get non-existent pet details + Given I can login with username "username" and password "password" + When I retrieve the pet with chip "1234" + Then The response code is 404 + + Scenario: Get pet details when I am not logged in + Given I'm not logged in + When I retrieve the pet with chip "1234" + Then The response code is 404 \ No newline at end of file diff --git a/src/test/resources/features/RegisterPet.feature b/src/test/resources/features/RegisterPet.feature new file mode 100644 index 0000000..98bf1e8 --- /dev/null +++ b/src/test/resources/features/RegisterPet.feature @@ -0,0 +1,59 @@ +Feature: Register pet + In order to use the app + As a user + I want to register a pet + + Background: + Given There is a registered user with username "username" and password "password" and email "user@email.com" + And There is a registered shelter with name "shelter1", email "shelter1@gmail.com", mobile "666 55 44 33" + + Scenario: Register existing pet + Given I can login with username "username" and password "password" + # And I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + Given There is a registered pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + When I register a new pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + Then The response code is 409 + + Scenario: Register pet with no permission + Given I can login with username "username" and password "password" + # And I am a user with role "User" Temporarily commented because we need to do first the Role tests + When I register a new pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + Then The response code is 201 + # Then The response code is 403 Temporarily commented because we need to do first the Role tests + # And It has not been created a pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" Temporarily commented because we need to do first the Role tests + + Scenario: Register pet with empty chip + Given I can login with username "username" and password "password" + # Given I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + When I register a new pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "", race "european", isDangerous False, at the shelter named "shelter1" + Then The response code is 400 + And The error message is "must not be blank" + And It has not been created a pet with chip "" + + Scenario: Register pet with empty name + Given I can login with username "username" and password "password" + # Given I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + When I register a new pet with name "", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + Then The response code is 400 + And The error message is "must not be blank" + And It has not been created a pet with name "" + + Scenario: Register pet with existing chip + Given I can login with username "username" and password "password" +# And I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + Given There is a registered pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + When I register a new pet with name "super_cat2", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + Then The response code is 409 + And It has not been created a pet with name "super_cat2" + + Scenario: Register pet when I am not logged in + Given I'm not logged in + When I register a new pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + Then The response code is 401 + And It has not been created a pet with chip "1234" + + Scenario: Register pet with valid attributes + Given I can login with username "username" and password "password" + When I register a new pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + Then The response code is 201 + And It has been created a pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" diff --git a/src/test/resources/features/UpdatePet.feature b/src/test/resources/features/UpdatePet.feature new file mode 100644 index 0000000..e29936e --- /dev/null +++ b/src/test/resources/features/UpdatePet.feature @@ -0,0 +1,33 @@ +Feature: Update Pet + In order to maintain pet information + As a user with appropriate permissions + I want to be able to update a pet + + Background: + Given There is a registered user with username "username" and password "password" and email "user@email.com" + And There is a registered shelter with name "shelter1", email "shelter1@gmail.com", mobile "666 55 44 33" + + Scenario: Update existing pet + Given I can login with username "username" and password "password" + # And I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + And There is a registered pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + When I update the pet with chip "1234" and new attributes: + | name | colour | dateOfBirth | + | mega_cat | white | 02-02-2024 | + Then The response code is 200 + + Scenario: Update non-existent pet + Given I can login with username "username" and password "password" + # And I am a user with role "petOwner" Temporarily commented because we need to do first the Role tests + When I update the pet with chip "9999" and new attributes: + | name | colour | dateOfBirth | + | mega_cat | white | 02-02-2024 | + Then The response code is 404 + + Scenario: Update pet when I am not logged in + Given I'm not logged in + And There is a registered pet with name "super_cat", date of birth "01-01-2024", isAdopted True, colour "black", sex "male", chip "1234", race "european", isDangerous False, at the shelter named "shelter1" + When I update the pet with chip "1234" and new attributes: + | name | colour | dateOfBirth | + | mega_cat | white | 02-02-2024 | + Then The response code is 401 \ No newline at end of file