diff --git a/backend/.gitignore b/backend/.gitignore index a02a3af4..5de39c9e 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -37,3 +37,5 @@ out/ ### VS Code ### .vscode/ + +/src/main/generated/ diff --git a/backend/src/docs/friend.adoc b/backend/src/docs/friend.adoc new file mode 100644 index 00000000..f6049e48 --- /dev/null +++ b/backend/src/docs/friend.adoc @@ -0,0 +1,21 @@ +:doctype: book +:icons: font +:source-highlighter: highlightjs +:toc: left +:toclevels: 4 + +== Friend +=== 친구 신청 +operation::post request friend[snippets='http-request,http-response'] + +=== 친구 승락/거절/차단 +operation::post update friend status[snippets='http-request,http-response'] + +=== 친구 검색 +operation::get search friend[snippets='http-request,http-response'] + +=== 친구 전체 조회 +operation::get all friends[snippets='http-request,http-response'] + +=== 친구 상태별 조회 +operation::get friends by status[snippets='http-request,http-response'] diff --git a/backend/src/docs/index.adoc b/backend/src/docs/index.adoc index bd176ec9..725e814f 100644 --- a/backend/src/docs/index.adoc +++ b/backend/src/docs/index.adoc @@ -13,3 +13,4 @@ include::path.adoc[] include::plan.adoc[] include::place.adoc[] include::member.adoc[] +include::friend.adoc[] diff --git a/backend/src/main/java/com/twtw/backend/domain/friend/controller/FriendController.java b/backend/src/main/java/com/twtw/backend/domain/friend/controller/FriendController.java index 96196736..1557c22c 100644 --- a/backend/src/main/java/com/twtw/backend/domain/friend/controller/FriendController.java +++ b/backend/src/main/java/com/twtw/backend/domain/friend/controller/FriendController.java @@ -38,7 +38,7 @@ public ResponseEntity addRequest(@RequestBody final FriendRequest friendRe } @PostMapping("deny") - public ResponseEntity deny(@RequestBody final FriendUpdateRequest friendUpdateRequest) { + public ResponseEntity updateStatus(@RequestBody final FriendUpdateRequest friendUpdateRequest) { friendService.updateStatus(friendUpdateRequest); return ResponseEntity.noContent().build(); } diff --git a/backend/src/test/java/com/twtw/backend/domain/friend/controller/FriendControllerTest.java b/backend/src/test/java/com/twtw/backend/domain/friend/controller/FriendControllerTest.java new file mode 100644 index 00000000..937c20d9 --- /dev/null +++ b/backend/src/test/java/com/twtw/backend/domain/friend/controller/FriendControllerTest.java @@ -0,0 +1,164 @@ +package com.twtw.backend.domain.friend.controller; + +import com.twtw.backend.domain.friend.dto.request.FriendRequest; +import com.twtw.backend.domain.friend.dto.request.FriendUpdateRequest; +import com.twtw.backend.domain.friend.dto.response.FriendResponse; +import com.twtw.backend.domain.friend.entity.FriendStatus; +import com.twtw.backend.domain.friend.service.FriendService; +import com.twtw.backend.support.docs.RestDocsTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.ResultActions; + +import java.util.List; +import java.util.UUID; + +import static com.twtw.backend.support.docs.ApiDocsUtils.getDocumentRequest; +import static com.twtw.backend.support.docs.ApiDocsUtils.getDocumentResponse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DisplayName("FriendController의") +@WebMvcTest(FriendController.class) +class FriendControllerTest extends RestDocsTest { + @MockBean private FriendService friendService; + + @Test + @DisplayName("친구 전체 조회 API가 수행되는가") + void getFriends() throws Exception { + //given + final List expected = List.of( + new FriendResponse(UUID.randomUUID(), "정해진"), + new FriendResponse(UUID.randomUUID(), "주어진")); + given(friendService.getFriends()).willReturn(expected); + + //when + final ResultActions perform = + mockMvc.perform( + get("/friends/all") + .contentType(MediaType.APPLICATION_JSON) + .header( + "Authorization", + "Bearer wefa3fsdczf32.gaoiuergf92.gb5hsa2jgh")); + + //then + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$").isArray()); + + //docs + perform.andDo(print()) + .andDo(document("get all friends", getDocumentRequest(), getDocumentResponse())); + } + + @Test + @DisplayName("친구 상태별 조회 API가 수행되는가") + void getFriendsByStatus() throws Exception { + //given + final List expected = List.of( + new FriendResponse(UUID.randomUUID(), "호전"), + new FriendResponse(UUID.randomUUID(), "후진")); + given(friendService.getFriendsByStatus(any())).willReturn(expected); + + //when + final ResultActions perform = + mockMvc.perform( + get("/friends?friendStatus=REQUESTED") + .contentType(MediaType.APPLICATION_JSON) + .header( + "Authorization", + "Bearer wefa3fsdczf32.gaoiuergf92.gb5hsa2jgh")); + + //then + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$").isArray()); + + //docs + perform.andDo(print()) + .andDo(document("get friends by status", getDocumentRequest(), getDocumentResponse())); + } + + @Test + @DisplayName("친구 신청 API가 수행되는가") + void addRequest() throws Exception { + //given + willDoNothing().given(friendService).addRequest(any()); + + //when + final ResultActions perform = + mockMvc.perform( + post("/friends/request") + .contentType(MediaType.APPLICATION_JSON) + .content(toRequestBody(new FriendRequest(UUID.randomUUID()))) + .header( + "Authorization", + "Bearer wefa3fsdczf32.gaoiuergf92.gb5hsa2jgh")); + + //then + perform.andExpect(status().isNoContent()); + + //docs + perform.andDo(print()) + .andDo(document("post request friend", getDocumentRequest(), getDocumentResponse())); + } + + @Test + @DisplayName("친구 상태 업데이트 API가 수행되는가") + void updateStatus() throws Exception { + //given + willDoNothing().given(friendService).updateStatus(any()); + + //when + final ResultActions perform = + mockMvc.perform( + post("/friends/request") + .contentType(MediaType.APPLICATION_JSON) + .content(toRequestBody(new FriendUpdateRequest(UUID.randomUUID(), FriendStatus.ACCEPTED))) + .header( + "Authorization", + "Bearer wefa3fsdczf32.gaoiuergf92.gb5hsa2jgh")); + + //then + perform.andExpect(status().isNoContent()); + + //docs + perform.andDo(print()) + .andDo(document("post update friend status", getDocumentRequest(), getDocumentResponse())); + } + + @Test + @DisplayName("친구 이름으로 검색 API가 수행되는가") + void getFriendByName() throws Exception { + //given + final List expected = List.of( + new FriendResponse(UUID.randomUUID(), "호진정"), + new FriendResponse(UUID.randomUUID(), "진정해")); + given(friendService.getFriendByNickname(any())).willReturn(expected); + + //when + final ResultActions perform = + mockMvc.perform( + get("/friends/search?nickname=hojin") + .contentType(MediaType.APPLICATION_JSON) + .header( + "Authorization", + "Bearer wefa3fsdczf32.gaoiuergf92.gb5hsa2jgh")); + + //then + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$").isArray()); + + //docs + perform.andDo(print()) + .andDo(document("get search friend", getDocumentRequest(), getDocumentResponse())); + } +}