From 6cdf296bf3339866d6fed8b06724430dadfd06d7 Mon Sep 17 00:00:00 2001 From: Jan Stroppel Date: Mon, 9 Dec 2024 12:05:41 +0100 Subject: [PATCH 1/4] added GET dancers endpoint --- .../dancier/dancer/core/DancerRepository.java | 15 -------- .../dancier/dancer/core/ProfileService.java | 1 + .../{chat => dancers}/DancerController.java | 19 ++++++++--- .../dancer/dancers/DancerRepository.java | 34 +++++++++++++++++++ .../{core => dancers}/DancerService.java | 24 ++++++++++++- .../recommendation/RecommendationService.java | 2 +- .../CustomUserDetailsServiceImpl.java | 2 +- .../dancer/chat/ChatControllerTest.java | 6 +--- .../dancer/dancers/DancerControllerTest.java | 32 +++++++++++++++++ .../EndToEndRecommendationTest.java | 2 +- src/test/resources/data.sql | 4 +-- 11 files changed, 111 insertions(+), 30 deletions(-) delete mode 100644 src/main/java/net/dancier/dancer/core/DancerRepository.java rename src/main/java/net/dancier/dancer/{chat => dancers}/DancerController.java (68%) create mode 100644 src/main/java/net/dancier/dancer/dancers/DancerRepository.java rename src/main/java/net/dancier/dancer/{core => dancers}/DancerService.java (50%) create mode 100644 src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java diff --git a/src/main/java/net/dancier/dancer/core/DancerRepository.java b/src/main/java/net/dancier/dancer/core/DancerRepository.java deleted file mode 100644 index c78470d3..00000000 --- a/src/main/java/net/dancier/dancer/core/DancerRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.dancier.dancer.core; - -import net.dancier.dancer.core.model.Dancer; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; -import java.util.UUID; - -public interface DancerRepository extends JpaRepository { - - Optional findByUserId(UUID userid); - - Boolean existsByDancerName(String dancerName); - -} diff --git a/src/main/java/net/dancier/dancer/core/ProfileService.java b/src/main/java/net/dancier/dancer/core/ProfileService.java index 5d4465b6..495123d2 100644 --- a/src/main/java/net/dancier/dancer/core/ProfileService.java +++ b/src/main/java/net/dancier/dancer/core/ProfileService.java @@ -15,6 +15,7 @@ import net.dancier.dancer.core.model.DanceProfile; import net.dancier.dancer.core.model.Dancer; import net.dancier.dancer.core.util.ModelMapper; +import net.dancier.dancer.dancers.DancerRepository; import net.dancier.dancer.location.ZipCode; import net.dancier.dancer.location.ZipCodeRepository; import org.slf4j.Logger; diff --git a/src/main/java/net/dancier/dancer/chat/DancerController.java b/src/main/java/net/dancier/dancer/dancers/DancerController.java similarity index 68% rename from src/main/java/net/dancier/dancer/chat/DancerController.java rename to src/main/java/net/dancier/dancer/dancers/DancerController.java index 9d673c19..be631f87 100644 --- a/src/main/java/net/dancier/dancer/chat/DancerController.java +++ b/src/main/java/net/dancier/dancer/dancers/DancerController.java @@ -1,9 +1,10 @@ -package net.dancier.dancer.chat; +package net.dancier.dancer.dancers; import lombok.RequiredArgsConstructor; import net.dancier.dancer.chat.dto.DancerDto; import net.dancier.dancer.chat.dto.DancerIdsDto; -import net.dancier.dancer.core.DancerService; +import net.dancier.dancer.core.dto.PublicProfileDto; +import net.dancier.dancer.core.model.Gender; import net.dancier.dancer.security.AuthenticatedUser; import net.dancier.dancer.security.CurrentUser; import org.slf4j.Logger; @@ -12,8 +13,7 @@ import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import java.util.HashMap; -import java.util.UUID; +import java.util.*; import static net.dancier.dancer.authentication.Constants.ROLE_USER; @@ -25,6 +25,17 @@ public class DancerController { private final DancerService dancerService; + @GetMapping("") + @Secured(ROLE_USER) + public ResponseEntity> get( + @CurrentUser AuthenticatedUser authenticatedUser, + @RequestParam Gender gender, + @RequestParam int range + ) { + log.info("Fetching list of dancers in {} km range with gender {} for user {}", range, gender, authenticatedUser.getUserId()); + return ResponseEntity.ok(dancerService.getDancersList(authenticatedUser, gender, range)); + } + @PostMapping("") @Secured(ROLE_USER) public ResponseEntity> post( diff --git a/src/main/java/net/dancier/dancer/dancers/DancerRepository.java b/src/main/java/net/dancier/dancer/dancers/DancerRepository.java new file mode 100644 index 00000000..6fe77236 --- /dev/null +++ b/src/main/java/net/dancier/dancer/dancers/DancerRepository.java @@ -0,0 +1,34 @@ +package net.dancier.dancer.dancers; + +import net.dancier.dancer.core.model.Dancer; +import net.dancier.dancer.core.model.Gender; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface DancerRepository extends JpaRepository { + + Optional findByUserId(UUID userid); + + Boolean existsByDancerName(String dancerName); + + List findFirst500ByGenderAndLongitudeBetweenAndLatitudeBetween( + Gender gender, + double lowerLongitude, + double upperLongitude, + double lowerLatitude, + double upperLatitude + ); + + List findFirst500ByLongitudeBetween( + double lowerLongitude, + double upperLongitude + ); + + List findFirst500ByGender( + Gender gender + ); + +} diff --git a/src/main/java/net/dancier/dancer/core/DancerService.java b/src/main/java/net/dancier/dancer/dancers/DancerService.java similarity index 50% rename from src/main/java/net/dancier/dancer/core/DancerService.java rename to src/main/java/net/dancier/dancer/dancers/DancerService.java index 27d890ca..2d0a2806 100644 --- a/src/main/java/net/dancier/dancer/core/DancerService.java +++ b/src/main/java/net/dancier/dancer/dancers/DancerService.java @@ -1,9 +1,12 @@ -package net.dancier.dancer.core; +package net.dancier.dancer.dancers; import net.dancier.dancer.chat.dto.DancerDto; import net.dancier.dancer.chat.dto.DancerIdsDto; +import net.dancier.dancer.core.dto.PublicProfileDto; import net.dancier.dancer.core.exception.NotFoundException; import net.dancier.dancer.core.model.Dancer; +import net.dancier.dancer.core.model.Gender; +import net.dancier.dancer.security.AuthenticatedUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -36,4 +39,23 @@ public HashMap getDancerMap(DancerIdsDto dancerIdsDto) { return dancers; } + + public List getDancersList(AuthenticatedUser authenticatedUser, Gender gender, int range) { + + Dancer dancer = loadByUserId(authenticatedUser.getUserId()); + Double longitudeRange = (double)range/112; + Double latitudeRange = range/75.78; + double upperLatitude = dancer.getLatitude() + latitudeRange; + double lowerLatitude = dancer.getLatitude() - latitudeRange; + double upperLongitude = dancer.getLongitude() + longitudeRange; + double lowerLongitude = dancer.getLongitude() - longitudeRange; + + List resultList = dancerRepository.findFirst500ByGenderAndLongitudeBetweenAndLatitudeBetween( + gender, lowerLongitude, upperLongitude, lowerLatitude, upperLatitude); + + return resultList.stream() + .map(PublicProfileDto::of) + .filter(d -> d.getId() != dancer.getId()) + .toList(); + } } diff --git a/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java b/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java index f1256c9d..6a58416a 100644 --- a/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java +++ b/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java @@ -1,7 +1,7 @@ package net.dancier.dancer.recommendation; import lombok.RequiredArgsConstructor; -import net.dancier.dancer.core.DancerRepository; +import net.dancier.dancer.dancers.DancerRepository; import net.dancier.dancer.core.model.Dancer; import net.dancier.dancer.recommendation.model.BaseRecommendation; import net.dancier.dancer.recommendation.model.RecommendationWrapper; diff --git a/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java b/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java index 978455b9..f418aa40 100644 --- a/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java +++ b/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java @@ -4,7 +4,7 @@ import lombok.RequiredArgsConstructor; import net.dancier.dancer.authentication.model.User; import net.dancier.dancer.authentication.repository.UserRepository; -import net.dancier.dancer.core.DancerRepository; +import net.dancier.dancer.dancers.DancerRepository; import net.dancier.dancer.core.model.Dancer; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; diff --git a/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java b/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java index 8d49f02d..8d67f940 100644 --- a/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java +++ b/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java @@ -4,21 +4,17 @@ import net.dancier.dancer.AbstractPostgreSQLEnabledTest; import net.dancier.dancer.chat.client.ChatServiceClient; import net.dancier.dancer.chat.dto.*; -import net.dancier.dancer.core.DancerRepository; +import net.dancier.dancer.dancers.DancerRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.test.web.servlet.ResultActions; -import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.UUID; diff --git a/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java b/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java new file mode 100644 index 00000000..6766d11b --- /dev/null +++ b/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java @@ -0,0 +1,32 @@ +package net.dancier.dancer.dancers; + +import net.dancier.dancer.AbstractPostgreSQLEnabledTest; +import org.junit.jupiter.api.Test; +import org.springframework.security.test.context.support.WithUserDetails; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.util.MultiValueMap; + +import java.util.UUID; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class DancerControllerTest extends AbstractPostgreSQLEnabledTest { + + + UUID userId = UUID.fromString("55bbf334-6649-11ed-8f65-5b299f0e161f"); + + @Test + @WithUserDetails("user-with-a-profile@dancier.net") + void getDancersShouldNotReturnOwnProfile() throws Exception { + + ResultActions result = mockMvc + .perform(get("/dancers") + .param("range", "20") + .param("gender", "MALE") + ) + .andExpect(status().isOk()); + + } +} diff --git a/src/test/java/net/dancier/dancer/recommendation/EndToEndRecommendationTest.java b/src/test/java/net/dancier/dancer/recommendation/EndToEndRecommendationTest.java index 397cd210..ac75168c 100644 --- a/src/test/java/net/dancier/dancer/recommendation/EndToEndRecommendationTest.java +++ b/src/test/java/net/dancier/dancer/recommendation/EndToEndRecommendationTest.java @@ -1,7 +1,7 @@ package net.dancier.dancer.recommendation; import net.dancier.dancer.AbstractPostgreSQLEnabledTest; -import net.dancier.dancer.core.DancerRepository; +import net.dancier.dancer.dancers.DancerRepository; import net.dancier.dancer.core.model.Dancer; import net.dancier.dancer.recommendation.dto.RecommendationDto; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index 25545bde..ffbc59df 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -41,8 +41,8 @@ SELECT '55bbf334-6649-11ed-8f65-5b299f0e161f', WHERE name IN ('ROLE_USER', 'ROLE_HUMAN'); INSERT - INTO dancer(user_id, id) -VALUES ('55bbf334-6649-11ed-8f65-5b299f0e161f', '11065e54-664a-11ed-872e-1b1eb88b44b6'); + INTO dancer(user_id, id, dancer_name, size, birth_date, gender, country, city, longitude, latitude, about_me) +VALUES ('55bbf334-6649-11ed-8f65-5b299f0e161f', '11065e54-664a-11ed-872e-1b1eb88b44b6', 'good_dancer', '178', '2000-11-11', 'MALE', 'GER', 'Dortmund', '7.1075023', '51.4429498', 'Hi'); -- one admin -- no profile attached From 88740663b0c686fcb85d2ffda36a9db96129f0f3 Mon Sep 17 00:00:00 2001 From: Jan Stroppel Date: Tue, 10 Dec 2024 10:57:18 +0100 Subject: [PATCH 2/4] adjusted test case --- .../dancer/dancers/DancerControllerTest.java | 29 +++-- src/test/resources/dancers/data.sql | 116 ++++++++++++++++++ 2 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 src/test/resources/dancers/data.sql diff --git a/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java b/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java index 6766d11b..d18de155 100644 --- a/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java +++ b/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java @@ -5,28 +5,39 @@ import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.web.servlet.ResultActions; -import org.springframework.util.MultiValueMap; -import java.util.UUID; +import java.util.List; +import static net.dancier.dancer.core.model.Gender.FEMALE; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.isA; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; public class DancerControllerTest extends AbstractPostgreSQLEnabledTest { - - UUID userId = UUID.fromString("55bbf334-6649-11ed-8f65-5b299f0e161f"); - @Test @WithUserDetails("user-with-a-profile@dancier.net") - void getDancersShouldNotReturnOwnProfile() throws Exception { + @Sql(value = {"/dancers/data.sql"}) + void getDancersShouldReturnFilteredProfiles() throws Exception { - ResultActions result = mockMvc + mockMvc .perform(get("/dancers") .param("range", "20") - .param("gender", "MALE") + .param("gender", "FEMALE") ) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.*", isA(List.class))) + .andExpect(jsonPath("$.*", hasSize(1))) + .andExpect(jsonPath("$[0].id").value("503ffad4-148b-4af1-8365-62315ff89b9f")) + .andExpect(jsonPath("$[0].gender").value("FEMALE")) + .andExpect(jsonPath("$[0].dancerName").value("perfect_dancer")) + .andExpect(jsonPath("$[0].aboutMe").value("Hi")) + .andExpect(jsonPath("$[0].age").isNotEmpty()) + .andExpect(jsonPath("$[0].size").value("178")) + .andExpect(jsonPath("$[0].city").value("Dortmund")) + .andExpect(jsonPath("$[0].country").value("GER")); } } diff --git a/src/test/resources/dancers/data.sql b/src/test/resources/dancers/data.sql new file mode 100644 index 00000000..f6f99d52 --- /dev/null +++ b/src/test/resources/dancers/data.sql @@ -0,0 +1,116 @@ +-- 5 test users are added +-- user-with-a-profile@dancier.net +-- -> the user that initiates the query +-- user-matching-criterias@dancier.net +-- -> a user that matches all query parameters and is returned by GET /dancers request +-- user-without-matching-gender@dancier.net +-- -> a user that matches all query parameters except gender and is returned by GET /dancers request +-- user-without-matching-latitude@dancier.net +-- -> valid user with a profile but not matching the latitude +-- user-without-matching-longitude@dancier.net +-- -> valid user with a profile but not matching the longitude + +-- user who initiates the query +INSERT + INTO users (id, email, password, email_validated ) + VALUES ( + '55bbf334-6649-11ed-8f65-5b299f0e161f', + 'user-with-a-profile@dancier.net', + '$2a$10$GOChyBEqco9m3wZwkh0RqOTwyWq4HmocguPPfEraSgnbmlrM4.Fey', + true + ); + +INSERT + INTO user_roles (user_id, role_id) +SELECT '55bbf334-6649-11ed-8f65-5b299f0e161f', + id + FROM roles + WHERE name IN ('ROLE_USER', 'ROLE_HUMAN'); + +INSERT + INTO dancer(user_id, id, dancer_name, size, birth_date, gender, country, city, longitude, latitude, about_me) +VALUES ('55bbf334-6649-11ed-8f65-5b299f0e161f', '11065e54-664a-11ed-872e-1b1eb88b44b6', 'good_dancer', '178', '2000-11-11', 'MALE', 'GER', 'Dortmund', '7.1075023', '51.4429498', 'Hi'); + +-- one ordinary user with matching profile +INSERT + INTO users (id, email, password, email_validated ) + VALUES ( + 'b8300af3-a27b-41ed-b35b-3735b25a04df', + 'user-matching-criterias@dancier.net', + '$2a$10$GOChyh6tco9m3wZwkh0RqOTwyWq4HmocguPPfEraSgnbmlrM4.Fax', + true + ); + +INSERT + INTO user_roles (user_id, role_id) +SELECT 'b8300af3-a27b-41ed-b35b-3735b25a04df', + id + FROM roles + WHERE name IN ('ROLE_USER', 'ROLE_HUMAN'); + +INSERT + INTO dancer(user_id, id, dancer_name, size, birth_date, gender, country, city, longitude, latitude, about_me) +VALUES ('b8300af3-a27b-41ed-b35b-3735b25a04df', '503ffad4-148b-4af1-8365-62315ff89b9f', 'perfect_dancer', '178', '1998-11-11', 'FEMALE', 'GER', 'Dortmund', '7.0075023', '51.3429498', 'Hi'); + +-- one ordinary user with not matching gender +INSERT + INTO users (id, email, password, email_validated ) + VALUES ( + 'b90e6478-19d9-492e-97a8-df1f8f7c3901', + 'user-without-matching-gender@dancier.net', + '$2a$10$GOChyh6tco9zu6Zwkh0RqOTwyWq4HmocguPPfEraSgnbmlrM4.Fax', + true + ); + +INSERT + INTO user_roles (user_id, role_id) +SELECT 'b90e6478-19d9-492e-97a8-df1f8f7c3901', + id + FROM roles + WHERE name IN ('ROLE_USER', 'ROLE_HUMAN'); + +INSERT + INTO dancer(user_id, id, dancer_name, size, birth_date, gender, country, city, longitude, latitude, about_me) +VALUES ('b90e6478-19d9-492e-97a8-df1f8f7c3901', '0948c9ba-75a9-4821-8701-0cd3e564f10e', 'Horst', '178', '1980-11-11', 'MALE', 'GER', 'Dortmund', '7.0075023', '51.3429498', 'Hi'); + +-- one ordinary user with not matching latitude +INSERT + INTO users (id, email, password, email_validated ) + VALUES ( + '6cd96820-ce61-4f72-9fa4-6f8900bb7494', + 'user-without-matching-latitude@dancier.net', + '$2a$10$GOChyh6tco9m3wZwkk8tqOTwyWq4HmocguPPfEraSgnbmlrM4.Fax', + true + ); + +INSERT + INTO user_roles (user_id, role_id) +SELECT '6cd96820-ce61-4f72-9fa4-6f8900bb7494', + id + FROM roles + WHERE name IN ('ROLE_USER', 'ROLE_HUMAN'); + +INSERT + INTO dancer(user_id, id, dancer_name, size, birth_date, gender, country, city, longitude, latitude, about_me) +VALUES ('6cd96820-ce61-4f72-9fa4-6f8900bb7494', '9593cd4c-bff4-41b5-b7d8-a632a526721a', 'dancer', '178', '1997-11-11', 'FEMALE', 'GER', 'Bremen', '7.0075023', '54.3429498', 'Hi'); + +-- one ordinary user with not matching longitude +INSERT + INTO users (id, email, password, email_validated ) + VALUES ( + 'e177c7f1-1082-4bd1-ad72-fd88de5b19b2', + 'user-without-matching-longitude@dancier.net', + '$2a$10$GOChyh6tco9m3wZwkk8tqOTwyWq4HmocguPPfEraSgnbmlrM4.Fax', + true + ); + +INSERT + INTO user_roles (user_id, role_id) +SELECT 'e177c7f1-1082-4bd1-ad72-fd88de5b19b2', + id + FROM roles + WHERE name IN ('ROLE_USER', 'ROLE_HUMAN'); + +INSERT + INTO dancer(user_id, id, dancer_name, size, birth_date, gender, country, city, longitude, latitude, about_me) +VALUES ('e177c7f1-1082-4bd1-ad72-fd88de5b19b2', 'f140bc96-5d65-4e6b-8727-f89f2afef03d', 'dancing_queen', '178', '1995-11-11', 'FEMALE', 'GER', 'Essen', '6.0075023', '51.3429498', 'Hi'); From 35c75caed0b59faf8af4f479487c6f958db51568 Mon Sep 17 00:00:00 2001 From: Jan Stroppel Date: Tue, 10 Dec 2024 11:08:55 +0100 Subject: [PATCH 3/4] removed unneeded methods --- .../net/dancier/dancer/dancers/DancerRepository.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/net/dancier/dancer/dancers/DancerRepository.java b/src/main/java/net/dancier/dancer/dancers/DancerRepository.java index 6fe77236..abcb9a6a 100644 --- a/src/main/java/net/dancier/dancer/dancers/DancerRepository.java +++ b/src/main/java/net/dancier/dancer/dancers/DancerRepository.java @@ -22,13 +22,4 @@ List findFirst500ByGenderAndLongitudeBetweenAndLatitudeBetween( double upperLatitude ); - List findFirst500ByLongitudeBetween( - double lowerLongitude, - double upperLongitude - ); - - List findFirst500ByGender( - Gender gender - ); - } From f02600a573f36366a5d96b48e50f291b693761e3 Mon Sep 17 00:00:00 2001 From: Jan Stroppel Date: Sun, 22 Dec 2024 15:20:29 +0100 Subject: [PATCH 4/4] added review comments --- api/swagger.yaml | 4 +-- .../dancer/dancers/DancerController.java | 4 +-- .../dancier/dancer/dancers/DancerService.java | 10 ++++-- .../dancer/dancers/DancerControllerTest.java | 36 ++++++++++++++++--- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/api/swagger.yaml b/api/swagger.yaml index 17ef452d..8415b098 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -652,13 +652,13 @@ components: gender: name: gender in: query - description: preferred gender of the dancers + description: required preferred gender of the dancers schema: type: string range: name: range in: query - description: Range [km] in which the search for dancers should be done + description: Range [km] in which the search for dancers should be done, defaults to 20 km schema: type: string schemas: diff --git a/src/main/java/net/dancier/dancer/dancers/DancerController.java b/src/main/java/net/dancier/dancer/dancers/DancerController.java index be631f87..40382aa5 100644 --- a/src/main/java/net/dancier/dancer/dancers/DancerController.java +++ b/src/main/java/net/dancier/dancer/dancers/DancerController.java @@ -30,10 +30,10 @@ public class DancerController { public ResponseEntity> get( @CurrentUser AuthenticatedUser authenticatedUser, @RequestParam Gender gender, - @RequestParam int range + @RequestParam(defaultValue = "20") int range ) { log.info("Fetching list of dancers in {} km range with gender {} for user {}", range, gender, authenticatedUser.getUserId()); - return ResponseEntity.ok(dancerService.getDancersList(authenticatedUser, gender, range)); + return ResponseEntity.ok(dancerService.getDancerList(authenticatedUser, gender, range)); } @PostMapping("") diff --git a/src/main/java/net/dancier/dancer/dancers/DancerService.java b/src/main/java/net/dancier/dancer/dancers/DancerService.java index 2d0a2806..8803e7bf 100644 --- a/src/main/java/net/dancier/dancer/dancers/DancerService.java +++ b/src/main/java/net/dancier/dancer/dancers/DancerService.java @@ -40,11 +40,15 @@ public HashMap getDancerMap(DancerIdsDto dancerIdsDto) { return dancers; } - public List getDancersList(AuthenticatedUser authenticatedUser, Gender gender, int range) { + public List getDancerList(AuthenticatedUser authenticatedUser, Gender gender, int range) { Dancer dancer = loadByUserId(authenticatedUser.getUserId()); - Double longitudeRange = (double)range/112; - Double latitudeRange = range/75.78; + + // 1° in longitude in Germany (latitude 47) are 75,78 km + double longitudeRange = range/75.78; + // 1° in longitude are 112,12 km + double latitudeRange = range/112.12; + double upperLatitude = dancer.getLatitude() + latitudeRange; double lowerLatitude = dancer.getLatitude() - latitudeRange; double upperLongitude = dancer.getLongitude() + longitudeRange; diff --git a/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java b/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java index d18de155..b427b376 100644 --- a/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java +++ b/src/test/java/net/dancier/dancer/dancers/DancerControllerTest.java @@ -4,22 +4,18 @@ import org.junit.jupiter.api.Test; import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.test.context.jdbc.Sql; -import org.springframework.test.web.servlet.ResultActions; - import java.util.List; - -import static net.dancier.dancer.core.model.Gender.FEMALE; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.isA; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +@Sql(value = {"/dancers/data.sql"}) public class DancerControllerTest extends AbstractPostgreSQLEnabledTest { @Test @WithUserDetails("user-with-a-profile@dancier.net") - @Sql(value = {"/dancers/data.sql"}) void getDancersShouldReturnFilteredProfiles() throws Exception { mockMvc @@ -40,4 +36,34 @@ void getDancersShouldReturnFilteredProfiles() throws Exception { .andExpect(jsonPath("$[0].country").value("GER")); } + + @Test + @WithUserDetails("user-with-a-profile@dancier.net") + void getDancersUsingDefaultRange() throws Exception { + + mockMvc + .perform(get("/dancers") + .param("gender", "FEMALE") + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.*", isA(List.class))) + .andExpect(jsonPath("$.*", hasSize(1))) + .andExpect(jsonPath("$[0].id").value("503ffad4-148b-4af1-8365-62315ff89b9f")) + .andExpect(jsonPath("$[0].gender").value("FEMALE")) + .andExpect(jsonPath("$[0].dancerName").value("perfect_dancer")) + .andExpect(jsonPath("$[0].aboutMe").value("Hi")) + .andExpect(jsonPath("$[0].age").isNotEmpty()) + .andExpect(jsonPath("$[0].size").value("178")) + .andExpect(jsonPath("$[0].city").value("Dortmund")) + .andExpect(jsonPath("$[0].country").value("GER")); + + } + + @Test + @WithUserDetails("user-with-a-profile@dancier.net") + void shouldFailIfGenderIsNotSet() throws Exception { + mockMvc .perform(get("/dancers") + .param("range", "20") + ).andExpect(status().isBadRequest()); + } }