From 82b6dfc5a008038bea14ca2834773757ac6c33ac Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 00:08:19 +0900 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20=EC=9E=85=EB=8D=95=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=9E=91=EC=84=B1,=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=20=EC=9C=A0=EB=AC=B4=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AttractionPointService.java | 10 +++- .../service/AttractionPointServiceImpl.java | 46 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java index 1ef6001d..18de7dc0 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java @@ -1,11 +1,19 @@ package io.oduck.api.domain.attractionPoint.service; -import io.oduck.api.domain.attractionPoint.dto.AttractionPointResDto.IsAttractionPoint; + +import io.oduck.api.domain.attractionPoint.dto.AttractionPointReqDto.*; +import io.oduck.api.domain.attractionPoint.dto.AttractionPointResDto.*; import org.springframework.stereotype.Service; @Service public interface AttractionPointService { + //입덕 포인트 추가 + void save(Long memberId, AttractionPointReq req); + + //입덕 포인트 평가 여부 + boolean checkAttractionPoint(Long memberId, Long animeId); + //입덕포인트 조회(true/false) IsAttractionPoint isAttractionPoint(Long memberId, Long animeId); } diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java index b485b722..54992b2f 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java @@ -1,12 +1,22 @@ package io.oduck.api.domain.attractionPoint.service; -import io.oduck.api.domain.attractionPoint.dto.AttractionPointResDto.IsAttractionPoint; +import io.oduck.api.domain.anime.entity.Anime; +import io.oduck.api.domain.anime.repository.AnimeRepository; +import io.oduck.api.domain.attractionPoint.dto.AttractionPointReqDto.*; +import io.oduck.api.domain.attractionPoint.dto.AttractionPointResDto.*; import io.oduck.api.domain.attractionPoint.entity.AttractionPoint; import io.oduck.api.domain.attractionPoint.repository.AttractionPointRepository; import java.util.List; +import java.util.Optional; + +import io.oduck.api.domain.member.entity.Member; +import io.oduck.api.domain.member.repository.MemberRepository; +import io.oduck.api.global.exception.BadRequestException; +import io.oduck.api.global.exception.NotFoundException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Slf4j @Service @@ -14,6 +24,9 @@ public class AttractionPointServiceImpl implements AttractionPointService { private final AttractionPointRepository attractionPointRepository; + private final MemberRepository memberRepository; + private final AnimeRepository animeRepository; + @Override public IsAttractionPoint isAttractionPoint(Long memberId, Long animeId) { boolean drawing = false; @@ -41,4 +54,35 @@ public IsAttractionPoint isAttractionPoint(Long memberId, Long animeId) { .voiceActor(voiceActor) .build(); } + + @Override + @Transactional + public void save(Long memberId, AttractionPointReq req) { + if(!checkAttractionPoint(memberId, req.getAnimeId())){ + throw new BadRequestException("AttractionPoint is already exists."); + } + + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException("Member")); + + Anime anime = animeRepository.findById(req.getAnimeId()) + .orElseThrow(() -> new NotFoundException("Anime")); + + + for(int i = 0; i < req.getAttractionElements().size(); i++){ + AttractionPoint attractionPoint = AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(req.getAttractionElements().get(i)) + .build(); + attractionPointRepository.save(attractionPoint); + } + } + + @Override + public boolean checkAttractionPoint(Long memberId, Long animeId) { + List findPoint = attractionPointRepository.findAllByAnimeIdAndMemberId(memberId, animeId); + return findPoint.isEmpty(); + } } From d3c654310873884bea7ccb568c9cd770aa2ae833 Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 00:09:13 +0900 Subject: [PATCH 02/13] =?UTF-8?q?feat:=20=EC=9E=85=EB=8D=95=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=9E=91=EC=84=B1,=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=20=EC=9C=A0=EB=AC=B4=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AttractionPointController.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/io/oduck/api/domain/attractionPoint/controller/AttractionPointController.java diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/controller/AttractionPointController.java b/src/main/java/io/oduck/api/domain/attractionPoint/controller/AttractionPointController.java new file mode 100644 index 00000000..e017282d --- /dev/null +++ b/src/main/java/io/oduck/api/domain/attractionPoint/controller/AttractionPointController.java @@ -0,0 +1,38 @@ +package io.oduck.api.domain.attractionPoint.controller; + +import io.oduck.api.domain.attractionPoint.dto.AttractionPointReqDto.*; +import io.oduck.api.domain.attractionPoint.service.AttractionPointService; +import io.oduck.api.global.security.auth.dto.AuthUser; +import io.oduck.api.global.security.auth.dto.LoginUser; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +@Validated +@RestController +@RequiredArgsConstructor +@RequestMapping("/attraction-points") +@Slf4j +public class AttractionPointController { + + final AttractionPointService attractionPointService; + + @PostMapping + public ResponseEntity postAttractionPoint( + @LoginUser AuthUser user, + @RequestBody @Valid AttractionPointReq req){ + //TODO: 입덕포인트 작성 + attractionPointService.save(user.getId(), req); + return ResponseEntity.ok().build(); + } + + @GetMapping("/{animeId}") + public ResponseEntity getAttractionPoint( + @LoginUser AuthUser user, + @PathVariable("animeId") Long animeId){ + return ResponseEntity.ok(attractionPointService.checkAttractionPoint(user.getId(), animeId)); + } +} From cd601a8dc5810b718edf2976ff85b14d94b2038a Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 00:09:39 +0900 Subject: [PATCH 03/13] =?UTF-8?q?feat:=20=EC=9E=85=EB=8D=95=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=9E=91=EC=84=B1=20DTO=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/AttractionPointReqDto.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointReqDto.java diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointReqDto.java b/src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointReqDto.java new file mode 100644 index 00000000..a3b19e83 --- /dev/null +++ b/src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointReqDto.java @@ -0,0 +1,25 @@ +package io.oduck.api.domain.attractionPoint.dto; + +import io.oduck.api.domain.attractionPoint.entity.AttractionElement; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +public class AttractionPointReqDto { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class AttractionPointReq{ + private Long animeId; + @NotNull(message = "입덕포인트를 선택하세요.") + List attractionElements; + } + + +} From 484d491a4801357d2c826ec67669d3a07d66b33f Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 00:10:28 +0900 Subject: [PATCH 04/13] =?UTF-8?q?refactor:=20=EC=9E=85=EB=8D=95=20?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=97=94=ED=8B=B0=ED=8B=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/domain/attractionPoint/entity/AttractionPoint.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/entity/AttractionPoint.java b/src/main/java/io/oduck/api/domain/attractionPoint/entity/AttractionPoint.java index 16bf038c..99c64d55 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/entity/AttractionPoint.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/entity/AttractionPoint.java @@ -51,6 +51,8 @@ public void relateAnime(Anime anime){ } public void updateElement(AttractionElement attractionElement){ - this.attractionElement = attractionElement; + if(!this.attractionElement.equals(attractionElement)){ + this.attractionElement = attractionElement; + } } } From 1ccd9175b6dc3e85f3c27f5165991fb5beeceb16 Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 00:12:35 +0900 Subject: [PATCH 05/13] =?UTF-8?q?test:=20=EC=9E=85=EB=8D=95=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=83=9D=EC=84=B1,=20=EC=A1=B4=EC=9E=AC?= =?UTF-8?q?=20=EC=9C=A0=EB=AC=B4=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20?= =?UTF-8?q?test=20=EC=B6=94=EA=B0=80=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AttractionPointControllerTest.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java diff --git a/src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java b/src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java new file mode 100644 index 00000000..08673c40 --- /dev/null +++ b/src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java @@ -0,0 +1,114 @@ +package io.oduck.api.e2e.attractionPoint; + +import com.google.gson.Gson; +import io.oduck.api.domain.attractionPoint.dto.AttractionPointReqDto.*; +import io.oduck.api.domain.attractionPoint.entity.AttractionElement; +import io.oduck.api.domain.member.entity.Member; +import io.oduck.api.domain.member.entity.Role; +import io.oduck.api.global.mockMember.WithCustomMockMember; +import io.oduck.api.global.stub.MemberStub; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import java.util.ArrayList; +import java.util.List; + +import static io.oduck.api.global.config.RestDocsConfig.field; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.snippet.Attributes.attributes; +import static org.springframework.restdocs.snippet.Attributes.key; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@AutoConfigureRestDocs +@ExtendWith({RestDocumentationExtension.class, SpringExtension.class}) +@SpringBootTest +@ActiveProfiles("test") +class AttractionPointControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private Gson gson; + + private final String BASE_URL = "/attraction-points"; + + @Nested + @DisplayName("입덕포인트 생성") + class PostAttractionPoint{ + + @Test + @WithCustomMockMember(id = 2L, email = "john", password = "Qwer!234", role = Role.MEMBER) + @DisplayName("입덕포인트 생성 성공 시 status 200 반환") + void postAttractionPoint() throws Exception { + //given + Member member = new MemberStub().getMember(); + Long animeId = 1L; + List elementList = new ArrayList<>(); + elementList.add(AttractionElement.DRAWING); + elementList.add(AttractionElement.STORY); + + AttractionPointReq postAttractionPoint = AttractionPointReq + .builder() + .animeId(animeId) + .attractionElements(elementList) + .build(); + + String content = gson.toJson(postAttractionPoint); + + //when + ResultActions actions = mockMvc.perform( + post(BASE_URL) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.COOKIE, "oDuckio.sid={SESSION_VALUE}") + .content(content)); + + //then + actions + .andExpect(status().isOk()) + .andDo(document("postAttractionPoint/success", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(HttpHeaders.COOKIE) + .attributes(field("constraints", "oDuckio.sid={SESSION_VALUE}")) + .description("Header Cookie, 세션 쿠키") + ), + requestFields(attributes(key("title").value("Fields for AttractionPoint creation")), + fieldWithPath("animeId") + .type(JsonFieldType.NUMBER) + .attributes(field("constraints", "애니 아이디, NotNull, Min(1)")) + .description("애니 고유 식별 번호"), + fieldWithPath("attractionElements") + .type(JsonFieldType.ARRAY) + .attributes(field("constraints", "DRAWING, STORY, MUSIC, CHARACTER, VOICE_ACTOR 리스트만 허용합니다. ")) + .description("입덕포인트 리스트") + )) + ); + } + } + +} \ No newline at end of file From a7c7d21a6a87a7096f5c1d397dbc636ecad81d9a Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 00:12:54 +0900 Subject: [PATCH 06/13] =?UTF-8?q?test:=20=EC=9E=85=EB=8D=95=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=83=9D=EC=84=B1,=20=EC=A1=B4=EC=9E=AC?= =?UTF-8?q?=20=EC=9C=A0=EB=AC=B4=20=EB=A6=AC=ED=8F=AC=EC=A7=80=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=20test=20=EC=B6=94=EA=B0=80=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AttractionPointRepositoryTest.java | 103 +++++++++++++----- 1 file changed, 73 insertions(+), 30 deletions(-) diff --git a/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java b/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java index f16d80b8..bd7251ff 100644 --- a/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java +++ b/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java @@ -1,17 +1,8 @@ package io.oduck.api.unit.attractionPoint.repository; -import static io.oduck.api.global.utils.AnimeTestUtils.getBroadcastType; -import static io.oduck.api.global.utils.AnimeTestUtils.getEpisodeCount; -import static io.oduck.api.global.utils.AnimeTestUtils.getQuarter; -import static io.oduck.api.global.utils.AnimeTestUtils.getRating; -import static io.oduck.api.global.utils.AnimeTestUtils.getStatus; -import static io.oduck.api.global.utils.AnimeTestUtils.getSummary; -import static io.oduck.api.global.utils.AnimeTestUtils.getThumbnail; -import static io.oduck.api.global.utils.AnimeTestUtils.getTitle; -import static io.oduck.api.global.utils.AnimeTestUtils.getYear; -import static io.oduck.api.global.utils.AnimeTestUtils.isReleased; +import static io.oduck.api.global.utils.AnimeTestUtils.*; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.*; import io.oduck.api.domain.anime.entity.Anime; import io.oduck.api.domain.anime.entity.AnimeGenre; @@ -25,6 +16,8 @@ import io.oduck.api.domain.member.entity.Member; import java.util.ArrayList; import java.util.List; + +import io.oduck.api.domain.member.repository.MemberRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -43,23 +36,25 @@ public class AttractionPointRepositoryTest { @Autowired private AnimeRepository animeRepository; + @Autowired + private MemberRepository memberRepository; @Nested @DisplayName("애니 입덕 포인트 조회") - class isAttractionPoint{ + class isAttractionPoint { @Test @DisplayName("입덕포인트 조회 성공") - void isAttactionPoint(){ + void isAttractionPoint() { //given //회원 생성 Long memberId = 1L; Long pointId1 = 1L; Long pointId2 = 2L; Member member = Member.builder() - .id(memberId) - .build(); + .id(memberId) + .build(); // 애니 생성 List animeStudios = new ArrayList<>(); @@ -68,9 +63,9 @@ void isAttactionPoint(){ List animeOriginalAuthors = new ArrayList<>(); Anime createAnime = Anime.createAnime( - getTitle(), getSummary(), getBroadcastType(), getEpisodeCount(), getThumbnail(), - getYear(), getQuarter(), getRating(), getStatus(), isReleased(), - animeOriginalAuthors, animeStudios, animeVoiceActors, animeGenres, null + getTitle(), getSummary(), getBroadcastType(), getEpisodeCount(), getThumbnail(), + getYear(), getQuarter(), getRating(), getStatus(), isReleased(), + animeOriginalAuthors, animeStudios, animeVoiceActors, animeGenres, null ); Anime anime = animeRepository.saveAndFlush(createAnime); @@ -78,19 +73,19 @@ void isAttactionPoint(){ //입덕포인트 등록 AttractionPoint drawing = AttractionPoint - .builder() - .id(pointId1) - .member(member) - .anime(anime) - .attractionElement(AttractionElement.DRAWING) - .build(); + .builder() + .id(pointId1) + .member(member) + .anime(anime) + .attractionElement(AttractionElement.DRAWING) + .build(); AttractionPoint story = AttractionPoint - .builder() - .id(pointId2) - .member(member) - .anime(anime) - .attractionElement(AttractionElement.STORY) - .build(); + .builder() + .id(pointId2) + .member(member) + .anime(anime) + .attractionElement(AttractionElement.STORY) + .build(); AttractionPoint saveDrawing = attractionPointRepository.save(drawing); AttractionPoint saveStory = attractionPointRepository.save(story); @@ -109,6 +104,54 @@ void isAttactionPoint(){ assertThat(findStory).isEqualTo(saveStory.getAttractionElement()); } } + @Nested + @DisplayName("애니 입덕 포인트 생성") + class PostAttractionPoint{ + + @Test + @DisplayName("입덕포인트 추가 성공 시 status 200 반환") + void saveAttractionPoint(){ + //given + + //회원 생성 + Long memberId = 1L; + Member member = Member.builder() + .id(memberId) + .build(); + + // 애니 생성 + Anime anime = animeRepository.saveAndFlush(createAnime()); + memberRepository.save(member); + + List find = attractionPointRepository.findAllByAnimeIdAndMemberId(memberId, anime.getId()); + + //입덕포인트 등록 + AttractionPoint drawing = AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(AttractionElement.DRAWING) + .build(); + AttractionPoint story = AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(AttractionElement.STORY) + .build(); + + //when + AttractionPoint saveDrawing = attractionPointRepository.save(drawing); + AttractionPoint saveStory = attractionPointRepository.save(story); + + //then + assertNotNull(anime); + assertNotNull(member); + assertTrue(find.isEmpty()); + assertThat(saveDrawing.getAttractionElement()).isEqualTo(drawing.getAttractionElement()); + assertThat(saveStory.getAttractionElement()).isEqualTo(story.getAttractionElement()); + } + + } From 6d401578b19c6616b2a74a2a6845b4df31594eb7 Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 00:13:05 +0900 Subject: [PATCH 07/13] =?UTF-8?q?test:=20=EC=9E=85=EB=8D=95=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=83=9D=EC=84=B1,=20=EC=A1=B4=EC=9E=AC?= =?UTF-8?q?=20=EC=9C=A0=EB=AC=B4=20=EC=84=9C=EB=B9=84=EC=8A=A4=20test=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AttractionPointServiceTest.java | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/test/java/io/oduck/api/unit/attractionPoint/service/AttractionPointServiceTest.java b/src/test/java/io/oduck/api/unit/attractionPoint/service/AttractionPointServiceTest.java index 7721b0c1..11d735e5 100644 --- a/src/test/java/io/oduck/api/unit/attractionPoint/service/AttractionPointServiceTest.java +++ b/src/test/java/io/oduck/api/unit/attractionPoint/service/AttractionPointServiceTest.java @@ -1,10 +1,22 @@ package io.oduck.api.unit.attractionPoint.service; +import static io.oduck.api.global.utils.AnimeTestUtils.createAnime; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doReturn; +import io.oduck.api.domain.anime.entity.Anime; +import io.oduck.api.domain.anime.repository.AnimeRepository; +import io.oduck.api.domain.attractionPoint.dto.AttractionPointReqDto.*; import io.oduck.api.domain.attractionPoint.dto.AttractionPointResDto.IsAttractionPoint; +import io.oduck.api.domain.attractionPoint.entity.AttractionElement; +import io.oduck.api.domain.attractionPoint.entity.AttractionPoint; import io.oduck.api.domain.attractionPoint.repository.AttractionPointRepository; import io.oduck.api.domain.attractionPoint.service.AttractionPointServiceImpl; +import io.oduck.api.domain.member.entity.Member; +import io.oduck.api.domain.member.repository.MemberRepository; +import io.oduck.api.global.stub.MemberStub; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -13,14 +25,58 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + @ExtendWith(MockitoExtension.class) public class AttractionPointServiceTest { @InjectMocks private AttractionPointServiceImpl attractionPointService; - @Mock private AttractionPointRepository attractionPointRepository; + @Mock + private MemberRepository memberRepository; + @Mock + private AnimeRepository animeRepository; + + Member member = Member + .builder() + .id(1L) + .build(); + Anime anime = createAnime(); + @Nested + @DisplayName("입덕 포인트 추가") + class PostAttractionPoint{ + + @Test + @DisplayName("입덕 포인트 추가 성공 시 status 200 반환") + void saveAttractionPoint(){ + //given + List list = new ArrayList<>(); + List elementList = new ArrayList<>(); + elementList.add(AttractionElement.DRAWING); + elementList.add(AttractionElement.STORY); + + given(attractionPointRepository.findAllByAnimeIdAndMemberId(anyLong(), anyLong())) + .willReturn(list); + given(memberRepository.findById(anyLong())).willReturn(Optional.of(member)); + given(animeRepository.findById(anyLong())).willReturn(Optional.ofNullable(anime)); + + AttractionPointReq req = AttractionPointReq + .builder() + .animeId(1L) + .attractionElements(elementList) + .build(); + + //when + attractionPointService.save(member.getId(),req); + + //then + assertDoesNotThrow(() -> attractionPointService.save(member.getId(), req)); + } + } @Nested @DisplayName("입덕 포인트 조회") From ccc8c70ae9b247002700e3473ea0669c4c2d4ce0 Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 19:44:32 +0900 Subject: [PATCH 08/13] =?UTF-8?q?feat:=20=EC=9E=85=EB=8D=95=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=A1=B4=EC=9E=AC=20=EC=9C=A0=EB=AC=B4=20?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=98=ED=99=98=ED=95=A0=20DTO=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../attractionPoint/dto/AttractionPointResDto.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointResDto.java b/src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointResDto.java index 4b12c34a..0e3c64e9 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointResDto.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/dto/AttractionPointResDto.java @@ -1,7 +1,9 @@ package io.oduck.api.domain.attractionPoint.dto; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; @Getter @Builder @@ -16,4 +18,11 @@ public static class IsAttractionPoint{ private boolean voiceActor; } + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class CheckAttractionPoint{ + private Boolean isAttractionPoint; + } } From b2f55e01c5623bd4155c3cb12800def8f88c777c Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 19:45:39 +0900 Subject: [PATCH 09/13] =?UTF-8?q?refactor:=20boolean=20->=20CheckAttractio?= =?UTF-8?q?nPoint=20=EB=A1=9C=20=EB=B0=98=ED=99=98=EA=B0=92=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../attractionPoint/service/AttractionPointService.java | 2 +- .../service/AttractionPointServiceImpl.java | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java index 18de7dc0..55b37730 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointService.java @@ -12,7 +12,7 @@ public interface AttractionPointService { void save(Long memberId, AttractionPointReq req); //입덕 포인트 평가 여부 - boolean checkAttractionPoint(Long memberId, Long animeId); + CheckAttractionPoint checkAttractionPoint(Long memberId, Long animeId); //입덕포인트 조회(true/false) IsAttractionPoint isAttractionPoint(Long memberId, Long animeId); diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java index 54992b2f..38486858 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java @@ -58,7 +58,7 @@ public IsAttractionPoint isAttractionPoint(Long memberId, Long animeId) { @Override @Transactional public void save(Long memberId, AttractionPointReq req) { - if(!checkAttractionPoint(memberId, req.getAnimeId())){ + if(checkAttractionPoint(memberId, req.getAnimeId()).getIsAttractionPoint()){ throw new BadRequestException("AttractionPoint is already exists."); } @@ -81,8 +81,11 @@ public void save(Long memberId, AttractionPointReq req) { } @Override - public boolean checkAttractionPoint(Long memberId, Long animeId) { + public CheckAttractionPoint checkAttractionPoint(Long memberId, Long animeId) { List findPoint = attractionPointRepository.findAllByAnimeIdAndMemberId(memberId, animeId); - return findPoint.isEmpty(); + return CheckAttractionPoint + .builder() + .isAttractionPoint(!findPoint.isEmpty()) + .build(); } } From 55240cb0faf2208cede5c265e5ea8eb55997b865 Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 19:46:07 +0900 Subject: [PATCH 10/13] =?UTF-8?q?test:=20=EC=9E=85=EB=8D=95=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=A1=B4=EC=9E=AC=20=EC=9C=A0=EB=AC=B4=20?= =?UTF-8?q?test=20=EC=B6=94=EA=B0=80=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AttractionPointControllerTest.java | 48 +++++- .../AttractionPointRepositoryTest.java | 139 ++++++++++++------ 2 files changed, 139 insertions(+), 48 deletions(-) diff --git a/src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java b/src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java index 08673c40..b2956fad 100644 --- a/src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java +++ b/src/test/java/io/oduck/api/e2e/attractionPoint/AttractionPointControllerTest.java @@ -31,11 +31,13 @@ import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; 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.restdocs.operation.preprocess.Preprocessors.*; import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.restdocs.snippet.Attributes.attributes; import static org.springframework.restdocs.snippet.Attributes.key; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -109,6 +111,48 @@ void postAttractionPoint() throws Exception { )) ); } + + } + + @Nested + @DisplayName("입덕포인트 존재 유무") + class GetAttractionPoint { + + @Test + @DisplayName("입덕포인트 존재 시 false") + @WithCustomMockMember(id = 2L, email = "john", password = "Qwer!234", role = Role.MEMBER) + void checkAttractionPoint() throws Exception{ + //given + Long animeId = 1L; + + //when + ResultActions actions = mockMvc.perform( + get(BASE_URL + "/{animeId}", animeId) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.COOKIE, "oDuckio.sid={SESSION_VALUE}") + ); + //then + actions.andExpect(status().isOk()) + .andDo(document("checkAttractionPoint/isCheck", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(HttpHeaders.COOKIE) + .attributes(field("constraints", "oDuckio.sid={SESSION_VALUE}")) + .description("Header Cookie, 세션 쿠키") + ), + pathParameters( + parameterWithName("animeId") + .description("애니 고유 식별자") + ), + responseFields( + fieldWithPath("isAttractionPoint") + .type(JsonFieldType.BOOLEAN) + .description("입덕포인트 존재 시 true, 부재 시 false")) + )); + + } } } \ No newline at end of file diff --git a/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java b/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java index bd7251ff..fb9e7616 100644 --- a/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java +++ b/src/test/java/io/oduck/api/unit/attractionPoint/repository/AttractionPointRepositoryTest.java @@ -104,56 +104,103 @@ void isAttractionPoint() { assertThat(findStory).isEqualTo(saveStory.getAttractionElement()); } } - @Nested - @DisplayName("애니 입덕 포인트 생성") - class PostAttractionPoint{ - - @Test - @DisplayName("입덕포인트 추가 성공 시 status 200 반환") - void saveAttractionPoint(){ - //given - - //회원 생성 - Long memberId = 1L; - Member member = Member.builder() - .id(memberId) - .build(); - - // 애니 생성 - Anime anime = animeRepository.saveAndFlush(createAnime()); - memberRepository.save(member); - - List find = attractionPointRepository.findAllByAnimeIdAndMemberId(memberId, anime.getId()); - - //입덕포인트 등록 - AttractionPoint drawing = AttractionPoint - .builder() - .member(member) - .anime(anime) - .attractionElement(AttractionElement.DRAWING) - .build(); - AttractionPoint story = AttractionPoint - .builder() - .member(member) - .anime(anime) - .attractionElement(AttractionElement.STORY) - .build(); - - //when - AttractionPoint saveDrawing = attractionPointRepository.save(drawing); - AttractionPoint saveStory = attractionPointRepository.save(story); - - //then - assertNotNull(anime); - assertNotNull(member); - assertTrue(find.isEmpty()); - assertThat(saveDrawing.getAttractionElement()).isEqualTo(drawing.getAttractionElement()); - assertThat(saveStory.getAttractionElement()).isEqualTo(story.getAttractionElement()); - } + @Nested + @DisplayName("입덕 포인트 생성") + class PostAttractionPoint{ + + @Test + @DisplayName("입덕포인트 추가 성공 시 status 200 반환") + void saveAttractionPoint(){ + //given + + //회원 생성 + Long memberId = 1L; + Member member = Member.builder() + .id(memberId) + .build(); + + // 애니 생성 + Anime anime = animeRepository.saveAndFlush(createAnime()); + memberRepository.save(member); + + List find = attractionPointRepository.findAllByAnimeIdAndMemberId(memberId, anime.getId()); + + //입덕포인트 등록 + AttractionPoint drawing = AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(AttractionElement.DRAWING) + .build(); + AttractionPoint story = AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(AttractionElement.STORY) + .build(); + + //when + AttractionPoint saveDrawing = attractionPointRepository.save(drawing); + AttractionPoint saveStory = attractionPointRepository.save(story); + + //then + assertNotNull(anime); + assertNotNull(member); + assertTrue(find.isEmpty()); + assertThat(saveDrawing.getAttractionElement()).isEqualTo(drawing.getAttractionElement()); + assertThat(saveStory.getAttractionElement()).isEqualTo(story.getAttractionElement()); + } } + @Nested + @DisplayName("입덕 포인트 존재 유무") + class GetAttractionPoint { + @Test + @DisplayName("입덕포인트 존재 시 true, 부재 시 false") + void checkAttractionPoint() { + //given + + //회원 생성 + Long memberId = 1L; + Member member = Member.builder() + .id(memberId) + .build(); + + // 애니 생성 + Anime anime = animeRepository.saveAndFlush(createAnime()); + memberRepository.save(member); + + List find = attractionPointRepository.findAllByAnimeIdAndMemberId(memberId, anime.getId()); + + //입덕포인트 등록 + AttractionPoint drawing = AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(AttractionElement.DRAWING) + .build(); + AttractionPoint story = AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(AttractionElement.STORY) + .build(); + + //when + AttractionPoint saveDrawing = attractionPointRepository.save(drawing); + AttractionPoint saveStory = attractionPointRepository.save(story); + + //then + assertNotNull(anime); + assertNotNull(member); + assertTrue(find.isEmpty()); + assertThat(saveDrawing.getAttractionElement()).isEqualTo(drawing.getAttractionElement()); + assertThat(saveStory.getAttractionElement()).isEqualTo(story.getAttractionElement()); + } + + } } From 5f23ae78331b0da88c0a469482214a561c6bafeb Mon Sep 17 00:00:00 2001 From: hanyMK Date: Thu, 16 Nov 2023 19:47:11 +0900 Subject: [PATCH 11/13] =?UTF-8?q?docs:=20=EC=9E=85=EB=8D=95=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=9E=85?= =?UTF-8?q?=EB=8D=95=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=A1=B4=EC=9E=AC=20?= =?UTF-8?q?=EC=9C=A0=EB=AC=B4=20api=EB=AC=B8=EC=84=9C=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/index.adoc | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index 499b35b9..562ccd6b 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -1498,3 +1498,53 @@ include::{snippets}/starRating/patchScore/success/http-response.adoc[] ==== 실패시 .http-response include::{snippets}/starRating/patchScore/failure/http-response.adoc[] + + +== AttractionPoint +=== POST api/v1/attraction-points +.curl-request +include::{snippets}/postAttractionPoint/success/curl-request.adoc[] + +.http-request +include::{snippets}/postAttractionPoint/success/http-request.adoc[] + +.request-header +include::{snippets}/postAttractionPoint/success/request-headers.adoc[] + +.request-body +include::{snippets}/postAttractionPoint/success/request-body.adoc[] + +.request-fields +include::{snippets}/postAttractionPoint/success/request-fields.adoc[] + +==== 저장 성공시 +.http-response +include::{snippets}/likes/shortReview/save/success/http-response.adoc[] + +==== 삭제 성공시 +.http-response +include::{snippets}/likes/shortReview/delete/success/http-response.adoc[] + +== 입덕포인트 존재 여부 +=== GET api/v1/attraction-points/:animeId +.curl-request +include::{snippets}/checkAttractionPoint/isCheck/curl-request.adoc[] + +.http-request +include::{snippets}/checkAttractionPoint/isCheck/http-request.adoc[] + +.path-parameters +include::{snippets}/checkAttractionPoint/isCheck/path-parameters.adoc[] + +.request-header +include::{snippets}/checkAttractionPoint/isCheck/request-headers.adoc[] + +=== 짧은 리뷰 좋아요 존재 여부 +.http-response +include::{snippets}/checkAttractionPoint/isCheck/http-response.adoc[] + +.response-body +include::{snippets}/checkAttractionPoint/isCheck/response-body.adoc[] + +.response-fields +include::{snippets}/checkAttractionPoint/isCheck/response-fields.adoc[] From dee5682cae78bf007d4e17cba6f5acbbb941eba0 Mon Sep 17 00:00:00 2001 From: hanyMK Date: Sat, 18 Nov 2023 01:32:09 +0900 Subject: [PATCH 12/13] =?UTF-8?q?refactor:=20ConflictException,=20for?= =?UTF-8?q?=EB=AC=B8=20stream=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD,=20?= =?UTF-8?q?=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AttractionPointServiceImpl.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java index 38486858..09f78ffb 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java @@ -6,12 +6,12 @@ import io.oduck.api.domain.attractionPoint.dto.AttractionPointResDto.*; import io.oduck.api.domain.attractionPoint.entity.AttractionPoint; import io.oduck.api.domain.attractionPoint.repository.AttractionPointRepository; + import java.util.List; -import java.util.Optional; import io.oduck.api.domain.member.entity.Member; import io.oduck.api.domain.member.repository.MemberRepository; -import io.oduck.api.global.exception.BadRequestException; +import io.oduck.api.global.exception.ConflictException; import io.oduck.api.global.exception.NotFoundException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -59,7 +59,7 @@ public IsAttractionPoint isAttractionPoint(Long memberId, Long animeId) { @Transactional public void save(Long memberId, AttractionPointReq req) { if(checkAttractionPoint(memberId, req.getAnimeId()).getIsAttractionPoint()){ - throw new BadRequestException("AttractionPoint is already exists."); + throw new ConflictException("AttractionPoint"); } Member member = memberRepository.findById(memberId) @@ -68,16 +68,16 @@ public void save(Long memberId, AttractionPointReq req) { Anime anime = animeRepository.findById(req.getAnimeId()) .orElseThrow(() -> new NotFoundException("Anime")); + req.getAttractionElements() + .stream() + .map(attractionElement -> AttractionPoint + .builder() + .member(member) + .anime(anime) + .attractionElement(attractionElement) + .build()) + .forEach(attractionPointRepository::save); - for(int i = 0; i < req.getAttractionElements().size(); i++){ - AttractionPoint attractionPoint = AttractionPoint - .builder() - .member(member) - .anime(anime) - .attractionElement(req.getAttractionElements().get(i)) - .build(); - attractionPointRepository.save(attractionPoint); - } } @Override From 26f106468e68a9a6379e48ec24b09317f44071b9 Mon Sep 17 00:00:00 2001 From: hanyMK Date: Sun, 19 Nov 2023 18:01:24 +0900 Subject: [PATCH 13/13] =?UTF-8?q?refactor:=20saveAll=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=98=EC=97=AC=20=EC=A0=80=EC=9E=A5=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AttractionPointServiceImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java index 09f78ffb..251bde25 100644 --- a/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java +++ b/src/main/java/io/oduck/api/domain/attractionPoint/service/AttractionPointServiceImpl.java @@ -7,7 +7,9 @@ import io.oduck.api.domain.attractionPoint.entity.AttractionPoint; import io.oduck.api.domain.attractionPoint.repository.AttractionPointRepository; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import io.oduck.api.domain.member.entity.Member; import io.oduck.api.domain.member.repository.MemberRepository; @@ -68,7 +70,7 @@ public void save(Long memberId, AttractionPointReq req) { Anime anime = animeRepository.findById(req.getAnimeId()) .orElseThrow(() -> new NotFoundException("Anime")); - req.getAttractionElements() + List points = req.getAttractionElements() .stream() .map(attractionElement -> AttractionPoint .builder() @@ -76,8 +78,8 @@ public void save(Long memberId, AttractionPointReq req) { .anime(anime) .attractionElement(attractionElement) .build()) - .forEach(attractionPointRepository::save); - + .toList(); + attractionPointRepository.saveAll(points); } @Override