Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] refactor: 놀이터 전체조회->범위조회로 변경 #780

Merged
merged 3 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.happy.friendogly.playground.dto.request.SavePlaygroundRequest;
import com.happy.friendogly.playground.dto.request.UpdatePlaygroundArrivalRequest;
import com.happy.friendogly.playground.dto.request.UpdatePlaygroundMemberMessageRequest;
import com.happy.friendogly.playground.dto.response.FindMyPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundDetailResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundSummaryResponse;
Expand All @@ -25,12 +26,18 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/playgrounds")
public class PlaygroundController {

private static final String MIN_KOREA_LATITUDE = "33.0637";
private static final String MAX_KOREA_LATITUDE = "43.0042";
private static final String MIN_KOREA_LONGITUDE = "124.1104";
private static final String MAX_KOREA_LONGITUDE = "131.4220";

private final PlaygroundCommandService playgroundCommandService;
private final PlaygroundQueryService playgroundQueryService;

Expand Down Expand Up @@ -64,8 +71,26 @@ public ApiResponse<FindPlaygroundSummaryResponse> findSummaryById(@PathVariable
}

@GetMapping("/locations")
public ApiResponse<List<FindPlaygroundLocationResponse>> findAllLocation(@Auth Long memberId) {
return ApiResponse.ofSuccess(playgroundQueryService.findLocations(memberId));
public ApiResponse<List<FindPlaygroundLocationResponse>> findAllLocations(
@Auth Long memberId,
@RequestParam(defaultValue = MIN_KOREA_LATITUDE) double startLatitude,
@RequestParam(defaultValue = MAX_KOREA_LATITUDE) double endLatitude,
@RequestParam(defaultValue = MIN_KOREA_LONGITUDE) double startLongitude,
@RequestParam(defaultValue = MAX_KOREA_LONGITUDE) double endLongitude
) {
Comment on lines 73 to +80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

명세가 바뀌었네요. 실 사용자 없어서 버전 관리 안한 것이 맞을까요?!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultValue가 있어서 이전 버전에서 쓰면 전체 조회 되는거죠?!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ModelAttribute로 받으면 더 깔끔할 것 같기도~?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

같은 방법을 생각했었는데, 일단 보일러 플레이트제거를 위해 Record를 사용했다면, 아래와 같은 코드가 나옵니다.

public record FindPlaygroundLocationRequest(
        Double startLatitude,
        Double endLatitude,
        Double startLongitude,
        Double endLongitude
) {

    private static final double MIN_KOREA_LATITUDE = 33.0637;
    private static final double MAX_KOREA_LATITUDE = 43.0042;
    private static final double MIN_KOREA_LONGITUDE = 124.1104;
    private static final double MAX_KOREA_LONGITUDE = 131.4220;

    public FindPlaygroundLocationRequest {
        startLatitude = startLatitude == null ? MIN_KOREA_LATITUDE : startLatitude;
        endLatitude = endLatitude == null ? MAX_KOREA_LATITUDE : endLatitude;
        startLongitude = startLongitude == null ? MIN_KOREA_LONGITUDE : startLongitude;
        endLongitude = endLongitude == null ? MAX_KOREA_LONGITUDE : endLongitude;
    }
}

래퍼타입이 아닌 double을 하면 null로 입력을 못받기에 래퍼타입을 사용했고, 해당 로직으로 기본값을 설정해주게 됩니다.
불필요한 래퍼타입을 사용하기도하고, 해당 로직이 Dto에 들어가기에는 겉으로 들어나야하는 중요한 로직이 아닐까라는 생각으로 컨트롤러에 드러냈습니다

List<FindPlaygroundLocationResponse> findPlaygroundLocationResponses = playgroundQueryService.findLocations(
memberId,
startLatitude,
endLatitude,
startLongitude,
endLongitude
);
return ApiResponse.ofSuccess(findPlaygroundLocationResponses);
}

@GetMapping("/locations/mine")
public ApiResponse<FindMyPlaygroundLocationResponse> findMyLocation(@Auth Long memberId) {
return ApiResponse.ofSuccess(playgroundQueryService.findMyPlaygroundLocation(memberId));
}

@PatchMapping("/arrival")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.happy.friendogly.playground.dto.response;

public record FindMyPlaygroundLocationResponse(
Long id,
double latitude,
double longitude
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.happy.friendogly.pet.repository.PetRepository;
import com.happy.friendogly.playground.domain.Playground;
import com.happy.friendogly.playground.domain.PlaygroundMember;
import com.happy.friendogly.playground.dto.response.FindMyPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundDetailResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundSummaryResponse;
Expand Down Expand Up @@ -84,8 +85,19 @@ private int getArrivedPetCount(PlaygroundMember playgroundMember, List<Pet> pets
return 0;
}

public List<FindPlaygroundLocationResponse> findLocations(Long memberId) {
List<Playground> playgrounds = playgroundRepository.findAll();
public List<FindPlaygroundLocationResponse> findLocations(
Long memberId,
double startLatitude,
double endLatitude,
double startLongitude,
double endLongitude
) {
List<Playground> playgrounds = playgroundRepository.findAllByLatitudeBetweenAndLongitudeBetween(
startLatitude,
endLatitude,
startLongitude,
endLongitude
);
Optional<PlaygroundMember> playgroundMember = playgroundMemberRepository.findByMemberId(memberId);

if (playgroundMember.isPresent()) {
Expand Down Expand Up @@ -137,4 +149,14 @@ private List<String> cutPetImagesCount(List<String> petImageUrls) {
}
return petImageUrls;
}

public FindMyPlaygroundLocationResponse findMyPlaygroundLocation(Long memberId) {
PlaygroundMember playgroundMember = playgroundMemberRepository.getByMemberId(memberId);
Playground playground = playgroundMember.getPlayground();
return new FindMyPlaygroundLocationResponse(
playground.getId(),
playground.getLocation().getLatitude(),
playground.getLocation().getLongitude()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static com.epages.restdocs.apispec.ResourceDocumentation.parameterWithName;
import static com.epages.restdocs.apispec.ResourceDocumentation.resource;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyDouble;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
Expand All @@ -18,6 +19,7 @@

import com.epages.restdocs.apispec.ResourceSnippetParameters;
import com.epages.restdocs.apispec.Schema;
import com.epages.restdocs.apispec.SimpleType;
import com.happy.friendogly.member.domain.Member;
import com.happy.friendogly.pet.domain.Gender;
import com.happy.friendogly.pet.domain.Pet;
Expand All @@ -29,6 +31,7 @@
import com.happy.friendogly.playground.dto.request.SavePlaygroundRequest;
import com.happy.friendogly.playground.dto.request.UpdatePlaygroundArrivalRequest;
import com.happy.friendogly.playground.dto.request.UpdatePlaygroundMemberMessageRequest;
import com.happy.friendogly.playground.dto.response.FindMyPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundDetailResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundSummaryResponse;
Expand Down Expand Up @@ -221,19 +224,44 @@ void findAllLocation() throws Exception {
new FindPlaygroundLocationResponse(4L, 37.5131474, 127.1042528, false)
);

when(playgroundQueryService.findLocations(anyLong()))
when(playgroundQueryService.findLocations(anyLong(),anyDouble(),anyDouble(),anyDouble(),anyDouble()))
.thenReturn(response);

mockMvc
.perform(get("/playgrounds/locations")
.header(HttpHeaders.AUTHORIZATION, getMemberToken())
.queryParam("startLatitude", "37.5131474")
.queryParam("endLatitude", "37.5183316")
.queryParam("startLongitude", "127.0983182")
.queryParam("endLongitude", "127.1042528")
)
.andDo(document("playgrounds/findLocations",
getDocumentRequest(),
getDocumentResponse(),
resource(ResourceSnippetParameters.builder()
.tag("Playground API")
.summary("전체 놀이터 위치 조회 API")
.requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION).description("로그인한 회원의 access token")
)
.queryParameters(
parameterWithName("startLatitude")
.type(SimpleType.NUMBER)
.description("시작위도(default - 한국극단위도)")
.optional(),
parameterWithName("endLatitude")
.type(SimpleType.NUMBER)
.description("끝위도(default - 한국극단위도)")
.optional(),
parameterWithName("startLongitude")
.type(SimpleType.NUMBER)
.description("시작경도(default - 한국극단경도)")
.optional(),
parameterWithName("endLongitude")
.type(SimpleType.NUMBER)
.description("끝경도(default - 한국극단경도)")
.optional()
)
.responseFields(
fieldWithPath("isSuccess").description("응답 성공 여부"),
fieldWithPath("data.[].id").description("놀이터의 ID"),
Expand All @@ -248,6 +276,41 @@ void findAllLocation() throws Exception {
.andExpect(status().isOk());
}

@DisplayName("참여한 놀이터의 위치를 조회")
@Test
void findMyPlaygroundLocation() throws Exception {

FindMyPlaygroundLocationResponse response = new FindMyPlaygroundLocationResponse(1L, 37.5173316, 127.1011661);

when(playgroundQueryService.findMyPlaygroundLocation(anyLong()))
.thenReturn(response);

mockMvc
.perform(get("/playgrounds/locations/mine")
.header(HttpHeaders.AUTHORIZATION, getMemberToken())
)
.andDo(document("playgrounds/findMyPlaygroundLocations",
getDocumentRequest(),
getDocumentResponse(),
resource(ResourceSnippetParameters.builder()
.tag("Playground API")
.summary("참여한 놀이터 위치 조회 API")
.requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION).description("로그인한 회원의 access token")
)
.responseFields(
fieldWithPath("isSuccess").description("응답 성공 여부"),
fieldWithPath("data.id").description("놀이터의 ID"),
fieldWithPath("data.latitude").description("놀이터의 위도"),
fieldWithPath("data.longitude").description("놀이터의 경도")
)
.responseSchema(Schema.schema("MyPlaygroundLocationResponse"))
.build()
)
))
.andExpect(status().isOk());
}

@DisplayName("놀이터의 참여 현황 요약 정보를 조회")
@Test
void findSummary() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.happy.friendogly.pet.domain.SizeType;
import com.happy.friendogly.playground.domain.Playground;
import com.happy.friendogly.playground.domain.PlaygroundMember;
import com.happy.friendogly.playground.dto.response.FindMyPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundDetailResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundLocationResponse;
import com.happy.friendogly.playground.dto.response.FindPlaygroundSummaryResponse;
Expand Down Expand Up @@ -112,7 +113,13 @@ void findLocations() {
Playground playground = savePlayground(expectedLatitude, expectedLongitude);

// when
List<FindPlaygroundLocationResponse> response = playgroundQueryService.findLocations(1L);
List<FindPlaygroundLocationResponse> response = playgroundQueryService.findLocations(
1L,
37.0,
38.0,
127.0,
128.0
);

// then
assertAll(
Expand All @@ -121,6 +128,29 @@ void findLocations() {
);
}

@DisplayName("특정 범위내의 놀이터들의 위치를 조회할 수 있다.")
@Test
void findLocationsWithRange() {
// given
Playground insidePlayground = savePlayground(37.5173316, 127.1011661);
Playground outsidePlayground = savePlayground(38.5173316, 128.1011661);

// when
List<FindPlaygroundLocationResponse> playgroundsLocation = playgroundQueryService.findLocations(
1L,
37.0,
38.0,
127.0,
128.0
);

// then
assertAll(
() -> assertThat(playgroundsLocation).hasSize(1),
() -> assertThat(playgroundsLocation.get(0).id()).isEqualTo(insidePlayground.getId())
);
}

@DisplayName("놀이터들의 위치를 조회할 때, 내가 참여했는 지 알 수있다(true)")
@Test
void findLocationsWithIsParticipatingTrue() {
Expand All @@ -141,7 +171,13 @@ void findLocationsWithIsParticipatingTrue() {
);

// when
List<FindPlaygroundLocationResponse> response = playgroundQueryService.findLocations(member1.getId());
List<FindPlaygroundLocationResponse> response = playgroundQueryService.findLocations(
member1.getId(),
37.0,
38.0,
127.0,
128.0
);

// then
assertThat(response.get(0).isParticipating()).isEqualTo(true);
Expand All @@ -157,12 +193,33 @@ void findLocationsWithIsParticipatingFalse() {
savePlayground();

// when
List<FindPlaygroundLocationResponse> response = playgroundQueryService.findLocations(member1.getId());
List<FindPlaygroundLocationResponse> response = playgroundQueryService.findLocations(
member1.getId(),
37.0,
38.0,
127.0,
128.0
);

// then
assertThat(response.get(0).isParticipating()).isEqualTo(false);
}

@DisplayName("내가 참여한 놀이터의 위치를 조회할 수 있다.")
@Test
void findMyPlaygroundLocations() {
// given
Member member = saveMember("member1");
Playground playground = savePlayground();
savePlaygroundMember(playground, member);

// when
FindMyPlaygroundLocationResponse myPlaygroundLocation = playgroundQueryService.findMyPlaygroundLocation(member.getId());

// then
assertThat(myPlaygroundLocation.id()).isEqualTo(playground.getId());
}

@DisplayName("놀이터의 요약정보를 조회한다.")
@Test
void findSummary() {
Expand Down
Loading