From 6c13dd99ff439a2c4556a60cbed9527f2463891c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Wed, 16 Oct 2024 18:01:17 +0200 Subject: [PATCH 01/29] Created feature for delete --- .../features/DeleteApartment.feature | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/test/resources/features/DeleteApartment.feature diff --git a/src/test/resources/features/DeleteApartment.feature b/src/test/resources/features/DeleteApartment.feature new file mode 100644 index 0000000..6b0110f --- /dev/null +++ b/src/test/resources/features/DeleteApartment.feature @@ -0,0 +1,47 @@ +Feature: Delete Advertisement + In order to use the app + Only admins and owners + can delete advertisement for an existing apartment + + Scenario: Delete an existing apartment advertisement with existing status as admin + Given There is an existing apartment with id "1" named "Cozy Apartment" and I login as admin with password "password" + And There is an existing advertisement status with id "1" and status "Available" + When I delete the apartment advertisement with id "1" + Then The response code is 200 + + Scenario: Delete an existing apartment advertisement with existing status as owner + Given There is an existing apartment with id "1" named "Cozy Apartment" and I login as owner with password "password" + And There is an existing advertisement status with id "1" and status "Available" + When I delete the apartment advertisement with id "1" + Then The response code is 200 + + Scenario: Delete an existing apartment advertisement with existing status as user + Given There is an existing apartment with id "1" named "Cozy Apartment" and I login as student with password "password" + And There is an existing advertisement status with id "1" and status "Available" + When I delete the apartment advertisement with id "1" + Then The response code is 401 + + Scenario: Delete a non-existing apartment as admin + Given I login as admin with password "password" + When I attempt to delete the apartment advertisement with id "9999" + Then The response code is 404 + + Scenario: Delete a non-existing apartment as owner + Given I login as admin with password "password" + When I attempt to delete the apartment advertisement with id "9999" + Then The response code is 404 + + Scenario: Delete a non-existing apartment as student + Given I login as admin with password "password" + When I attempt to delete the apartment advertisement with id "9999" + Then The response code is 403 + + Scenario: Delete apartment advertisement when not authenticated + Given I'm not logged in + And There is an existing apartment with id "1" named "Cozy Apartment" + When I attempt to delete the apartment advertisement with id "1" + Then The response code is 401 + + + + From be7e581974c5fb0d8e4366e1b4065fcb95eaeafc Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 17 Oct 2024 16:28:30 +0200 Subject: [PATCH 02/29] feat: create visit test --- .../demo/config/DBInitialization.java | 17 +++++- .../udl/eps/softarch/demo/domain/Visit.java | 13 ++--- .../demo/repository/VisitRepository.java | 3 + .../demo/steps/RequestVisitStepDefs.java | 58 +++++++++++++++++++ .../resources/features/RequestVisit.feature | 10 ++++ 5 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java create mode 100644 src/test/resources/features/RequestVisit.feature diff --git a/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java b/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java index f2fd97f..a37903d 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java +++ b/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java @@ -1,5 +1,7 @@ package cat.udl.eps.softarch.demo.config; +import cat.udl.eps.softarch.demo.domain.Advertisement; import cat.udl.eps.softarch.demo.domain.User; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; import cat.udl.eps.softarch.demo.repository.UserRepository; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -13,9 +15,11 @@ public class DBInitialization { @Value("${spring.profiles.active:}") private String activeProfiles; private final UserRepository userRepository; + private final AdvertisementRepository advertisementRepository; - public DBInitialization(UserRepository userRepository) { + public DBInitialization(UserRepository userRepository, AdvertisementRepository advertisementRepository) { this.userRepository = userRepository; + this.advertisementRepository = advertisementRepository; } @PostConstruct @@ -29,6 +33,17 @@ public void initializeDatabase() { user.encodePassword(); userRepository.save(user); } + + // Advertisement + if (!advertisementRepository.existsById(1L)) { + Advertisement advertisement = new Advertisement(); + advertisement.setId(1L); + advertisement.setTitle("Demo"); + advertisement.setDescription("Demo"); + advertisement.setPrice(1.0); + advertisementRepository.save(advertisement); + } + if (Arrays.asList(activeProfiles.split(",")).contains("test")) { // Testing instances if (!userRepository.existsById("test")) { diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java index 94908c8..53f50e4 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java @@ -1,20 +1,16 @@ package cat.udl.eps.softarch.demo.domain; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; import java.time.ZonedDateTime; - @EqualsAndHashCode(callSuper = true) @Entity @Data -public class Visit extends UriEntity{ +public class Visit extends UriEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -23,4 +19,7 @@ public class Visit extends UriEntity{ @NotNull private ZonedDateTime when; -} + @ManyToOne + @JoinColumn(name = "advertisement_id") + private Advertisement advertisement; +} \ No newline at end of file diff --git a/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java b/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java index 48b93e0..63496e4 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java +++ b/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java @@ -1,6 +1,8 @@ package cat.udl.eps.softarch.demo.repository; +import cat.udl.eps.softarch.demo.domain.Advertisement; +import cat.udl.eps.softarch.demo.domain.Apartment; import cat.udl.eps.softarch.demo.domain.Visit; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; @@ -14,4 +16,5 @@ public interface VisitRepository extends CrudRepository, PagingAndS Optional findById(@Param("id") Long id); List findByWhen(@Param("when") ZonedDateTime when); + List findByAdvertisement(@Param("advertisement") Advertisement advertisement); } diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java new file mode 100644 index 0000000..2541c23 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java @@ -0,0 +1,58 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.Advertisement; +import cat.udl.eps.softarch.demo.domain.Visit; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; +import cat.udl.eps.softarch.demo.repository.UserRepository; +import cat.udl.eps.softarch.demo.repository.VisitRepository; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.junit.Assert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class RequestVisitStepDefs { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private VisitRepository visitRepository; + + @Autowired + private AdvertisementRepository advertisementRepository; + + private MvcResult result; + + @Given("There is an advertisement with id {int}") + public void thereIsAnAdvertisementWithId(long advertisementId) { + Assert.assertFalse("Advertisement \"" + + advertisementId + "\"shouldn't exist", + advertisementRepository.existsById(advertisementId)); + } + + @When("I request a visit to the advertisement with id {int}") + public void iRequestAVisitToTheAdvertisementWithId(long advertisementId) throws Exception { + Visit visit = new Visit(); + Advertisement advertisement = new Advertisement(); + advertisement.setId(advertisementId); + visit.setAdvertisement(advertisement); + + result = mockMvc.perform(post("/visits") + .contentType("application/json") + .content("{\"advertisement\":{\"id\":" + advertisementId + "}}")) + .andExpect(status().isCreated()) + .andReturn(); + } + + @Then("The visit is successfully requested") + public void theVisitIsSuccessfullyRequested() { + assertNotNull(result); + } +} \ No newline at end of file diff --git a/src/test/resources/features/RequestVisit.feature b/src/test/resources/features/RequestVisit.feature new file mode 100644 index 0000000..9e2853e --- /dev/null +++ b/src/test/resources/features/RequestVisit.feature @@ -0,0 +1,10 @@ +# Created by abdee at 17/10/24 +Feature: Request Visit + As a user + I want to request a visit to an advertisement + So that I can see the advertisement in person + + Scenario: Successful visit request + Given There is an advertisement with id 1 + When I request a visit to the advertisement with id 1 + Then The visit is successfully requested \ No newline at end of file From 55b1b2225c7d4c7e1aae654c61cfc4c66c2a72b6 Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 17 Oct 2024 16:33:11 +0200 Subject: [PATCH 03/29] fix: change advertisement price --- .../cat/udl/eps/softarch/demo/config/DBInitialization.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java b/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java index a2a0f5e..c27e21d 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java +++ b/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java @@ -8,6 +8,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import jakarta.annotation.PostConstruct; + +import java.math.BigDecimal; import java.util.Arrays; import cat.udl.eps.softarch.demo.domain.Advertisement; import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; @@ -57,7 +59,7 @@ public void initializeDatabase() { advertisement.setId(1L); advertisement.setTitle("Demo"); advertisement.setDescription("Demo"); - advertisement.setPrice(1.0); + advertisement.setPrice(BigDecimal.ONE); advertisementRepository.save(advertisement); } if (Arrays.asList(activeProfiles.split(",")).contains("test")) { From a338e1016637c14767d69b1c40f35e0797c45b2f Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Tue, 29 Oct 2024 15:28:19 +0100 Subject: [PATCH 04/29] fix: update visit test --- .../demo/steps/RequestVisitStepDefs.java | 32 +++++++++++++------ .../resources/features/RequestVisit.feature | 4 +-- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java index 2541c23..07ad68a 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java @@ -13,6 +13,9 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import java.math.BigDecimal; +import java.time.ZonedDateTime; + import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -30,23 +33,32 @@ public class RequestVisitStepDefs { private MvcResult result; - @Given("There is an advertisement with id {int}") - public void thereIsAnAdvertisementWithId(long advertisementId) { - Assert.assertFalse("Advertisement \"" - + advertisementId + "\"shouldn't exist", - advertisementRepository.existsById(advertisementId)); + @Given("There is an advertisement with and title {string} and address {string}") + public void thereIsAnAdvertisementWithIdAndTitleAndAddress(long advertisementId, String title, String address) { + Advertisement advertisement = new Advertisement(); + advertisement.setId(advertisementId); + advertisement.setTitle(title); + advertisement.setAddress(address); + advertisement.setDescription("A cozy loft in the center of Barcelona"); + advertisement.setPrice(new BigDecimal("1000.00")); + advertisement.setZipCode("08001"); + advertisement.setCountry("Spain"); + advertisement.setCreationDate(ZonedDateTime.now()); + + advertisementRepository.save(advertisement); } - @When("I request a visit to the advertisement with id {int}") - public void iRequestAVisitToTheAdvertisementWithId(long advertisementId) throws Exception { + @When("I request a visit to the advertisement with title {string}") + public void iRequestAVisitToTheAdvertisementWithTitle(String title) throws Exception { + Advertisement advertisement = advertisementRepository.findByTitle(title).get(0); + assertNotNull(advertisement); + Visit visit = new Visit(); - Advertisement advertisement = new Advertisement(); - advertisement.setId(advertisementId); visit.setAdvertisement(advertisement); result = mockMvc.perform(post("/visits") .contentType("application/json") - .content("{\"advertisement\":{\"id\":" + advertisementId + "}}")) + .content("{\"advertisement\":{\"id\":" + advertisement.getId() + "}}")) .andExpect(status().isCreated()) .andReturn(); } diff --git a/src/test/resources/features/RequestVisit.feature b/src/test/resources/features/RequestVisit.feature index 9e2853e..9d50078 100644 --- a/src/test/resources/features/RequestVisit.feature +++ b/src/test/resources/features/RequestVisit.feature @@ -5,6 +5,6 @@ Feature: Request Visit So that I can see the advertisement in person Scenario: Successful visit request - Given There is an advertisement with id 1 - When I request a visit to the advertisement with id 1 + Given There is an advertisement with and title "Cozy Loft" and address "Carrer de les Flors 10" + When I request a visit to the advertisement with title "Cozy Loft" Then The visit is successfully requested \ No newline at end of file From 0d417b54386a2bf80cc4b94d2e0fef11668ea509 Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Tue, 29 Oct 2024 15:58:06 +0100 Subject: [PATCH 05/29] fix: add new changes in visitSteps --- .../demo/steps/RequestVisitStepDefs.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java index 07ad68a..0fb73e6 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java @@ -1,14 +1,15 @@ package cat.udl.eps.softarch.demo.steps; import cat.udl.eps.softarch.demo.domain.Advertisement; +import cat.udl.eps.softarch.demo.domain.AdvertisementStatus; import cat.udl.eps.softarch.demo.domain.Visit; import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; -import cat.udl.eps.softarch.demo.repository.UserRepository; +import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; import cat.udl.eps.softarch.demo.repository.VisitRepository; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -30,13 +31,15 @@ public class RequestVisitStepDefs { @Autowired private AdvertisementRepository advertisementRepository; + @Autowired + private AdvertisementStatusRepository advertisementStatusRepository; private MvcResult result; + private Advertisement advertisement; - @Given("There is an advertisement with and title {string} and address {string}") - public void thereIsAnAdvertisementWithIdAndTitleAndAddress(long advertisementId, String title, String address) { - Advertisement advertisement = new Advertisement(); - advertisement.setId(advertisementId); + @Given("There is an advertisement with title {string} and address {string}") + public void thereIsAnAdvertisementWithTitleAndAddress(String title, String address) { + advertisement = new Advertisement(); advertisement.setTitle(title); advertisement.setAddress(address); advertisement.setDescription("A cozy loft in the center of Barcelona"); @@ -44,18 +47,19 @@ public void thereIsAnAdvertisementWithIdAndTitleAndAddress(long advertisementId, advertisement.setZipCode("08001"); advertisement.setCountry("Spain"); advertisement.setCreationDate(ZonedDateTime.now()); + AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus("Available").stream().findFirst().orElse(null); + advertisement.setAdStatus(cur_status); - advertisementRepository.save(advertisement); + advertisement = advertisementRepository.save(advertisement); } @When("I request a visit to the advertisement with title {string}") public void iRequestAVisitToTheAdvertisementWithTitle(String title) throws Exception { + // Ensure that the advertisement exists Advertisement advertisement = advertisementRepository.findByTitle(title).get(0); - assertNotNull(advertisement); - - Visit visit = new Visit(); - visit.setAdvertisement(advertisement); + assertNotNull(advertisement, "Advertisement should exist"); + // Request visit using MockMvc to simulate a POST request result = mockMvc.perform(post("/visits") .contentType("application/json") .content("{\"advertisement\":{\"id\":" + advertisement.getId() + "}}")) @@ -65,6 +69,7 @@ public void iRequestAVisitToTheAdvertisementWithTitle(String title) throws Excep @Then("The visit is successfully requested") public void theVisitIsSuccessfullyRequested() { - assertNotNull(result); + assertNotNull(result, "Result should not be null after visit request"); + Assertions.assertEquals(201, result.getResponse().getStatus(), "Expected HTTP status 201 Created"); } -} \ No newline at end of file +} From 0bff06a2ffe5429e42ab48949cbb826384fd9ee7 Mon Sep 17 00:00:00 2001 From: Sergi Vila Monguia <47522460+Troter2@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:38:12 +0100 Subject: [PATCH 06/29] Added apartment creation on test --- .../softarch/demo/domain/Advertisement.java | 5 ++ .../udl/eps/softarch/demo/domain/Room.java | 9 ++-- .../demo/steps/AdvertisementStepDefs.java | 52 +++++++++++++------ .../features/CreateAdvertisement.feature | 14 ++--- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Advertisement.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Advertisement.java index bcf7e9e..cc38f26 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Advertisement.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Advertisement.java @@ -52,6 +52,11 @@ public class Advertisement extends UriEntity { @JsonIdentityReference(alwaysAsId = true) public AdvertisementStatus adStatus; + @NotNull + @ManyToOne + @JsonIdentityReference(alwaysAsId = true) + public Apartment apartment; + public Advertisement() { this.creationDate = ZonedDateTime.now(); diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java index 17654c9..69885f3 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java @@ -3,10 +3,7 @@ import cat.udl.eps.softarch.demo.domain.UriEntity; import com.fasterxml.jackson.annotation.JsonIdentityReference; import com.fasterxml.jackson.annotation.JsonInclude; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; +import jakarta.persistence.*; import lombok.*; @EqualsAndHashCode(callSuper = true) @@ -19,7 +16,9 @@ public class Room extends UriEntity { @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + private int surface; private boolean isOccupied; private boolean hasWindow; @@ -30,4 +29,6 @@ public class Room extends UriEntity { @ManyToOne() private Apartment apart; + public void setApartment(Apartment apartment) { + } } \ No newline at end of file diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java index 339472d..577dfd0 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java @@ -4,10 +4,10 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import cat.udl.eps.softarch.demo.repository.*; +import org.antlr.v4.runtime.misc.LogManager; import org.springframework.http.MediaType; import cat.udl.eps.softarch.demo.domain.*; -import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; -import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; import com.fasterxml.jackson.core.JsonProcessingException; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; @@ -19,14 +19,21 @@ import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; import java.util.List; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; public class AdvertisementStepDefs { + @Autowired + private OwnerRepository ownerRepository; + @Autowired + private RoomRepository roomRepository; @Autowired private AdvertisementRepository advertisementRepository; @Autowired + private ApartmentRepository apartmentRepository; + @Autowired private AdvertisementStatusRepository advertisementStatusRepository; private AdvertisementStatus status; private ResponseEntity response; @@ -36,14 +43,22 @@ public class AdvertisementStepDefs { @Given("There is an existing apartment with id {string} named {string}") public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { // Crea un objeto Owner (propietario) - Owner owner = new Owner(); - owner.setName("John Doe"); - owner.setPhoneNumber("123456789"); - owner.setAddress("456 Another St"); + Optional ownerOptional = ownerRepository.findById("owner"); + Owner owner; + if (ownerOptional.isPresent()) { + owner = ownerOptional.get(); + } else { + owner = new Owner(); + owner.setEmail("owner@sample.app"); + owner.setId("owner"); + owner.setName("Ramon"); + owner.setPhoneNumber("639826878"); + owner.setPassword("password"); + owner.encodePassword(); + ownerRepository.save(owner); + } - // Crea una lista de habitaciones (rooms) Room room1 = new Room(); - room1.setId(1L); room1.setSurface(20); room1.setOccupied(false); room1.setHasWindow(true); @@ -51,17 +66,14 @@ public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { room1.setHasBed(true); Room room2 = new Room(); - room2.setId(2L); room2.setSurface(15); room2.setOccupied(true); room2.setHasWindow(false); room2.setHasDesk(false); room2.setHasBed(true); - List rooms = List.of(room1, room2); - +// Asignar el apartamento a cada habitación Apartment apartment = new Apartment(); - apartment.setId(Long.parseLong(id)); apartment.setName(name); apartment.setFloor(5); apartment.setAddress("123 Example St"); @@ -71,7 +83,15 @@ public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { apartment.setDescription("A beautiful luxury apartment in the city center."); apartment.setRegistrationDate(ZonedDateTime.now()); apartment.setOwner(owner); + + List rooms = List.of(room1, room2); + for (Room room : rooms) { + room.setApartment(apartment); // Establecer la relación bidireccional + } + apartment.setRooms(rooms); + apartmentRepository.save(apartment); // Guardar el apartamento con las habitaciones + } @@ -83,8 +103,8 @@ public void thereIsAnExistingAdvertisementStatusWithIdAndStatus(String status) { } - @When("I create a new advertisement with title {string}, description {string}, price {string}, zipCode {string}, address {string}, country {string}, status {string}") - public void iCreateANewAdvertisement(String title, String description, String price, String zipCode, String adress, String country, String adStatusId) throws Exception { + @When("I create a new advertisement with title {string}, description {string}, price {string}, zipCode {string}, address {string}, country {string}, status {string}, apartment title {string}") + public void iCreateANewAdvertisement(String title, String description, String price, String zipCode, String adress, String country, String status_state, String apartment) throws Exception { Advertisement ad = new Advertisement(); ad.setTitle(title); ad.setDescription(description); @@ -92,8 +112,10 @@ public void iCreateANewAdvertisement(String title, String description, String pr ad.setZipCode(zipCode); ad.setAddress(adress); ad.setCountry(country); - AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus("Available").stream().findFirst().orElse(null); + AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus(status_state).stream().findFirst().orElse(null); + Apartment cur_apartment = apartmentRepository.findByName(apartment).stream().findFirst().orElse(null); ad.setAdStatus(cur_status); + ad.setApartment(cur_apartment); stepDefs.result = stepDefs.mockMvc.perform( diff --git a/src/test/resources/features/CreateAdvertisement.feature b/src/test/resources/features/CreateAdvertisement.feature index 13cd41a..03ce184 100644 --- a/src/test/resources/features/CreateAdvertisement.feature +++ b/src/test/resources/features/CreateAdvertisement.feature @@ -6,14 +6,14 @@ Feature: Create advertisement Scenario: Create new advertisement for existing apartment with existing status Given There is an existing apartment with id "1" named "Cozy Apartment" And There is an existing advertisement status "Available" - When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" Then The response code is 201 And The advertisement has been created with title "Apartment for rent" Scenario: Create advertisement with missing title Given There is an existing apartment with id "1" named "Cozy Apartment" And There is an existing advertisement status "Available" - When I create a new advertisement with title "", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + When I create a new advertisement with title "", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" Then The response code is 400 And The error message is "must not be blank" And It has not been created an advertisement @@ -21,7 +21,7 @@ Feature: Create advertisement Scenario: Create advertisement with missing description Given There is an existing apartment with id "1" named "Cozy Apartment" And There is an existing advertisement status "Available" - When I create a new advertisement with title "Apartment for rent", description "", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + When I create a new advertisement with title "Apartment for rent", description "", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" Then The response code is 400 And The error message is "must not be blank" And It has not been created an advertisement @@ -29,7 +29,7 @@ Feature: Create advertisement Scenario: Create advertisement with invalid price Given There is an existing apartment with id "1" named "Cozy Apartment" And There is an existing advertisement status "Available" - When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "-100", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "-100", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" Then The response code is 400 And The error message is "must be greater than or equal to 0.01" And It has not been created an advertisement @@ -37,7 +37,7 @@ Feature: Create advertisement Scenario: Create advertisement with missing zip code Given There is an existing apartment with id "1" named "Cozy Apartment" And There is an existing advertisement status "Available" - When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "", address "456 Elm St", country "Spain", status "Available" + When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" Then The response code is 400 And The error message is "must not be blank" And It has not been created an advertisement @@ -45,14 +45,14 @@ Feature: Create advertisement Scenario: Create advertisement with missing country Given There is an existing apartment with id "1" named "Cozy Apartment" And There is an existing advertisement status "Available" - When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "", status "Available" + When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "", status "Available", apartment title "Cozy Apartment" Then The response code is 400 And The error message is "must not be blank" And It has not been created an advertisement Scenario: Create advertisement with missing ad status Given There is an existing apartment with id "1" named "Cozy Apartment" - When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "" + When I create a new advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "", apartment title "Cozy Apartment" Then The response code is 400 And The error message is "must not be null" And It has not been created an advertisement From f00d09a931e21050334b3ce2e3e7dde741fc3042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Wed, 30 Oct 2024 17:46:07 +0100 Subject: [PATCH 07/29] Error de test --- .../demo/steps/DeleteApartStepsDefs.java | 102 ++++++++++++++++++ .../features/DeleteApartment.feature | 32 ++---- 2 files changed, 108 insertions(+), 26 deletions(-) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java new file mode 100644 index 0000000..1e47e7e --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java @@ -0,0 +1,102 @@ +package cat.udl.eps.softarch.demo.steps; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +import org.springframework.http.MediaType; +import cat.udl.eps.softarch.demo.domain.*; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; +import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; +import com.fasterxml.jackson.core.JsonProcessingException; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; + +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.time.ZonedDateTime; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class AdvertisementStepDefs { + + @Autowired + private AdvertisementRepository advertisementRepository; + @Autowired + private AdvertisementStatusRepository advertisementStatusRepository; + private AdvertisementStatus status; + private ResponseEntity response; + @Autowired + private StepDefs stepDefs; + + @Given("There is an existing apartment with id {string} named {string}") + public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { + // Crea un objeto Owner (propietario) + Owner owner = new Owner(); + owner.setName("John Doe"); + owner.setPhoneNumber("123456789"); + owner.setAddress("456 Another St"); + + // Crea una lista de habitaciones (rooms) + Room room1 = new Room(); + room1.setId(1L); + room1.setSurface(20); + room1.setOccupied(false); + room1.setHasWindow(true); + room1.setHasDesk(true); + room1.setHasBed(true); + + Room room2 = new Room(); + room2.setId(2L); + room2.setSurface(15); + room2.setOccupied(true); + room2.setHasWindow(false); + room2.setHasDesk(false); + room2.setHasBed(true); + + List rooms = List.of(room1, room2); + + Apartment apartment = new Apartment(); + apartment.setId(Long.parseLong(id)); + apartment.setName(name); + apartment.setFloor(5); + apartment.setAddress("123 Example St"); + apartment.setPostalCode("08001"); + apartment.setCity("Barcelona"); + apartment.setCountry("Spain"); + apartment.setDescription("A beautiful luxury apartment in the city center."); + apartment.setRegistrationDate(ZonedDateTime.now()); + apartment.setOwner(owner); + apartment.setRooms(rooms); + + } + + @Given("There is an existing advertisement status {string}") + public void thereIsAnExistingAdvertisementStatusWithIdAndStatus(String status) { + AdvertisementStatus advertisementStatus = new AdvertisementStatus(); + advertisementStatus.setStatus(status); + advertisementStatusRepository.save(advertisementStatus); + + } + + @When("^I delete the advertisement with id/name nosek \"([^\"]*)\"$") + public void iDeleteTheApartmentAdvertisement(String a) throws Exception { + stepDefs.result = stepDefs.mockMvc.perform( + delete("/advertisements/{id}", advertisementId) + .with(AuthenticationStepDefs.authenticate()) + ).andDo(print()); + } + + @And("^The apartment with name \"([^\"]*)\" no longer exists$") + public void theApartmentWithNameNoLongerExists(String name) { + List apartments = apartmentRepository.findByName(name); + assertTrue("Apartment with name \"" + name + "\" should no longer exist", apartments.isEmpty()); + } + + + +} diff --git a/src/test/resources/features/DeleteApartment.feature b/src/test/resources/features/DeleteApartment.feature index 6b0110f..61ab022 100644 --- a/src/test/resources/features/DeleteApartment.feature +++ b/src/test/resources/features/DeleteApartment.feature @@ -1,45 +1,25 @@ Feature: Delete Advertisement In order to use the app - Only admins and owners + owners can delete advertisement for an existing apartment - Scenario: Delete an existing apartment advertisement with existing status as admin - Given There is an existing apartment with id "1" named "Cozy Apartment" and I login as admin with password "password" - And There is an existing advertisement status with id "1" and status "Available" - When I delete the apartment advertisement with id "1" - Then The response code is 200 + Scenario: Delete an existing apartment advertisement with existing status as owner - Given There is an existing apartment with id "1" named "Cozy Apartment" and I login as owner with password "password" - And There is an existing advertisement status with id "1" and status "Available" + Given There is an existing apartment with id "1" named "Cozy Apartment" + And There is an existing advertisement status "Available" When I delete the apartment advertisement with id "1" Then The response code is 200 - Scenario: Delete an existing apartment advertisement with existing status as user - Given There is an existing apartment with id "1" named "Cozy Apartment" and I login as student with password "password" - And There is an existing advertisement status with id "1" and status "Available" - When I delete the apartment advertisement with id "1" - Then The response code is 401 - - Scenario: Delete a non-existing apartment as admin - Given I login as admin with password "password" - When I attempt to delete the apartment advertisement with id "9999" - Then The response code is 404 - Scenario: Delete a non-existing apartment as owner Given I login as admin with password "password" When I attempt to delete the apartment advertisement with id "9999" Then The response code is 404 - Scenario: Delete a non-existing apartment as student - Given I login as admin with password "password" - When I attempt to delete the apartment advertisement with id "9999" - Then The response code is 403 - Scenario: Delete apartment advertisement when not authenticated + Given There is an existing apartment with id "1" named "Cozy Apartment" + And There is an existing advertisement status "Available" Given I'm not logged in - And There is an existing apartment with id "1" named "Cozy Apartment" - When I attempt to delete the apartment advertisement with id "1" Then The response code is 401 From 8f04bf0045a2bd6146097ce99a78bb37a4f8271b Mon Sep 17 00:00:00 2001 From: Sergi Vila Monguia <47522460+Troter2@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:47:56 +0100 Subject: [PATCH 08/29] updated to work with previous commits --- .../demo/steps/AdvertisementStepDefs.java | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java index 577dfd0..5cc0db0 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java @@ -42,7 +42,6 @@ public class AdvertisementStepDefs { @Given("There is an existing apartment with id {string} named {string}") public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { - // Crea un objeto Owner (propietario) Optional ownerOptional = ownerRepository.findById("owner"); Owner owner; if (ownerOptional.isPresent()) { @@ -58,12 +57,27 @@ public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { ownerRepository.save(owner); } + + Apartment apartment = new Apartment(); + apartment.setName(name); + apartment.setFloor(5); + apartment.setAddress("123 Example St"); + apartment.setPostalCode("08001"); + apartment.setCity("Barcelona"); + apartment.setCountry("Spain"); + apartment.setDescription("A beautiful luxury apartment in the city center."); + apartment.setRegistrationDate(ZonedDateTime.now()); + apartment.setOwner(owner); + + Room room1 = new Room(); room1.setSurface(20); room1.setOccupied(false); room1.setHasWindow(true); room1.setHasDesk(true); room1.setHasBed(true); + room1.setOwner(owner); + room1.setApart(apartment); Room room2 = new Room(); room2.setSurface(15); @@ -71,30 +85,19 @@ public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { room2.setHasWindow(false); room2.setHasDesk(false); room2.setHasBed(true); - -// Asignar el apartamento a cada habitación - Apartment apartment = new Apartment(); - apartment.setName(name); - apartment.setFloor(5); - apartment.setAddress("123 Example St"); - apartment.setPostalCode("08001"); - apartment.setCity("Barcelona"); - apartment.setCountry("Spain"); - apartment.setDescription("A beautiful luxury apartment in the city center."); - apartment.setRegistrationDate(ZonedDateTime.now()); - apartment.setOwner(owner); + room2.setOwner(owner); + room2.setApart(apartment); List rooms = List.of(room1, room2); for (Room room : rooms) { - room.setApartment(apartment); // Establecer la relación bidireccional + room.setApartment(apartment); } apartment.setRooms(rooms); - apartmentRepository.save(apartment); // Guardar el apartamento con las habitaciones - - + apartmentRepository.save(apartment); } + @Given("There is an existing advertisement status {string}") public void thereIsAnExistingAdvertisementStatusWithIdAndStatus(String status) { AdvertisementStatus advertisementStatus = new AdvertisementStatus(); From d9769fb3a921aa3b7c94a3e323315fa5bd463cf0 Mon Sep 17 00:00:00 2001 From: Sergi Vila Monguia <47522460+Troter2@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:54:16 +0100 Subject: [PATCH 09/29] removed setter on apartment --- src/main/java/cat/udl/eps/softarch/demo/domain/Room.java | 3 +-- .../cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java index 373680a..3c5a032 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Room.java @@ -34,8 +34,7 @@ public class Room extends UriEntity { @NotNull private Apartment apart; - public void setApartment(Apartment apartment) { - } + @JsonProperty(access = JsonProperty.Access.READ_ONLY) @NotNull @ManyToOne diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java index 5cc0db0..138364e 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/AdvertisementStepDefs.java @@ -90,7 +90,7 @@ public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { List rooms = List.of(room1, room2); for (Room room : rooms) { - room.setApartment(apartment); + room.setApart(apartment); } apartment.setRooms(rooms); From 8e4b85ff162b3bc690e045389bcda4a5f3f31ffc Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Wed, 30 Oct 2024 18:09:50 +0100 Subject: [PATCH 10/29] feat: add new changes visit --- .../demo/config/DBInitialization.java | 10 +---- .../demo/config/WebSecurityConfig.java | 1 + .../udl/eps/softarch/demo/domain/Visit.java | 5 +++ .../demo/repository/VisitRepository.java | 1 - .../demo/steps/RequestVisitStepDefs.java | 42 ++++++++++++++++--- .../resources/features/RequestVisit.feature | 3 +- 6 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java b/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java index 0b2c877..db6b5f3 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java +++ b/src/main/java/cat/udl/eps/softarch/demo/config/DBInitialization.java @@ -53,15 +53,7 @@ public void initializeDatabase() { owner.encodePassword(); ownerRepository.save(owner); } - // Advertisement - if (!advertisementRepository.existsById(1L)) { - Advertisement advertisement = new Advertisement(); - advertisement.setId(1L); - advertisement.setTitle("Demo"); - advertisement.setDescription("Demo"); - advertisement.setPrice(BigDecimal.ONE); - advertisementRepository.save(advertisement); - } + if (!ownerRepository.existsById("owner1")) { Owner owner = new Owner(); owner.setEmail("owner1@sample.app"); diff --git a/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java b/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java index 2a93798..84d70f3 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java +++ b/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java @@ -38,6 +38,7 @@ protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exce .requestMatchers(HttpMethod.POST, "/rooms/*").hasAnyRole("OWNER") .requestMatchers(HttpMethod.POST, "/properties").hasAuthority("ROLE_OWNER") .requestMatchers(HttpMethod.PUT, "/properties/*").hasAuthority("ROLE_OWNER") + .requestMatchers(HttpMethod.POST, "/visits").authenticated() .requestMatchers(HttpMethod.POST, "/*/*").authenticated() .requestMatchers(HttpMethod.PUT, "/*/*").authenticated() .requestMatchers(HttpMethod.PATCH, "/*/*").authenticated() diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java index 53f50e4..0625e2c 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java @@ -9,6 +9,7 @@ @EqualsAndHashCode(callSuper = true) @Entity +@Table(name = "visit") @Data public class Visit extends UriEntity { @@ -22,4 +23,8 @@ public class Visit extends UriEntity { @ManyToOne @JoinColumn(name = "advertisement_id") private Advertisement advertisement; + + public void setVisitDateTime(ZonedDateTime parse) { + this.when = parse; + } } \ No newline at end of file diff --git a/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java b/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java index 63496e4..326f174 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java +++ b/src/main/java/cat/udl/eps/softarch/demo/repository/VisitRepository.java @@ -2,7 +2,6 @@ import cat.udl.eps.softarch.demo.domain.Advertisement; -import cat.udl.eps.softarch.demo.domain.Apartment; import cat.udl.eps.softarch.demo.domain.Visit; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java index 0fb73e6..3122336 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java @@ -6,12 +6,14 @@ import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; import cat.udl.eps.softarch.demo.repository.VisitRepository; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; import org.junit.jupiter.api.Assertions; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.web.servlet.MockMvc; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; import java.math.BigDecimal; @@ -19,12 +21,13 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; public class RequestVisitStepDefs { @Autowired - private MockMvc mockMvc; + private StepDefs stepDefs; @Autowired private VisitRepository visitRepository; @@ -37,6 +40,13 @@ public class RequestVisitStepDefs { private MvcResult result; private Advertisement advertisement; + + public void createAdvertisementStatus(String status) { + AdvertisementStatus advertisementStatus = new AdvertisementStatus(); + advertisementStatus.setStatus(status); + advertisementStatusRepository.save(advertisementStatus); + + } @Given("There is an advertisement with title {string} and address {string}") public void thereIsAnAdvertisementWithTitleAndAddress(String title, String address) { advertisement = new Advertisement(); @@ -47,6 +57,7 @@ public void thereIsAnAdvertisementWithTitleAndAddress(String title, String addre advertisement.setZipCode("08001"); advertisement.setCountry("Spain"); advertisement.setCreationDate(ZonedDateTime.now()); + createAdvertisementStatus("Available"); AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus("Available").stream().findFirst().orElse(null); advertisement.setAdStatus(cur_status); @@ -59,12 +70,31 @@ public void iRequestAVisitToTheAdvertisementWithTitle(String title) throws Excep Advertisement advertisement = advertisementRepository.findByTitle(title).get(0); assertNotNull(advertisement, "Advertisement should exist"); - // Request visit using MockMvc to simulate a POST request - result = mockMvc.perform(post("/visits") - .contentType("application/json") - .content("{\"advertisement\":{\"id\":" + advertisement.getId() + "}}")) + // Set the visit date and time + String visitDateTime = "2024-10-30T10:00:00+01:00[Europe/Madrid]"; + Visit visit = new Visit(); + visit.setVisitDateTime(ZonedDateTime.parse(visitDateTime)); + visit.setAdvertisement(advertisement); + + visit = visitRepository.save(visit); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + + + String jsonContent = objectMapper.writeValueAsString(visit); + + + result = stepDefs.mockMvc.perform(post("/visits") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonContent) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()) .andExpect(status().isCreated()) .andReturn(); + + + } @Then("The visit is successfully requested") diff --git a/src/test/resources/features/RequestVisit.feature b/src/test/resources/features/RequestVisit.feature index 9d50078..39fb163 100644 --- a/src/test/resources/features/RequestVisit.feature +++ b/src/test/resources/features/RequestVisit.feature @@ -5,6 +5,7 @@ Feature: Request Visit So that I can see the advertisement in person Scenario: Successful visit request - Given There is an advertisement with and title "Cozy Loft" and address "Carrer de les Flors 10" + Given There is an advertisement with title "Cozy Loft" and address "Carrer de les Flors 10" + And I login as "demo" with password "password" When I request a visit to the advertisement with title "Cozy Loft" Then The visit is successfully requested \ No newline at end of file From e966f5820d8f03e191e492a12173c8440cbc20cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Wed, 30 Oct 2024 18:48:09 +0100 Subject: [PATCH 11/29] Almost finished test --- .../demo/steps/DeleteAdvStepsDefs.java | 64 +++++++++++ .../demo/steps/DeleteApartStepsDefs.java | 103 ------------------ .../features/DeleteAdvertisment.feature | 33 ++++++ .../features/DeleteApartment.feature | 28 ----- 4 files changed, 97 insertions(+), 131 deletions(-) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java delete mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java create mode 100644 src/test/resources/features/DeleteAdvertisment.feature delete mode 100644 src/test/resources/features/DeleteApartment.feature diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java new file mode 100644 index 0000000..7da5e91 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java @@ -0,0 +1,64 @@ +package cat.udl.eps.softarch.demo.steps; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import io.cucumber.java.en.And; +import org.springframework.http.MediaType; +import cat.udl.eps.softarch.demo.domain.*; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; +import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; + +import java.math.BigDecimal; +import java.time.ZonedDateTime; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DeleteAdvStepsDefs { + + @Autowired + private AdvertisementRepository advertisementRepository; + @Autowired + private AdvertisementStatusRepository advertisementStatusRepository; + private AdvertisementStatus status; + private ResponseEntity response; + @Autowired + private StepDefs stepDefs; + + + + + + @When("I delete the apartment advertisement with title {string}") + public void iDeleteTheApartmentAdvertisement(String advertisementId) throws Exception { + stepDefs.result = stepDefs.mockMvc.perform( + delete("/advertisements/{id}", advertisementId).accept(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate()) + ).andDo(print()); + } + + @And("There is an advertisement with title {string}, description {string}, price {string}, zipCode {string}, address {string}, country {string}, status {string}") + public void iCreateANewAdvertisement(String title, String description, String price, String zipCode, String adress, String country, String status) { + Advertisement ad = new Advertisement(); + ad.setTitle(title); + ad.setDescription(description); + ad.setPrice(new BigDecimal(price)); + ad.setZipCode(zipCode); + ad.setAddress(adress); + ad.setCountry(country); + AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus(status).stream().findFirst().orElse(null); + ad.setAdStatus(cur_status); + advertisementRepository.save(ad); + + + } + + + +} diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java deleted file mode 100644 index 2c49f65..0000000 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteApartStepsDefs.java +++ /dev/null @@ -1,103 +0,0 @@ -package cat.udl.eps.softarch.demo.steps; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import io.cucumber.java.en.And; -import org.springframework.http.MediaType; -import cat.udl.eps.softarch.demo.domain.*; -import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; -import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; -import com.fasterxml.jackson.core.JsonProcessingException; -import io.cucumber.java.en.Given; -import io.cucumber.java.en.Then; -import io.cucumber.java.en.When; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; - -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.time.ZonedDateTime; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class AdvertisementStepDefs { - - @Autowired - private AdvertisementRepository advertisementRepository; - @Autowired - private AdvertisementStatusRepository advertisementStatusRepository; - private AdvertisementStatus status; - private ResponseEntity response; - @Autowired - private StepDefs stepDefs; - - @Given("There is an existing apartment with id {string} named {string}") - public void thereIsAnExistingApartmentWithIdNamed(String id, String name) { - // Crea un objeto Owner (propietario) - Owner owner = new Owner(); - owner.setName("John Doe"); - owner.setPhoneNumber("123456789"); - owner.setAddress("456 Another St"); - - // Crea una lista de habitaciones (rooms) - Room room1 = new Room(); - room1.setId(1L); - room1.setSurface(20); - room1.setOccupied(false); - room1.setHasWindow(true); - room1.setHasDesk(true); - room1.setHasBed(true); - - Room room2 = new Room(); - room2.setId(2L); - room2.setSurface(15); - room2.setOccupied(true); - room2.setHasWindow(false); - room2.setHasDesk(false); - room2.setHasBed(true); - - List rooms = List.of(room1, room2); - - Apartment apartment = new Apartment(); - apartment.setId(Long.parseLong(id)); - apartment.setName(name); - apartment.setFloor(5); - apartment.setAddress("123 Example St"); - apartment.setPostalCode("08001"); - apartment.setCity("Barcelona"); - apartment.setCountry("Spain"); - apartment.setDescription("A beautiful luxury apartment in the city center."); - apartment.setRegistrationDate(ZonedDateTime.now()); - apartment.setOwner(owner); - apartment.setRooms(rooms); - - } - - @Given("There is an existing advertisement status {string}") - public void thereIsAnExistingAdvertisementStatusWithIdAndStatus(String status) { - AdvertisementStatus advertisementStatus = new AdvertisementStatus(); - advertisementStatus.setStatus(status); - advertisementStatusRepository.save(advertisementStatus); - - } - - @When("^I delete the advertisement with id {long}") - public void iDeleteTheApartmentAdvertisement(String advertisementId) throws Exception { - stepDefs.result = stepDefs.mockMvc.perform( - delete("/advertisements/{id}", advertisementId).accept(MediaType.APPLICATION_JSON) - .with(AuthenticationStepDefs.authenticate()) - ).andDo(print()); - } - - @And("^The adveritsment with name {string}") - public void theApartmentWithNameNoLongerExists(String name) { - List advertisements = advertisementRepository.findAdvertisementBy("name"); - assertTrue("Advertisment with name associated \"" + name + "\" should no longer exist", advertisements.isEmpty()); - } - - - -} diff --git a/src/test/resources/features/DeleteAdvertisment.feature b/src/test/resources/features/DeleteAdvertisment.feature new file mode 100644 index 0000000..47c9c5c --- /dev/null +++ b/src/test/resources/features/DeleteAdvertisment.feature @@ -0,0 +1,33 @@ +Feature: Delete Advertisement + In order to use the app + owners + can delete advertisement for an existing apartment + + + + Scenario: Delete an existing apartment advertisement with existing status as owner + Given There is an existing apartment with id "1" named "Cozy Apartment" + And I login as "owner" with password "password" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + When I delete the apartment advertisement with title "test" + Then The response code is 200 + + Scenario: Delete a non-existing apartment as owner + Given There is an existing apartment with id "1" named "Cozy Apartment" + And I login as "owner" with password "password" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + When I delete the apartment advertisement with title "non existing title" + Then The response code is 404 + + Scenario: Delete apartment advertisement when not authenticated + Given There is an existing apartment with id "1" named "Cozy Apartment" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + Given I'm not logged in + Then The response code is 401 + + + + diff --git a/src/test/resources/features/DeleteApartment.feature b/src/test/resources/features/DeleteApartment.feature deleted file mode 100644 index 88a2b3e..0000000 --- a/src/test/resources/features/DeleteApartment.feature +++ /dev/null @@ -1,28 +0,0 @@ -Feature: Delete Advertisement - In order to use the app - owners - can delete advertisement for an existing apartment - - - - Scenario: Delete an existing apartment advertisement with existing status as owner - Given There is an existing apartment with id "1" named "Cozy Apartment" - And There is an existing advertisement status "Available" - And There is an existing advertisement with name "name" - When I delete the apartment advertisement with name "" - Then The response code is 200 - - Scenario: Delete a non-existing apartment as owner - Given I login as admin with password "password" - When I attempt to delete the apartment advertisement with id "9999" - Then The response code is 404 - - Scenario: Delete apartment advertisement when not authenticated - Given There is an existing apartment with id "1" named "Cozy Apartment" - And There is an existing advertisement status "Available" - Given I'm not logged in - Then The response code is 401 - - - - From 8e889bf4268f8af7e347325d4afb6088a1745e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Thu, 31 Oct 2024 15:38:45 +0100 Subject: [PATCH 12/29] Feature well defined --- src/test/resources/features/DeleteAdvertisment.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/features/DeleteAdvertisment.feature b/src/test/resources/features/DeleteAdvertisment.feature index 47c9c5c..c701db2 100644 --- a/src/test/resources/features/DeleteAdvertisment.feature +++ b/src/test/resources/features/DeleteAdvertisment.feature @@ -10,7 +10,7 @@ Feature: Delete Advertisement And I login as "owner" with password "password" And There is an existing advertisement status "Available" And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" - When I delete the apartment advertisement with title "test" + When I delete the apartment advertisement with title "Apartment for rent" Then The response code is 200 Scenario: Delete a non-existing apartment as owner @@ -26,8 +26,8 @@ Feature: Delete Advertisement And There is an existing advertisement status "Available" And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" Given I'm not logged in + When I delete the apartment advertisement with title "Apartment for rent" Then The response code is 401 - From 6c4ace2e2615a87a06ae9cbe3320139016f40a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Thu, 31 Oct 2024 15:39:12 +0100 Subject: [PATCH 13/29] Steps well defined and passed tests --- .../demo/steps/DeleteAdvStepsDefs.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java index 7da5e91..66af43f 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java @@ -31,18 +31,6 @@ public class DeleteAdvStepsDefs { @Autowired private StepDefs stepDefs; - - - - - @When("I delete the apartment advertisement with title {string}") - public void iDeleteTheApartmentAdvertisement(String advertisementId) throws Exception { - stepDefs.result = stepDefs.mockMvc.perform( - delete("/advertisements/{id}", advertisementId).accept(MediaType.APPLICATION_JSON) - .with(AuthenticationStepDefs.authenticate()) - ).andDo(print()); - } - @And("There is an advertisement with title {string}, description {string}, price {string}, zipCode {string}, address {string}, country {string}, status {string}") public void iCreateANewAdvertisement(String title, String description, String price, String zipCode, String adress, String country, String status) { Advertisement ad = new Advertisement(); @@ -55,10 +43,22 @@ public void iCreateANewAdvertisement(String title, String description, String pr AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus(status).stream().findFirst().orElse(null); ad.setAdStatus(cur_status); advertisementRepository.save(ad); - - } - + @When("I delete the apartment advertisement with title {string}") + public void iDeleteTheApartmentAdvertisement(String title) throws Exception { + Advertisement ad = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + if (ad == null) { + stepDefs.result = stepDefs.mockMvc.perform( + delete("/advertisements/{id}", 9999).accept(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate()) + ).andDo(print()); + } else { + stepDefs.result = stepDefs.mockMvc.perform( + delete("/advertisements/{id}", ad.getId()).accept(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate()) + ).andDo(print()); + } + } } From b24a4067b62b861306ea010de11ad10f6996fbec Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 16:00:16 +0100 Subject: [PATCH 14/29] feat: create visit test --- src/test/resources/features/RequestVisit.feature | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/resources/features/RequestVisit.feature b/src/test/resources/features/RequestVisit.feature index 39fb163..c3d25e0 100644 --- a/src/test/resources/features/RequestVisit.feature +++ b/src/test/resources/features/RequestVisit.feature @@ -6,6 +6,7 @@ Feature: Request Visit Scenario: Successful visit request Given There is an advertisement with title "Cozy Loft" and address "Carrer de les Flors 10" - And I login as "demo" with password "password" + And I login as "demo" with password "password" When I request a visit to the advertisement with title "Cozy Loft" - Then The visit is successfully requested \ No newline at end of file + Then The visit is successfully requested + \ No newline at end of file From 253f559a96a3c45da6b008de7b3ddd79b714a5ed Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 16:03:44 +0100 Subject: [PATCH 15/29] feat: create visit entity and add dynamic date --- .../udl/eps/softarch/demo/steps/RequestVisitStepDefs.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java index 3122336..b6a44d6 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java @@ -66,17 +66,16 @@ public void thereIsAnAdvertisementWithTitleAndAddress(String title, String addre @When("I request a visit to the advertisement with title {string}") public void iRequestAVisitToTheAdvertisementWithTitle(String title) throws Exception { - // Ensure that the advertisement exists + Advertisement advertisement = advertisementRepository.findByTitle(title).get(0); assertNotNull(advertisement, "Advertisement should exist"); - // Set the visit date and time - String visitDateTime = "2024-10-30T10:00:00+01:00[Europe/Madrid]"; + + String visitDateTime = ZonedDateTime.now().plusDays(30).toString(); Visit visit = new Visit(); visit.setVisitDateTime(ZonedDateTime.parse(visitDateTime)); visit.setAdvertisement(advertisement); - visit = visitRepository.save(visit); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); From 2747178a2e1e14c514e120443a6309e25d834589 Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 16:04:06 +0100 Subject: [PATCH 16/29] fix: change date name --- .../cat/udl/eps/softarch/demo/domain/Visit.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java index 0625e2c..5369362 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java @@ -1,16 +1,19 @@ package cat.udl.eps.softarch.demo.domain; +import com.fasterxml.jackson.annotation.JsonIdentityReference; import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; -import lombok.Data; -import lombok.EqualsAndHashCode; +import lombok.*; import java.time.ZonedDateTime; + @EqualsAndHashCode(callSuper = true) -@Entity -@Table(name = "visit") +@Entity(name = "visit") @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class Visit extends UriEntity { @Id @@ -18,10 +21,12 @@ public class Visit extends UriEntity { private Long id; @NotNull + @Column(name = "visit_date") private ZonedDateTime when; + @ManyToOne - @JoinColumn(name = "advertisement_id") + @JsonIdentityReference(alwaysAsId = true) private Advertisement advertisement; public void setVisitDateTime(ZonedDateTime parse) { From 1196bed5f4298ff6da58d4b24edbd302ec621617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Mart=C3=ADnez=20de=20Sanjuan?= Date: Thu, 31 Oct 2024 16:04:32 +0100 Subject: [PATCH 17/29] TestDeletePropoerty --- .../demo/config/WebSecurityConfig.java | 1 + .../demo/steps/DeletePropertyStepDefs.java | 33 +++++++++++++++++++ .../resources/features/DeleteProperty.feature | 31 +++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/DeletePropertyStepDefs.java create mode 100644 src/test/resources/features/DeleteProperty.feature diff --git a/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java b/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java index 2a93798..e6a345f 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java +++ b/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java @@ -38,6 +38,7 @@ protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exce .requestMatchers(HttpMethod.POST, "/rooms/*").hasAnyRole("OWNER") .requestMatchers(HttpMethod.POST, "/properties").hasAuthority("ROLE_OWNER") .requestMatchers(HttpMethod.PUT, "/properties/*").hasAuthority("ROLE_OWNER") + .requestMatchers(HttpMethod.DELETE, "/properties/*").hasAuthority("ROLE_OWNER") .requestMatchers(HttpMethod.POST, "/*/*").authenticated() .requestMatchers(HttpMethod.PUT, "/*/*").authenticated() .requestMatchers(HttpMethod.PATCH, "/*/*").authenticated() diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeletePropertyStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeletePropertyStepDefs.java new file mode 100644 index 0000000..c529e7c --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/DeletePropertyStepDefs.java @@ -0,0 +1,33 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.Property; +import cat.udl.eps.softarch.demo.repository.PropertyRepository; +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.junit.Assert.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +public class DeletePropertyStepDefs { + @Autowired + StepDefs stepDefs; + @Autowired + PropertyRepository propertyRepository; + + @When("^I delete a property with a description \"([^\"]*)\"$") + public void modifyProperty(String previousDescription)throws Throwable { + Property property = propertyRepository.findByDescription(previousDescription).get(0); + Long propertyId = property.getId(); + this.stepDefs.result = this.stepDefs.mockMvc.perform(delete("/properties/"+propertyId) + .contentType(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(property)) + .characterEncoding(StandardCharsets.UTF_8) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()); + } +} diff --git a/src/test/resources/features/DeleteProperty.feature b/src/test/resources/features/DeleteProperty.feature new file mode 100644 index 0000000..c16e41f --- /dev/null +++ b/src/test/resources/features/DeleteProperty.feature @@ -0,0 +1,31 @@ +Feature: Delete Property + In order to make changes on a property + As an Owner + I want to delete properties + + Background: + Given There is a registered user with username "user" and password "password" and email "user@user.app" + Given There is a registered owner with username "owner" and password "password" and email "owner@example.com" + Given There is a property already created with description "description" + + Scenario: Delete a property without being logged in + Given I'm not logged in + When I delete a property with a description "description" + Then The response code is 401 + And The error message is "Unauthorized" + And There is 1 Property created with description "description" + + + Scenario: Delete a property as an owner with a valid description: + Given I login as "owner" with password "password" + When I delete a property with a description "description" + Then The response code is 204 + And There is 0 Property created with description "description" + + + Scenario: Delete a property as an user with a valid description: + Given I login as "user" with password "password" + When I delete a property with a description "description" + Then The response code is 403 + And The error message is "Forbidden" + And There is 1 Property created with description "description" \ No newline at end of file From b3387ef45b2def8e5ffd785aaba5223fca30ef44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Thu, 31 Oct 2024 16:17:27 +0100 Subject: [PATCH 18/29] Problem Fixed --- .../eps/softarch/demo/steps/DeleteAdvStepsDefs.java | 11 +++++++++-- .../resources/features/DeleteAdvertisment.feature | 6 +++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java index 66af43f..b8d182e 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteAdvStepsDefs.java @@ -4,6 +4,8 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; + +import cat.udl.eps.softarch.demo.repository.ApartmentRepository; import io.cucumber.java.en.And; import org.springframework.http.MediaType; import cat.udl.eps.softarch.demo.domain.*; @@ -24,6 +26,9 @@ public class DeleteAdvStepsDefs { @Autowired private AdvertisementRepository advertisementRepository; + + @Autowired + private ApartmentRepository apartmentRepository; @Autowired private AdvertisementStatusRepository advertisementStatusRepository; private AdvertisementStatus status; @@ -31,8 +36,8 @@ public class DeleteAdvStepsDefs { @Autowired private StepDefs stepDefs; - @And("There is an advertisement with title {string}, description {string}, price {string}, zipCode {string}, address {string}, country {string}, status {string}") - public void iCreateANewAdvertisement(String title, String description, String price, String zipCode, String adress, String country, String status) { + @And("There is an advertisement with title {string}, description {string}, price {string}, zipCode {string}, address {string}, country {string}, status {string}, apartment title {string}") + public void iCreateANewAdvertisement(String title, String description, String price, String zipCode, String adress, String country, String status, String apartmentTitle) { Advertisement ad = new Advertisement(); ad.setTitle(title); ad.setDescription(description); @@ -40,6 +45,8 @@ public void iCreateANewAdvertisement(String title, String description, String pr ad.setZipCode(zipCode); ad.setAddress(adress); ad.setCountry(country); + Apartment apartment = apartmentRepository.findByName(apartmentTitle).stream().findFirst().orElse(null); + ad.setApartment(apartment); AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus(status).stream().findFirst().orElse(null); ad.setAdStatus(cur_status); advertisementRepository.save(ad); diff --git a/src/test/resources/features/DeleteAdvertisment.feature b/src/test/resources/features/DeleteAdvertisment.feature index c701db2..8e30119 100644 --- a/src/test/resources/features/DeleteAdvertisment.feature +++ b/src/test/resources/features/DeleteAdvertisment.feature @@ -9,7 +9,7 @@ Feature: Delete Advertisement Given There is an existing apartment with id "1" named "Cozy Apartment" And I login as "owner" with password "password" And There is an existing advertisement status "Available" - And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" When I delete the apartment advertisement with title "Apartment for rent" Then The response code is 200 @@ -17,14 +17,14 @@ Feature: Delete Advertisement Given There is an existing apartment with id "1" named "Cozy Apartment" And I login as "owner" with password "password" And There is an existing advertisement status "Available" - And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" When I delete the apartment advertisement with title "non existing title" Then The response code is 404 Scenario: Delete apartment advertisement when not authenticated Given There is an existing apartment with id "1" named "Cozy Apartment" And There is an existing advertisement status "Available" - And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" Given I'm not logged in When I delete the apartment advertisement with title "Apartment for rent" Then The response code is 401 From 71d967da0d1c3439f941bdad45c1aefe6841f4e3 Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 16:27:41 +0100 Subject: [PATCH 19/29] feat: add Invalid Advertisement test visit --- src/test/resources/features/RequestVisit.feature | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/resources/features/RequestVisit.feature b/src/test/resources/features/RequestVisit.feature index c3d25e0..4b954d6 100644 --- a/src/test/resources/features/RequestVisit.feature +++ b/src/test/resources/features/RequestVisit.feature @@ -9,4 +9,9 @@ Feature: Request Visit And I login as "demo" with password "password" When I request a visit to the advertisement with title "Cozy Loft" Then The visit is successfully requested - \ No newline at end of file + + Scenario: Visit request with invalid advertisement + Given There is an advertisement with title "Cozy Loft" and address "Carrer de les Flors 10" + And I login as "demo" with password "password" + When I request a visit to the advertisement with title "Invalid Advertisement" + Then The visit is not successfully requested \ No newline at end of file From b4d963f05a1e3a9fb57de0f20c10f99421213337 Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 16:28:31 +0100 Subject: [PATCH 20/29] feat: adapt "when" step for visit tests --- .../udl/eps/softarch/demo/domain/Visit.java | 2 + .../demo/steps/RequestVisitStepDefs.java | 45 ++++++++++++++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java index 5369362..5070dc0 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java +++ b/src/main/java/cat/udl/eps/softarch/demo/domain/Visit.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonIdentityReference; import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.*; @@ -26,6 +27,7 @@ public class Visit extends UriEntity { @ManyToOne + @NotNull @JsonIdentityReference(alwaysAsId = true) private Advertisement advertisement; diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java index b6a44d6..27042fc 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java @@ -6,6 +6,7 @@ import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; import cat.udl.eps.softarch.demo.repository.VisitRepository; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.cucumber.java.en.Given; @@ -18,6 +19,7 @@ import java.math.BigDecimal; import java.time.ZonedDateTime; +import java.util.Objects; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -67,9 +69,13 @@ public void thereIsAnAdvertisementWithTitleAndAddress(String title, String addre @When("I request a visit to the advertisement with title {string}") public void iRequestAVisitToTheAdvertisementWithTitle(String title) throws Exception { - Advertisement advertisement = advertisementRepository.findByTitle(title).get(0); - assertNotNull(advertisement, "Advertisement should exist"); + Advertisement advertisement; + if(title.equals("Invalid Advertisement")) + advertisement = null; + else { + advertisement = advertisementRepository.findByTitle(title).get(0); + } String visitDateTime = ZonedDateTime.now().plusDays(30).toString(); Visit visit = new Visit(); @@ -83,15 +89,24 @@ public void iRequestAVisitToTheAdvertisementWithTitle(String title) throws Excep String jsonContent = objectMapper.writeValueAsString(visit); - - result = stepDefs.mockMvc.perform(post("/visits") - .contentType(MediaType.APPLICATION_JSON) - .content(jsonContent) - .with(AuthenticationStepDefs.authenticate())) - .andDo(print()) - .andExpect(status().isCreated()) - .andReturn(); - + if(advertisement != null) { + result = stepDefs.mockMvc.perform(post("/visits") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonContent) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()) + .andExpect(status().isCreated()) + .andReturn(); + } else if (advertisement == null) { + + result = stepDefs.mockMvc.perform(post("/visits") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonContent) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()) + .andExpect(status().isBadRequest()) + .andReturn(); + } } @@ -101,4 +116,12 @@ public void theVisitIsSuccessfullyRequested() { assertNotNull(result, "Result should not be null after visit request"); Assertions.assertEquals(201, result.getResponse().getStatus(), "Expected HTTP status 201 Created"); } + + + @Then("The visit is not successfully requested") + public void theVisitIsNotSuccessfullyRequested() { + assertNotNull(result, "Result should not be null after visit request"); + Assertions.assertEquals(400, result.getResponse().getStatus(), "Expected HTTP status 400 Bad Request"); + } + } From 1d55198651e0ef118d44694ebf35ab8b8930e96c Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 17:56:12 +0100 Subject: [PATCH 21/29] feat: add delete visits to WebSecurityConfig --- .../java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java b/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java index 79a74e7..2f9353e 100644 --- a/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java +++ b/src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java @@ -40,6 +40,7 @@ protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exce .requestMatchers(HttpMethod.PUT, "/properties/*").hasAuthority("ROLE_OWNER") .requestMatchers(HttpMethod.DELETE, "/properties/*").hasAuthority("ROLE_OWNER") .requestMatchers(HttpMethod.POST, "/visits").authenticated() + .requestMatchers(HttpMethod.DELETE, "/visits/*").authenticated() .requestMatchers(HttpMethod.POST, "/*/*").authenticated() .requestMatchers(HttpMethod.PUT, "/*/*").authenticated() .requestMatchers(HttpMethod.PATCH, "/*/*").authenticated() From b83d7feac6f7ea2f7a579c1bd75495bd0d4a91bb Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 17:56:34 +0100 Subject: [PATCH 22/29] feat: create delete visit steps --- .../softarch/demo/steps/DeleteVisitSteps.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/DeleteVisitSteps.java diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteVisitSteps.java b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteVisitSteps.java new file mode 100644 index 0000000..162bb1c --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/DeleteVisitSteps.java @@ -0,0 +1,56 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.Advertisement; +import cat.udl.eps.softarch.demo.domain.Visit; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; +import cat.udl.eps.softarch.demo.repository.VisitRepository; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.junit.jupiter.api.Assertions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class DeleteVisitSteps { + + @Autowired + private StepDefs stepDefs; + + @Autowired + private VisitRepository visitRepository; + + @Autowired + private AdvertisementRepository advertisementRepository; + + private MvcResult result; + + + + @When("I delete the visit request to the advertisement with title {string}") + public void iDeleteTheVisitRequestToTheAdvertisementWithTitle(String title) throws Exception { + + Advertisement advertisement = advertisementRepository.findByTitle(title).get(0); + Visit visit = visitRepository.findByAdvertisement(advertisement).get(0); + + result = stepDefs.mockMvc.perform(delete( "/visits/" + visit.getId() ) + .contentType(MediaType.APPLICATION_JSON) + .with(AuthenticationStepDefs.authenticate())) + .andDo(print()) + .andExpect(status().isNoContent()) + .andReturn(); + + + + } + + @Then("The visit is successfully deleted") + public void theVisitIsSuccessfullyDeleted() { + assertNotNull(result, "Result should not be null after visit deletion"); + Assertions.assertEquals(204, result.getResponse().getStatus(), "Expected HTTP status 200 OK"); + } +} From 5b371859b1d80dcc020369c6ad2253f5c55324a9 Mon Sep 17 00:00:00 2001 From: Abdellah Lamrabat Date: Thu, 31 Oct 2024 17:57:05 +0100 Subject: [PATCH 23/29] feat: create delete visit test --- .../softarch/demo/steps/RequestVisitStepDefs.java | 13 +++++++++++++ src/test/resources/features/DeleteVisit.feature | 13 +++++++++++++ src/test/resources/features/RequestVisit.feature | 3 ++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/features/DeleteVisit.feature diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java index 27042fc..6b33c59 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/RequestVisitStepDefs.java @@ -2,9 +2,11 @@ import cat.udl.eps.softarch.demo.domain.Advertisement; import cat.udl.eps.softarch.demo.domain.AdvertisementStatus; +import cat.udl.eps.softarch.demo.domain.Apartment; import cat.udl.eps.softarch.demo.domain.Visit; import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; +import cat.udl.eps.softarch.demo.repository.ApartmentRepository; import cat.udl.eps.softarch.demo.repository.VisitRepository; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -12,16 +14,19 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import org.checkerframework.checker.units.qual.A; import org.junit.jupiter.api.Assertions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; import java.util.Objects; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -34,6 +39,9 @@ public class RequestVisitStepDefs { @Autowired private VisitRepository visitRepository; + @Autowired + private ApartmentRepository apartmentRepository; + @Autowired private AdvertisementRepository advertisementRepository; @Autowired @@ -59,6 +67,10 @@ public void thereIsAnAdvertisementWithTitleAndAddress(String title, String addre advertisement.setZipCode("08001"); advertisement.setCountry("Spain"); advertisement.setCreationDate(ZonedDateTime.now()); + String visitDateTime = ZonedDateTime.now().plusDays(30).toString(); + Apartment apartment = ApartmentUtils.buildApartment("Apartment", "2", "Apartment", "25182", "Lleida", "Spain", "Apartment", visitDateTime); + apartmentRepository.save(apartment); + advertisement.setApartment(apartment); createAdvertisementStatus("Available"); AdvertisementStatus cur_status = advertisementStatusRepository.findByStatus("Available").stream().findFirst().orElse(null); advertisement.setAdStatus(cur_status); @@ -124,4 +136,5 @@ public void theVisitIsNotSuccessfullyRequested() { Assertions.assertEquals(400, result.getResponse().getStatus(), "Expected HTTP status 400 Bad Request"); } + } diff --git a/src/test/resources/features/DeleteVisit.feature b/src/test/resources/features/DeleteVisit.feature new file mode 100644 index 0000000..77c7577 --- /dev/null +++ b/src/test/resources/features/DeleteVisit.feature @@ -0,0 +1,13 @@ +# Created by abdee at 31/10/24 +# Created by abdee at 17/10/24 +Feature: Delete Visit + As a user + I want to delete a visit to an advertisement + So that I can cancel the visit request + +Scenario: Delete visit request + Given There is an advertisement with title "Cozy Loft" and address "Carrer de les Flors 10" + And I login as "demo" with password "password" + And I request a visit to the advertisement with title "Cozy Loft" + When I delete the visit request to the advertisement with title "Cozy Loft" + Then The visit is successfully deleted \ No newline at end of file diff --git a/src/test/resources/features/RequestVisit.feature b/src/test/resources/features/RequestVisit.feature index 4b954d6..31ba485 100644 --- a/src/test/resources/features/RequestVisit.feature +++ b/src/test/resources/features/RequestVisit.feature @@ -14,4 +14,5 @@ Feature: Request Visit Given There is an advertisement with title "Cozy Loft" and address "Carrer de les Flors 10" And I login as "demo" with password "password" When I request a visit to the advertisement with title "Invalid Advertisement" - Then The visit is not successfully requested \ No newline at end of file + Then The visit is not successfully requested + From 551492fd540bc6d6d690ab0aedae14f274bb0abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Fri, 1 Nov 2024 14:24:05 +0100 Subject: [PATCH 24/29] scenarios Defined --- .../features/GetAdvertisment.feature | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/resources/features/GetAdvertisment.feature diff --git a/src/test/resources/features/GetAdvertisment.feature b/src/test/resources/features/GetAdvertisment.feature new file mode 100644 index 0000000..419c05c --- /dev/null +++ b/src/test/resources/features/GetAdvertisment.feature @@ -0,0 +1,28 @@ +Feature: Get Advertisement + In order to use the app + users can retrieve advertisement details for existing apartments + + Scenario: Get an existing apartment advertisement by title + Given There is an existing apartment with id "1" named "Cozy Apartment" + And I login as "owner" with password "password" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" + When I get the apartment advertisement with title "Apartment for rent" + Then The response code is 200 + + Scenario: Get a non-existing apartment advertisement by title + Given There is an existing apartment with id "1" named "Cozy Apartment" + And I login as "owner" with password "password" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" + When I get the apartment advertisement with title "non existing title" + Then The response code is 404 + + + Scenario: Get apartment advertisement when not authenticated + Given There is an existing apartment with id "1" named "Cozy Apartment" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "A beautiful apartment", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" + Given I'm not logged in + When I get the apartment advertisement with title "Apartment for rent" + Then The response code is 200 From e723f25098061a6de2756644e772bbb38b289f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Fri, 1 Nov 2024 14:24:21 +0100 Subject: [PATCH 25/29] Steps defined and passed tests --- .../demo/steps/GetAdvertismentStepDefs.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/GetAdvertismentStepDefs.java diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/GetAdvertismentStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/GetAdvertismentStepDefs.java new file mode 100644 index 0000000..959d9e4 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/GetAdvertismentStepDefs.java @@ -0,0 +1,56 @@ +package cat.udl.eps.softarch.demo.steps; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; + +import cat.udl.eps.softarch.demo.repository.ApartmentRepository; +import io.cucumber.java.en.And; +import org.springframework.http.MediaType; +import cat.udl.eps.softarch.demo.domain.*; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; +import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; + +import java.math.BigDecimal; +import java.time.ZonedDateTime; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class GetAdvertismentStepDefs { + + @Autowired + private AdvertisementRepository advertisementRepository; + + @Autowired + private ApartmentRepository apartmentRepository; + @Autowired + private AdvertisementStatusRepository advertisementStatusRepository; + private AdvertisementStatus status; + private ResponseEntity response; + @Autowired + private StepDefs stepDefs; + + @When("I get the apartment advertisement with title {string}") + public void iGetTheApartmentAdvertisement(String title) throws Exception { + Advertisement ad = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + + if (ad == null) { + stepDefs.result = stepDefs.mockMvc.perform( + get("/advertisements/{id}", 9999) + .accept(MediaType.APPLICATION_JSON) + ).andDo(print()); + } else { + stepDefs.result = stepDefs.mockMvc.perform( + get("/advertisements/{id}", ad.getId()) + .accept(MediaType.APPLICATION_JSON) + ).andDo(print()); + } + } + +} From cf3f22564faff8ae3a392f34b52038d2044ab882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Fri, 1 Nov 2024 16:43:19 +0100 Subject: [PATCH 26/29] Patch Scenarios done --- .../features/PatchAdvertisment.feature | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/resources/features/PatchAdvertisment.feature diff --git a/src/test/resources/features/PatchAdvertisment.feature b/src/test/resources/features/PatchAdvertisment.feature new file mode 100644 index 0000000..da27387 --- /dev/null +++ b/src/test/resources/features/PatchAdvertisment.feature @@ -0,0 +1,28 @@ +Feature: Patch Advertisement + In order to update advertisement details + as an authenticated owner + I want to patch an existing advertisement's data + + Scenario: Patch an existing apartment advertisement + Given There is an existing apartment with id "1" named "Cozy Apartment" + And I login as "owner" with password "password" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "Old description", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" + When I patch the apartment advertisement with title "Apartment for rent" and new description "Updated description" + Then The response code is 204 + + + Scenario: Patch a non-existing apartment advertisement + Given There is an existing apartment with id "1" named "Cozy Apartment" + Given I login as "owner" with password "password" + And There is an existing advertisement status "Available" + When I patch the apartment advertisement with title "Non-existing title" and new description "Should not update" + Then The response code is 404 + + Scenario: Patch an advertisement when not authenticated + Given There is an existing apartment with id "1" named "Cozy Apartment" + And There is an existing advertisement status "Available" + And There is an advertisement with title "Apartment for rent", description "Old description", price "1200", zipCode "12345", address "456 Elm St", country "Spain", status "Available", apartment title "Cozy Apartment" + Given I'm not logged in + When I patch the apartment advertisement with title "Apartment for rent" and new description "Updated description" + Then The response code is 401 From 0cee7e81e097632d4de4ac7af65e2b651946ff8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Creus=20Nu=C3=B1ez?= Date: Fri, 1 Nov 2024 16:43:36 +0100 Subject: [PATCH 27/29] StepDefs done and running tests --- .../softarch/demo/steps/PatchAdvStepDefs.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/PatchAdvStepDefs.java diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/PatchAdvStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/PatchAdvStepDefs.java new file mode 100644 index 0000000..d1e17fb --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/PatchAdvStepDefs.java @@ -0,0 +1,50 @@ +package cat.udl.eps.softarch.demo.steps; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +import cat.udl.eps.softarch.demo.domain.Advertisement; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; +import io.cucumber.core.internal.com.fasterxml.jackson.databind.ObjectMapper; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; + + + +import java.util.HashMap; +import java.util.Map; + +public class PatchAdvStepDefs { + + @Autowired + private AdvertisementRepository advertisementRepository; + + @Autowired + private StepDefs stepDefs; + + @When("I patch the apartment advertisement with title {string} and new description {string}") + public void iPatchTheApartmentAdvertisement(String title, String newDescription) throws Exception { + Advertisement ad = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + + Map updatedFields = new HashMap<>(); + updatedFields.put("description", newDescription); + String jsonContent = new ObjectMapper().writeValueAsString(updatedFields); + + if (ad == null) { + stepDefs.result = stepDefs.mockMvc.perform( + patch("/advertisements/{id}", 9999) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonContent) + .with(AuthenticationStepDefs.authenticate()) + ).andDo(print()); + } else { + stepDefs.result = stepDefs.mockMvc.perform( + patch("/advertisements/{id}", ad.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonContent) + .with(AuthenticationStepDefs.authenticate()) + ).andDo(print()); + } + } +} From 5f07efec840ad11150e820012ee4f189b6263bd9 Mon Sep 17 00:00:00 2001 From: Josep Prades Vidal Date: Sun, 3 Nov 2024 16:46:36 +0100 Subject: [PATCH 28/29] Create UpdateAdvertisementStepDefs.java --- .../steps/UpdateAdvertisementStepDefs.java | 200 ++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 src/test/java/cat/udl/eps/softarch/demo/steps/UpdateAdvertisementStepDefs.java diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/UpdateAdvertisementStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/UpdateAdvertisementStepDefs.java new file mode 100644 index 0000000..78df593 --- /dev/null +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/UpdateAdvertisementStepDefs.java @@ -0,0 +1,200 @@ +package cat.udl.eps.softarch.demo.steps; + +import cat.udl.eps.softarch.demo.domain.*; +import cat.udl.eps.softarch.demo.repository.AdvertisementRepository; +import cat.udl.eps.softarch.demo.repository.AdvertisementStatusRepository; +import cat.udl.eps.softarch.demo.repository.ApartmentRepository; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; + +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +public class UpdateAdvertisementStepDefs { + + @Autowired + private AdvertisementStatusRepository advertisementStatusRepository; + + @Autowired + private AdvertisementRepository advertisementRepository; + + @Autowired + private ApartmentRepository apartmentRepository; + + @Autowired + private StepDefs stepDefs; + + + @When("I update an advertisement with title {string} to have name {string} and address {string}") + public void iUpdateAdvertisement(String title, String newTitle, String newAddress) throws Exception { + List ads = advertisementRepository.findByTitle(title); + + if (ads.isEmpty()) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + Advertisement advertisement = ads.get(0); + advertisement.setTitle(newTitle); + advertisement.setAddress(newAddress); + advertisementRepository.save(advertisement); + + stepDefs.result = stepDefs.mockMvc.perform(put("/advertisements/" + advertisement.getId()) + .with(AuthenticationStepDefs.authenticate()) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(advertisement)) + .characterEncoding(StandardCharsets.UTF_8)) + .andDo(print()); + } + + + + @Then("The advertisement with title {string} should have name {string} and address {string}") + public void theAdvertisementWithTitleShouldHaveNameAndAddress(String title, String expectedName, String expectedAddress) throws Exception { + Advertisement updatedAdvertisement = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + + if (updatedAdvertisement == null) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + assertEquals(expectedName, updatedAdvertisement.getTitle()); + assertEquals(expectedAddress, updatedAdvertisement.getAddress()); + } + + @When("I update the advertisement with title {string} to have price {string}") + public void iUpdateAdvertisementPrice(String title, String newPrice) throws Exception { + List ads = advertisementRepository.findByTitle(title); + + if (ads.isEmpty()) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + Advertisement advertisement = ads.get(0); + advertisement.setPrice(new BigDecimal(newPrice)); + + stepDefs.result = stepDefs.mockMvc.perform(put("/advertisements/" + advertisement.getId()) + .with(AuthenticationStepDefs.authenticate()) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(advertisement)) + .characterEncoding(StandardCharsets.UTF_8)) + .andDo(print()); + } + + @Then("The advertisement with title {string} should have price {string}") + public void theAdvertisementWithTitleShouldHavePrice(String title, String expectedPrice) throws Exception { + Advertisement updatedAdvertisement = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + + if (updatedAdvertisement == null) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + assertEquals(new BigDecimal(expectedPrice), updatedAdvertisement.getPrice()); + } + + @When("I update the advertisement with title {string} to have zipCode {string}") + public void iUpdateAdvertisementZipCode(String title, String newZipCode) throws Exception { + List ads = advertisementRepository.findByTitle(title); + + if (ads.isEmpty()) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + Advertisement advertisement = ads.get(0); + advertisement.setZipCode(newZipCode); + advertisementRepository.save(advertisement); + + stepDefs.result = stepDefs.mockMvc.perform(put("/advertisements/" + advertisement.getId()) + .with(AuthenticationStepDefs.authenticate()) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(advertisement)) + .characterEncoding(StandardCharsets.UTF_8)) + .andDo(print()); + } + + @Then("The advertisement with title {string} should have zipCode {string}") + public void theAdvertisementWithTitleShouldHaveZipCode(String title, String expectedZipCode) throws Exception { + Advertisement updatedAdvertisement = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + + if (updatedAdvertisement == null) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + assertEquals(expectedZipCode, updatedAdvertisement.getZipCode()); + } + + @When("I update the advertisement with title {string} to have country {string}") + public void iUpdateAdvertisementCountry(String title, String newCountry) throws Exception { + List ads = advertisementRepository.findByTitle(title); + + if (ads.isEmpty()) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + Advertisement advertisement = ads.get(0); + advertisement.setCountry(newCountry); + advertisementRepository.save(advertisement); + + stepDefs.result = stepDefs.mockMvc.perform(put("/advertisements/" + advertisement.getId()) + .with(AuthenticationStepDefs.authenticate()) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(advertisement)) + .characterEncoding(StandardCharsets.UTF_8)) + .andDo(print()); + } + + @Then("The advertisement with title {string} should have country {string}") + public void theAdvertisementWithTitleShouldHaveCountry(String title, String expectedCountry) throws Exception { + Advertisement updatedAdvertisement = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + + if (updatedAdvertisement == null) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + assertEquals(expectedCountry, updatedAdvertisement.getCountry()); + } + + @When("I update the advertisement with title {string} to have description {string}") + public void iUpdateAdvertisementDescription(String title, String newDescription) throws Exception { + List ads = advertisementRepository.findByTitle(title); + + if (ads.isEmpty()) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + Advertisement advertisement = ads.get(0); + advertisement.setDescription(newDescription); + advertisementRepository.save(advertisement); + + stepDefs.result = stepDefs.mockMvc.perform(put("/advertisements/" + advertisement.getId()) + .with(AuthenticationStepDefs.authenticate()) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stepDefs.mapper.writeValueAsString(advertisement)) + .characterEncoding(StandardCharsets.UTF_8)) + .andDo(print()); + } + + @Then("The advertisement with title {string} should have description {string}") + public void theAdvertisementWithTitleShouldHaveDescription(String title, String expectedDescription) throws Exception { + Advertisement updatedAdvertisement = advertisementRepository.findByTitle(title).stream().findFirst().orElse(null); + + if (updatedAdvertisement == null) { + throw new IllegalArgumentException("Advertisement with title " + title + " not found"); + } + + assertEquals(expectedDescription, updatedAdvertisement.getDescription()); + } + + +} From 5f201100378aa506e833341a9a77209164404f28 Mon Sep 17 00:00:00 2001 From: Josep Prades Vidal Date: Sun, 3 Nov 2024 16:46:39 +0100 Subject: [PATCH 29/29] Create UpdateAdvertisement.feature --- .../features/UpdateAdvertisement.feature | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/resources/features/UpdateAdvertisement.feature diff --git a/src/test/resources/features/UpdateAdvertisement.feature b/src/test/resources/features/UpdateAdvertisement.feature new file mode 100644 index 0000000..45371ca --- /dev/null +++ b/src/test/resources/features/UpdateAdvertisement.feature @@ -0,0 +1,60 @@ +Feature: Update Advertisement + In order to update advertisements in the system + As a user + I want to be able to create and update advertisements + + Background: + Given There is a registered user with username "owner" and password "password" and email "test@test.com" + Given There is an existing apartment with id "1" named "Luxury Suite" + And There is an existing advertisement status "Active" + + Scenario: Create and update an advertisement without logged in + Given I'm not logged in + Given There is an advertisement with title "Luxury Suite Ad", description "A beautiful suite", price "2000", zipCode "12345", address "High Street 123", country "Wonderland", status "Active", apartment title "Luxury Suite" + When I update an advertisement with title "Luxury Suite Ad" to have name "Updated Suite Ad" and address "Updated Street 123" + Then The advertisement with title "Updated Suite Ad" should have name "Updated Suite Ad" and address "Updated Street 123" + And The response code is 401 + + Scenario: Create and update an advertisement + Given I login as "owner" with password "password" + Given There is an advertisement with title "Luxury Suite Ad", description "A beautiful suite", price "2000", zipCode "12345", address "High Street 123", country "Wonderland", status "Active", apartment title "Luxury Suite" + When I update an advertisement with title "Luxury Suite Ad" to have name "Updated Suite Ad" and address "Updated Street 123" + Then The advertisement with title "Updated Suite Ad" should have name "Updated Suite Ad" and address "Updated Street 123" + And The response code is 200 + + Scenario: Update advertisement price + Given I login as "owner" with password "password" + Given There is an advertisement with title "Luxury Suite Ad", description "A beautiful suite", price "2000", zipCode "12345", address "High Street 123", country "Wonderland", status "Active", apartment title "Luxury Suite" + When I update the advertisement with title "Luxury Suite Ad" to have price "2500" + Then The advertisement with title "Luxury Suite Ad" should have price "2500.00" + And The response code is 200 + + Scenario: Attempt to update advertisement with invalid data + Given I login as "owner" with password "password" + Given There is an advertisement with title "Luxury Suite Ad", description "A beautiful suite", price "2000", zipCode "12345", address "High Street 123", country "Wonderland", status "Active", apartment title "Luxury Suite" + When I update the advertisement with title "Luxury Suite Ad" to have price "-100.00" + Then The response code is 400 + And The error message is "must be greater than or equal to 0.01" + + Scenario: Update advertisement zip code + Given I login as "owner" with password "password" + Given There is an advertisement with title "Luxury Suite Ad", description "A beautiful suite", price "2000", zipCode "12345", address "High Street 123", country "Wonderland", status "Active", apartment title "Luxury Suite" + When I update the advertisement with title "Luxury Suite Ad" to have zipCode "54321" + Then The advertisement with title "Luxury Suite Ad" should have zipCode "54321" + And The response code is 200 + + Scenario: Update advertisement country + Given I login as "owner" with password "password" + Given There is an advertisement with title "Luxury Suite Ad", description "A beautiful suite", price "2000", zipCode "12345", address "High Street 123", country "Wonderland", status "Active", apartment title "Luxury Suite" + When I update the advertisement with title "Luxury Suite Ad" to have country "Dreamland" + Then The advertisement with title "Luxury Suite Ad" should have country "Dreamland" + And The response code is 200 + + Scenario: Update advertisement description + Given I login as "owner" with password "password" + Given There is an advertisement with title "Luxury Suite Ad", description "A beautiful suite", price "2000", zipCode "12345", address "High Street 123", country "Wonderland", status "Active", apartment title "Luxury Suite" + When I update the advertisement with title "Luxury Suite Ad" to have description "An updated beautiful suite" + Then The advertisement with title "Luxury Suite Ad" should have description "An updated beautiful suite" + And The response code is 200 + +