From 8646b1ab6ca01c586fd34f598e593576e72610bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=ED=8C=8D=28junpak=29?= <112045553+junpakPark@users.noreply.github.com> Date: Tue, 18 Jul 2023 13:49:45 +0900 Subject: [PATCH 01/22] =?UTF-8?q?[Docs]=20GitHub=20Issue=20=EB=B0=8F=20PR?= =?UTF-8?q?=20Template=20=EC=84=A4=EC=A0=95=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: .gitignore 추가 * chore: GitHub PR 및 Issue Template * Revert "chore: GitHub PR 및 Issue Template" This reverts commit 65915f72740bbf22899ef7ac52fefa99cde96a8b. * Revert "chore: .gitignore 추가" This reverts commit 1e1865a1cb7f0a279b4e74c12cd0f66631809ff3. * chore: .gitignore 추가 * chore: GitHub Issue 및 PR Template 추가 --- .github/ISSUE_TEMPLATE/bug.yml | 44 ++++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/deploy.yml | 28 ++++++++++++++++++ .github/ISSUE_TEMPLATE/env.yml | 28 ++++++++++++++++++ .github/ISSUE_TEMPLATE/feat.yml | 28 ++++++++++++++++++ .github/ISSUE_TEMPLATE/meeting.yml | 36 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/refactor.yml | 28 ++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 21 +++++++++++++ .gitignore | 41 ++++++++++++++++++++++++++ 8 files changed, 254 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug.yml create mode 100644 .github/ISSUE_TEMPLATE/deploy.yml create mode 100644 .github/ISSUE_TEMPLATE/env.yml create mode 100644 .github/ISSUE_TEMPLATE/feat.yml create mode 100644 .github/ISSUE_TEMPLATE/meeting.yml create mode 100644 .github/ISSUE_TEMPLATE/refactor.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .gitignore diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 00000000..ba8e6088 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,44 @@ +name: "bug" +description: "버그 발생 시" +labels: "bug" +body: + - type: textarea + attributes: + label: 🐞버그 설명 + description: 버그에 대한 설명을 작성해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: 📄 버그 로그 + description: 로그가 있으면 입력해 주세요. + render: shell + validations: + required: false + - type: textarea + attributes: + label: 🌏 버그 발생 환경 + description: 버그가 발생한 환경에 대해 작성해 주세요. + placeholder: | + OS: macOS + validations: + required: true + - type: textarea + attributes: + label: ✅ 버그 재현 방법 + description: Given-When-Then 형식으로 버그를 재현할 수 있는 방법에 대해 작성해 주세요. + validations: + required: false + - type: textarea + attributes: + label: 📎 참고 자료 + description: 발생한 버그에 대한 참고 자료가 있다면 작성해 주세요. + validations: + required: false + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 버그를 해결하기 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/deploy.yml b/.github/ISSUE_TEMPLATE/deploy.yml new file mode 100644 index 00000000..778c6237 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/deploy.yml @@ -0,0 +1,28 @@ +name: "deploy" +description: "배포 시" +labels: "deploy" +body: + - type: textarea + attributes: + label: 📄 작업 설명 + description: 배포에 대한 설명을 작성해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: ✅ 작업 내용 + description: 배포에 대한 Tasks를 작성해 주세요. + placeholder: 최대한 세분화 해서 적어주세요! + validations: + required: true + - type: textarea + attributes: + label: 📎 참고 자료 + description: 배포에 대한 참고 자료가 있다면 작성해 주세요. + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 배포를 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/env.yml b/.github/ISSUE_TEMPLATE/env.yml new file mode 100644 index 00000000..af06b0b4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/env.yml @@ -0,0 +1,28 @@ +name: "env" +description: "환경 설정 시" +labels: "env" +body: + - type: textarea + attributes: + label: 📄 작업 대상 + description: 작업할 환경 설정에 대해 설명해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: ✅ 작업할 내용 + description: 환경 설정에 대한 Tasks를 작성해주세요. + placeholder: 최대한 세분화 해서 적어주세요! + validations: + required: true + - type: textarea + attributes: + label: 📎 참고 자료 + description: 환경 설정에 대한 참고 자료가 있다면 작성해 주세요. + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 환경설정을 추가하기 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/feat.yml b/.github/ISSUE_TEMPLATE/feat.yml new file mode 100644 index 00000000..5abde374 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feat.yml @@ -0,0 +1,28 @@ +name: "feat" +description: "기능 추가 시" +labels: "feat" +body: + - type: textarea + attributes: + label: 📄 작업 대상 + description: 작업할 기능에 대한 설명을 작성해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: ✅ 작업 내용 + description: 기능 구현에 대한 Tasks를 작성해 주세요. + placeholder: 최대한 세분화 해서 적어주세요! + validations: + required: true + - type: textarea + attributes: + label: 📎 참고 자료 + description: 새로운 기능에 대한 참고 자료가 있다면 URL을 작성해 주세요. + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 새로운 기능을 추가하기 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/meeting.yml b/.github/ISSUE_TEMPLATE/meeting.yml new file mode 100644 index 00000000..d07e0f30 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/meeting.yml @@ -0,0 +1,36 @@ +name: "meeting" +description: "회의 시" +labels: "meeting" +body: + - type: textarea + attributes: + label: 📝 설명 + description: 회의 주제에 대한 설명을 작성해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: 🙋🏻 참가 인원 + validations: + required: true + description: 회의에 참여할 인원 및 역할(진행자, 서기)을 작성해 주세요. + - type: textarea + attributes: + label: ⏰ 회의 시간 + validations: + required: true + description: 회의 날짜와 시간을 입력해 주세요. + - type: textarea + attributes: + label: ✅ 회의 안건 + description: 해야 하는 일에 대한 Tasks를 작성해 주세요. + placeholder: 최대한 세분화 해서 적어 주세요! + validations: + required: true + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 회의를 진행하는데 필요한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/refactor.yml b/.github/ISSUE_TEMPLATE/refactor.yml new file mode 100644 index 00000000..ae5d0d05 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/refactor.yml @@ -0,0 +1,28 @@ +name: "refactor" +description: "리팩터링 시" +labels: "refactor" +body: + - type: textarea + attributes: + label: 🛠️ 작업 대상 + description: 리팩터링에 해야할 범위를 설명해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: ✅ 작업 내용 + description: 리팩터링을 할 부분에 대한 Tasks를 작성해 주세요. + placeholder: 최대한 세분화 해서 적어주세요! + validations: + required: true + - type: textarea + attributes: + label: 📎 참고 자료 + description: 리팩터링에 대한 참고 자료가 있다면 작성해 주세요. + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 리펙토링을 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..3f5b9136 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,21 @@ + + +## 작업 대상 + + +## 📄 작업 내용 + + +## 🙋🏻 주의 사항 + + +## 스크린샷 + + +## 📎 관련 이슈 + + + + +## 레퍼런스 + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..8ccd3c55 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +node_modules/ + +dist/ From 5b153cc49d884ad80e672ec9f98b4e03b0c8e9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=ED=8C=8D=28junpak=29?= <112045553+junpakPark@users.noreply.github.com> Date: Tue, 18 Jul 2023 13:56:16 +0900 Subject: [PATCH 02/22] =?UTF-8?q?[Docs]=20GitHub=20Issue=20Template=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(#39)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: .gitignore 추가 * chore: GitHub PR 및 Issue Template * Revert "chore: GitHub PR 및 Issue Template" This reverts commit 65915f72740bbf22899ef7ac52fefa99cde96a8b. * Revert "chore: .gitignore 추가" This reverts commit 1e1865a1cb7f0a279b4e74c12cd0f66631809ff3. * chore: .gitignore 추가 * chore: GitHub Issue 및 PR Template 추가 * chore: GitHub Issue 및 PR Template 추가 --- .github/ISSUE_TEMPLATE/bug.yml | 44 +++++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/deploy.yml | 28 ++++++++++++++++++ .github/ISSUE_TEMPLATE/refactor.yml | 28 ++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug.yml create mode 100644 .github/ISSUE_TEMPLATE/deploy.yml create mode 100644 .github/ISSUE_TEMPLATE/refactor.yml diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 00000000..ba8e6088 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,44 @@ +name: "bug" +description: "버그 발생 시" +labels: "bug" +body: + - type: textarea + attributes: + label: 🐞버그 설명 + description: 버그에 대한 설명을 작성해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: 📄 버그 로그 + description: 로그가 있으면 입력해 주세요. + render: shell + validations: + required: false + - type: textarea + attributes: + label: 🌏 버그 발생 환경 + description: 버그가 발생한 환경에 대해 작성해 주세요. + placeholder: | + OS: macOS + validations: + required: true + - type: textarea + attributes: + label: ✅ 버그 재현 방법 + description: Given-When-Then 형식으로 버그를 재현할 수 있는 방법에 대해 작성해 주세요. + validations: + required: false + - type: textarea + attributes: + label: 📎 참고 자료 + description: 발생한 버그에 대한 참고 자료가 있다면 작성해 주세요. + validations: + required: false + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 버그를 해결하기 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/deploy.yml b/.github/ISSUE_TEMPLATE/deploy.yml new file mode 100644 index 00000000..778c6237 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/deploy.yml @@ -0,0 +1,28 @@ +name: "deploy" +description: "배포 시" +labels: "deploy" +body: + - type: textarea + attributes: + label: 📄 작업 설명 + description: 배포에 대한 설명을 작성해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: ✅ 작업 내용 + description: 배포에 대한 Tasks를 작성해 주세요. + placeholder: 최대한 세분화 해서 적어주세요! + validations: + required: true + - type: textarea + attributes: + label: 📎 참고 자료 + description: 배포에 대한 참고 자료가 있다면 작성해 주세요. + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 배포를 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/refactor.yml b/.github/ISSUE_TEMPLATE/refactor.yml new file mode 100644 index 00000000..ae5d0d05 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/refactor.yml @@ -0,0 +1,28 @@ +name: "refactor" +description: "리팩터링 시" +labels: "refactor" +body: + - type: textarea + attributes: + label: 🛠️ 작업 대상 + description: 리팩터링에 해야할 범위를 설명해 주세요. + placeholder: 자세히 적을수록 좋습니다! + validations: + required: true + - type: textarea + attributes: + label: ✅ 작업 내용 + description: 리팩터링을 할 부분에 대한 Tasks를 작성해 주세요. + placeholder: 최대한 세분화 해서 적어주세요! + validations: + required: true + - type: textarea + attributes: + label: 📎 참고 자료 + description: 리팩터링에 대한 참고 자료가 있다면 작성해 주세요. + - type: textarea + attributes: + label: ⏰ 추정 시간 + description: 리펙토링을 위한 추정 시간(비관적 추정, 낙관적 추정)에 대해 작성해주세요. + validations: + required: true From e9d70171e34054d702c71e94d210d5d76a855862 Mon Sep 17 00:00:00 2001 From: junpakPark Date: Wed, 9 Aug 2023 22:23:15 +0900 Subject: [PATCH 03/22] =?UTF-8?q?feat:=20=EB=AA=A8=EC=95=84=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/AtlasCommandService.java | 73 +++++++++++++++++++ .../atlas/application/AtlasQueryService.java | 30 ++++++++ .../mapbefine/atlas/domain/Atlas.java | 50 +++++++++++++ .../atlas/domain/AtlasRepository.java | 15 ++++ .../atlas/presentation/AtlasController.java | 53 ++++++++++++++ 5 files changed, 221 insertions(+) create mode 100644 backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java create mode 100644 backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java create mode 100644 backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/Atlas.java create mode 100644 backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/AtlasRepository.java create mode 100644 backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java new file mode 100644 index 00000000..8103740a --- /dev/null +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java @@ -0,0 +1,73 @@ +package com.mapbefine.mapbefine.atlas.application; + +import com.mapbefine.mapbefine.atlas.domain.Atlas; +import com.mapbefine.mapbefine.atlas.domain.AtlasRepository; +import com.mapbefine.mapbefine.auth.domain.AuthMember; +import com.mapbefine.mapbefine.member.domain.Member; +import com.mapbefine.mapbefine.member.domain.MemberRepository; +import com.mapbefine.mapbefine.topic.domain.Topic; +import com.mapbefine.mapbefine.topic.domain.TopicRepository; +import java.util.NoSuchElementException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class AtlasCommandService { + + private final TopicRepository topicRepository; + private final MemberRepository memberRepository; + private final AtlasRepository atlasRepository; + + public AtlasCommandService( + TopicRepository topicRepository, + MemberRepository memberRepository, + AtlasRepository atlasRepository + ) { + this.topicRepository = topicRepository; + this.memberRepository = memberRepository; + this.atlasRepository = atlasRepository; + } + + public void addTopic(AuthMember authMember, Long topicId) { + Long memberId = authMember.getMemberId(); + + if (isTopicAlreadyAdded(topicId, memberId)) { + return; + } + + Topic topic = findTopicById(topicId); + validateReadPermission(authMember, topic); + + Member member = findMemberById(memberId); + + Atlas atlas = Atlas.from(topic, member); + atlasRepository.save(atlas); + } + + private boolean isTopicAlreadyAdded(Long topicId, Long memberId) { + return atlasRepository.existsByMemberIdAndTopicId(memberId, topicId); + } + + private Member findMemberById(Long memberId) { + return memberRepository.findById(memberId) + .orElseThrow(NoSuchElementException::new); + } + + private Topic findTopicById(Long topicId) { + return topicRepository.findById(topicId) + .orElseThrow(NoSuchElementException::new); + } + + private void validateReadPermission(AuthMember authMember, Topic topic) { + if (authMember.canRead(topic)) { + return; + } + throw new IllegalArgumentException("해당 지도에 접근권한이 없습니다."); + } + + public void removeTopic(AuthMember authMember, Long topicId) { + atlasRepository.deleteByMemberIdAndTopicId(authMember.getMemberId(), topicId); + } + +} diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java new file mode 100644 index 00000000..7e8a4b90 --- /dev/null +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java @@ -0,0 +1,30 @@ +package com.mapbefine.mapbefine.atlas.application; + +import com.mapbefine.mapbefine.atlas.domain.Atlas; +import com.mapbefine.mapbefine.atlas.domain.AtlasRepository; +import com.mapbefine.mapbefine.auth.domain.AuthMember; +import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; +import java.util.List; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +public class AtlasQueryService { + + private final AtlasRepository atlasRepository; + + public AtlasQueryService(AtlasRepository atlasRepository) { + this.atlasRepository = atlasRepository; + } + + public List findAtlasByMember(AuthMember member) { + return atlasRepository.findAllByMemberId(member.getMemberId()) + .stream() + .map(Atlas::getTopic) + .filter(member::canRead) + .map(TopicResponse::from) + .toList(); + } + +} diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/Atlas.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/Atlas.java new file mode 100644 index 00000000..a47b5156 --- /dev/null +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/Atlas.java @@ -0,0 +1,50 @@ +package com.mapbefine.mapbefine.atlas.domain; + +import static lombok.AccessLevel.PROTECTED; + +import com.mapbefine.mapbefine.member.domain.Member; +import com.mapbefine.mapbefine.topic.domain.Topic; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import java.util.Objects; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = PROTECTED) +@Getter +public class Atlas { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "topic_id", nullable = false) + private Topic topic; + + @ManyToOne + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + private Atlas(Topic topic, Member member) { + this.topic = topic; + this.member = member; + } + + public static Atlas from(Topic topic, Member member) { + validateNotNull(topic, member); + return new Atlas(topic, member); + } + + private static void validateNotNull(Topic topic, Member member) { + if (Objects.isNull(topic) || Objects.isNull(member)) { + throw new IllegalArgumentException("토픽과 멤버는 Null이어선 안됩니다."); + } + } + +} diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/AtlasRepository.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/AtlasRepository.java new file mode 100644 index 00000000..6a0c8570 --- /dev/null +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/domain/AtlasRepository.java @@ -0,0 +1,15 @@ +package com.mapbefine.mapbefine.atlas.domain; + +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AtlasRepository extends JpaRepository { + + List findAllByMemberId(Long memberId); + + boolean existsByMemberIdAndTopicId(Long memberId, Long topicId); + + void deleteByMemberIdAndTopicId(Long memberId, Long topicId); +} diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java new file mode 100644 index 00000000..f3eb6722 --- /dev/null +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java @@ -0,0 +1,53 @@ +package com.mapbefine.mapbefine.atlas.presentation; + +import com.mapbefine.mapbefine.atlas.application.AtlasCommandService; +import com.mapbefine.mapbefine.atlas.application.AtlasQueryService; +import com.mapbefine.mapbefine.auth.domain.AuthMember; +import com.mapbefine.mapbefine.common.interceptor.LoginRequired; +import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; +import java.util.List; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/atlantes") +public class AtlasController { + + private AtlasCommandService atlasCommandService; + private AtlasQueryService atlasQueryService; + + public AtlasController(AtlasCommandService atlasCommandService, AtlasQueryService atlasQueryService) { + this.atlasCommandService = atlasCommandService; + this.atlasQueryService = atlasQueryService; + } + + @LoginRequired + @GetMapping + public ResponseEntity> showTopics(AuthMember member) { + List topicResponses = atlasQueryService.findAtlasByMember(member); + + return ResponseEntity.ok(topicResponses); + } + + @LoginRequired + @PostMapping("/{topicId}") + public ResponseEntity addTopic(AuthMember authMember, @PathVariable Long topicId) { + atlasCommandService.addTopic(authMember, topicId); + + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + @LoginRequired + @DeleteMapping("/{topicId}") + public ResponseEntity removeAtlas(AuthMember authMember, @PathVariable Long topicId) { + atlasCommandService.removeTopic(authMember, topicId); + + return ResponseEntity.noContent().build(); + } +} From 1de1b01ad53b60a41fd39ec6a54eed38ff8bcd78 Mon Sep 17 00:00:00 2001 From: junpakPark <112045553+junpakPark@users.noreply.github.com> Date: Thu, 10 Aug 2023 14:48:09 +0900 Subject: [PATCH 04/22] =?UTF-8?q?refactor:=20controller=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20final=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapbefine/atlas/presentation/AtlasController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java index f3eb6722..5aafae81 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java @@ -19,8 +19,8 @@ @RequestMapping("/atlantes") public class AtlasController { - private AtlasCommandService atlasCommandService; - private AtlasQueryService atlasQueryService; + private final AtlasCommandService atlasCommandService; + private final AtlasQueryService atlasQueryService; public AtlasController(AtlasCommandService atlasCommandService, AtlasQueryService atlasQueryService) { this.atlasCommandService = atlasCommandService; From 62ba5f1e1885aaa7a3850964a22ac0310c516b38 Mon Sep 17 00:00:00 2001 From: junpakPark <112045553+junpakPark@users.noreply.github.com> Date: Thu, 10 Aug 2023 17:15:45 +0900 Subject: [PATCH 05/22] =?UTF-8?q?refactor:=20URI=20=EB=B0=8F=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../atlas/application/AtlasQueryService.java | 2 +- .../mapbefine/atlas/presentation/AtlasController.java | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java index 7e8a4b90..91e46ed3 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryService.java @@ -18,7 +18,7 @@ public AtlasQueryService(AtlasRepository atlasRepository) { this.atlasRepository = atlasRepository; } - public List findAtlasByMember(AuthMember member) { + public List findTopicsByMember(AuthMember member) { return atlasRepository.findAllByMemberId(member.getMemberId()) .stream() .map(Atlas::getTopic) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java index 5aafae81..0032f17d 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/presentation/AtlasController.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/atlantes") +@RequestMapping("/atlas") public class AtlasController { private final AtlasCommandService atlasCommandService; @@ -29,15 +29,15 @@ public AtlasController(AtlasCommandService atlasCommandService, AtlasQueryServic @LoginRequired @GetMapping - public ResponseEntity> showTopics(AuthMember member) { - List topicResponses = atlasQueryService.findAtlasByMember(member); + public ResponseEntity> findTopicsFromAtlas(AuthMember member) { + List topicResponses = atlasQueryService.findTopicsByMember(member); return ResponseEntity.ok(topicResponses); } @LoginRequired @PostMapping("/{topicId}") - public ResponseEntity addTopic(AuthMember authMember, @PathVariable Long topicId) { + public ResponseEntity addTopicToAtlas(AuthMember authMember, @PathVariable Long topicId) { atlasCommandService.addTopic(authMember, topicId); return ResponseEntity.status(HttpStatus.CREATED).build(); @@ -45,9 +45,10 @@ public ResponseEntity addTopic(AuthMember authMember, @PathVariable Long t @LoginRequired @DeleteMapping("/{topicId}") - public ResponseEntity removeAtlas(AuthMember authMember, @PathVariable Long topicId) { + public ResponseEntity removeTopicFromAtlas(AuthMember authMember, @PathVariable Long topicId) { atlasCommandService.removeTopic(authMember, topicId); return ResponseEntity.noContent().build(); } + } From 10df87611012a41ec05eb602e33d0c18ef5ee73e Mon Sep 17 00:00:00 2001 From: junpakPark <112045553+junpakPark@users.noreply.github.com> Date: Thu, 10 Aug 2023 17:17:44 +0900 Subject: [PATCH 06/22] =?UTF-8?q?test:=20atlas=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/AtlasCommandService.java | 1 + .../mapbefine/atlas/AtlasIntegrationTest.java | 104 +++++++++++++++ .../application/AtlasCommandServiceTest.java | 118 ++++++++++++++++++ .../application/AtlasQueryServiceTest.java | 68 ++++++++++ .../mapbefine/atlas/domain/AtlasTest.java | 58 +++++++++ .../presentation/AtlasControllerTest.java | 77 ++++++++++++ 6 files changed, 426 insertions(+) create mode 100644 backend/src/test/java/com/mapbefine/mapbefine/atlas/AtlasIntegrationTest.java create mode 100644 backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandServiceTest.java create mode 100644 backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryServiceTest.java create mode 100644 backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java create mode 100644 backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java diff --git a/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java index 8103740a..aaa30c02 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandService.java @@ -32,6 +32,7 @@ public AtlasCommandService( public void addTopic(AuthMember authMember, Long topicId) { Long memberId = authMember.getMemberId(); + // TODO: 2023/08/10 memberId가 없는 경우 터짐 (Guest인 경우) (단, loginRequired로 일차적으로 막아놓긴 함) if (isTopicAlreadyAdded(topicId, memberId)) { return; } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/atlas/AtlasIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/atlas/AtlasIntegrationTest.java new file mode 100644 index 00000000..12e4a6d5 --- /dev/null +++ b/backend/src/test/java/com/mapbefine/mapbefine/atlas/AtlasIntegrationTest.java @@ -0,0 +1,104 @@ +package com.mapbefine.mapbefine.atlas; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; + +import com.mapbefine.mapbefine.atlas.domain.Atlas; +import com.mapbefine.mapbefine.atlas.domain.AtlasRepository; +import com.mapbefine.mapbefine.common.IntegrationTest; +import com.mapbefine.mapbefine.member.MemberFixture; +import com.mapbefine.mapbefine.member.domain.Member; +import com.mapbefine.mapbefine.member.domain.MemberRepository; +import com.mapbefine.mapbefine.member.domain.Role; +import com.mapbefine.mapbefine.topic.TopicFixture; +import com.mapbefine.mapbefine.topic.domain.Topic; +import com.mapbefine.mapbefine.topic.domain.TopicRepository; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.apache.tomcat.util.codec.binary.Base64; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; + +public class AtlasIntegrationTest extends IntegrationTest { + + @Autowired + TopicRepository topicRepository; + + @Autowired + MemberRepository memberRepository; + + @Autowired + AtlasRepository atlasRepository; + + private Member member; + private Topic topic; + private String authHeader; + + @BeforeEach + void setMember() { + member = memberRepository.save( + MemberFixture.create("other", "other@othter.com", Role.USER) + ); + topic = topicRepository.save(TopicFixture.createPublicAndAllMembersTopic(member)); + authHeader = Base64.encodeBase64String( + ("Basic " + member.getMemberInfo().getEmail()).getBytes() + ); + } + + @Test + @DisplayName("모아보기에 추가되어있는 지도 목록을 조회한다") + void findTopicsFromAtlas_Success() { + // when + ExtractableResponse response = RestAssured.given() + .log().all() + .header(AUTHORIZATION, authHeader) + .when().get("/atlas") + .then().log().all() + .extract(); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + @Test + @DisplayName("모아보기에 지도를 추가한다") + void addTopicToAtlas_Success() { + //given + Long topicId = topic.getId(); + + // when + ExtractableResponse response = RestAssured.given() + .log().all() + .header(AUTHORIZATION, authHeader) + .when().post("/atlas/{topicId}", topicId) + .then().log().all() + .extract(); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + } + + + @Test + @DisplayName("모아보기에 추가되어있는 지도를 삭제한다") + void removeTopicFromAtlas_Success() { + //given + Long topicId = topic.getId(); + atlasRepository.save(Atlas.from(topic, member)); + + // when + ExtractableResponse response = RestAssured.given() + .log().all() + .header(AUTHORIZATION, authHeader) + .when().delete("/atlas/{topicId}", topicId) + .then().log().all() + .extract(); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + } +} diff --git a/backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandServiceTest.java b/backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandServiceTest.java new file mode 100644 index 00000000..fa940fed --- /dev/null +++ b/backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasCommandServiceTest.java @@ -0,0 +1,118 @@ +package com.mapbefine.mapbefine.atlas.application; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.mapbefine.mapbefine.atlas.domain.Atlas; +import com.mapbefine.mapbefine.atlas.domain.AtlasRepository; +import com.mapbefine.mapbefine.auth.domain.AuthMember; +import com.mapbefine.mapbefine.auth.domain.member.Admin; +import com.mapbefine.mapbefine.auth.domain.member.User; +import com.mapbefine.mapbefine.member.MemberFixture; +import com.mapbefine.mapbefine.member.domain.Member; +import com.mapbefine.mapbefine.member.domain.MemberRepository; +import com.mapbefine.mapbefine.member.domain.Role; +import com.mapbefine.mapbefine.topic.TopicFixture; +import com.mapbefine.mapbefine.topic.domain.Topic; +import com.mapbefine.mapbefine.topic.domain.TopicRepository; +import java.util.Collections; +import java.util.List; +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.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class AtlasCommandServiceTest { + + @Autowired + private TopicRepository topicRepository; + + @Autowired + private MemberRepository memberRepository; + + @Autowired + private AtlasRepository atlasRepository; + + private AtlasCommandService atlasCommandService; + private AuthMember authMember; + private Topic topic; + + @BeforeEach + void setUp() { + atlasCommandService = new AtlasCommandService(topicRepository, memberRepository, atlasRepository); + Member member = memberRepository.save(MemberFixture.create("member", "member@naver.com", Role.ADMIN)); + topic = topicRepository.save(TopicFixture.createPrivateByName("topic", member)); + + authMember = new Admin(member.getId()); + } + + @Nested + @DisplayName("모아보기에 토픽을 더할 때,") + class addTopic { + + @Test + @DisplayName("정상적인 값이 입력되면 성공한다.") + void success() { + //when + atlasCommandService.addTopic(authMember, topic.getId()); + + //then + boolean isExisted = atlasRepository.existsByMemberIdAndTopicId(authMember.getMemberId(), topic.getId()); + assertThat(isExisted).isTrue(); + } + + @Test + @DisplayName("이미 입력된 값이면 새로 입력하지 않는다.") + void alreadyAdd_Fail() { + //given + atlasCommandService.addTopic(authMember, topic.getId()); + List expected = atlasRepository.findAllByMemberId(authMember.getMemberId()); + + //when + atlasCommandService.addTopic(authMember, topic.getId()); + List actual = atlasRepository.findAllByMemberId(authMember.getMemberId()); + + //then + assertThat(actual.size()).isEqualTo(expected.size()); + } + + @Test + @DisplayName("접근 권한이 없는 경우 예외가 발생한다") + void validateReadPermission_fail() { + //given + Member other = memberRepository.save( + MemberFixture.create("other", "other@othter.com", Role.USER) + ); + AuthMember otherAuthMember = new User(other.getId(), Collections.emptyList(), Collections.emptyList()); + + //when + //then + assertThatThrownBy(() -> atlasCommandService.addTopic(otherAuthMember, topic.getId())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("해당 지도에 접근권한이 없습니다."); + } + + } + + @Test + @DisplayName("") + void remove_Success() { + Long topicId = topic.getId(); + Long memberId = authMember.getMemberId(); + + //given + atlasCommandService.addTopic(authMember, topicId); + List expected = atlasRepository.findAllByMemberId(memberId); + + //when + atlasCommandService.removeTopic(authMember, topicId); + List actual = atlasRepository.findAllByMemberId(memberId); + + //then + assertThat(actual.size()).isEqualTo(expected.size() - 1); + } + +} diff --git a/backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryServiceTest.java b/backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryServiceTest.java new file mode 100644 index 00000000..764b0ecd --- /dev/null +++ b/backend/src/test/java/com/mapbefine/mapbefine/atlas/application/AtlasQueryServiceTest.java @@ -0,0 +1,68 @@ +package com.mapbefine.mapbefine.atlas.application; + +import com.mapbefine.mapbefine.atlas.domain.Atlas; +import com.mapbefine.mapbefine.atlas.domain.AtlasRepository; +import com.mapbefine.mapbefine.auth.domain.AuthMember; +import com.mapbefine.mapbefine.auth.domain.member.Admin; +import com.mapbefine.mapbefine.member.MemberFixture; +import com.mapbefine.mapbefine.member.domain.Member; +import com.mapbefine.mapbefine.member.domain.MemberRepository; +import com.mapbefine.mapbefine.member.domain.Role; +import com.mapbefine.mapbefine.topic.TopicFixture; +import com.mapbefine.mapbefine.topic.domain.Topic; +import com.mapbefine.mapbefine.topic.domain.TopicRepository; +import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class AtlasQueryServiceTest { + + @Autowired + private AtlasRepository atlasRepository; + + @Autowired + private MemberRepository memberRepository; + + @Autowired + private TopicRepository topicRepository; + + private AtlasQueryService atlasQueryService; + private AuthMember authMember; + private List topics; + + @BeforeEach + void setUp() { + atlasQueryService = new AtlasQueryService(atlasRepository); + + Member member = memberRepository.save(MemberFixture.create("member", "member@member.com", Role.ADMIN)); + authMember = new Admin(member.getId()); + + createTopics(member); + topics.forEach(topic -> atlasRepository.save(Atlas.from(topic, member))); + } + + private void createTopics(Member member) { + topics = List.of( + TopicFixture.createPublicAndAllMembersTopic(member), + TopicFixture.createPublicAndAllMembersTopic(member), + TopicFixture.createPublicAndAllMembersTopic(member) + ); + topicRepository.saveAll(topics); + } + + @Test + @DisplayName("멤버 ID를 이용해 모아보기할 모든 Topic들을 가져올 수 있다.") + void findAtlasByMember_Success() { + //when + List atlas = atlasQueryService.findTopicsByMember(authMember); + + //then + Assertions.assertThat(atlas.size()).isEqualTo(topics.size()); + } +} diff --git a/backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java b/backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java new file mode 100644 index 00000000..311b8098 --- /dev/null +++ b/backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java @@ -0,0 +1,58 @@ +package com.mapbefine.mapbefine.atlas.domain; + + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import com.mapbefine.mapbefine.member.MemberFixture; +import com.mapbefine.mapbefine.member.domain.Member; +import com.mapbefine.mapbefine.member.domain.Role; +import com.mapbefine.mapbefine.topic.TopicFixture; +import com.mapbefine.mapbefine.topic.domain.Topic; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class AtlasTest { + + private static final Member MEMBER = MemberFixture.create("member", "member@member.com", Role.USER); + + private static final Topic TOPIC = TopicFixture.createByName("topic", MEMBER); + + @Nested + class ValidationTest { + + + @Test + @DisplayName("정상적인 값이 입력되면 객체가 생성된다.") + void success() { + Atlas atlas = Atlas.from(TOPIC, MEMBER); + + assertThat(atlas).isNotNull(); + assertThat(atlas.getTopic()).isEqualTo(TOPIC); + assertThat(atlas.getMember()).isEqualTo(MEMBER); + } + + @ParameterizedTest + @MethodSource(value = "memberTopicProvider") + @DisplayName("입력값이 null이면 예외가 발생된다.") + void validation_fail() { + assertThatThrownBy(() -> Atlas.from(null, MEMBER)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("토픽과 멤버는 Null이어선 안됩니다."); + } + + static Stream memberTopicProvider() { + return Stream.of( + Arguments.of(null, MEMBER), + Arguments.of(TOPIC, null), + Arguments.of(TOPIC, MEMBER) + ); + } + } + +} diff --git a/backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java new file mode 100644 index 00000000..0fa968f1 --- /dev/null +++ b/backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java @@ -0,0 +1,77 @@ +package com.mapbefine.mapbefine.atlas.presentation; + +import static org.apache.http.HttpHeaders.AUTHORIZATION; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; + +import com.mapbefine.mapbefine.atlas.application.AtlasCommandService; +import com.mapbefine.mapbefine.atlas.application.AtlasQueryService; +import com.mapbefine.mapbefine.common.RestDocsIntegration; +import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; +import java.time.LocalDateTime; +import java.util.List; +import org.apache.tomcat.util.codec.binary.Base64; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +class AtlasControllerTest extends RestDocsIntegration { + + @MockBean + private AtlasQueryService atlasQueryService; + + private final String authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); + private final List responses = List.of( + new TopicResponse( + 1L, + "준팍의 또 토픽", + "https://map-befine-official.github.io/favicon.png", + 5, + LocalDateTime.now() + ), new TopicResponse( + 2L, + "준팍의 두번째 토픽", + "https://map-befine-official.github.io/favicon.png", + 3, + LocalDateTime.now() + ) + ); + + @Test + @DisplayName("모아보기에 추가되어있는 지도 목록을 조회한다") + void findTopicsFromAtlas_Success() throws Exception { + // when + given(atlasQueryService.findTopicsByMember(any())) + .willReturn(responses); + + // then + mockMvc.perform( + MockMvcRequestBuilders.get("/atlas") + .header(AUTHORIZATION, authHeader) + .contentType(MediaType.APPLICATION_JSON) + ).andDo(restDocs.document()); + } + + @Test + @DisplayName("모아보기에 지도를 추가한다") + void addTopicToAtlas_Success() throws Exception { + // then + mockMvc.perform( + MockMvcRequestBuilders.get("/atlas/1") + .header(AUTHORIZATION, authHeader) + ).andDo(restDocs.document()); + } + + @Test + @DisplayName("모아보기에 추가되어있는 지도를 삭제한다") + void removeTopicFromAtlas_Success() throws Exception { + // then + mockMvc.perform( + MockMvcRequestBuilders.get("/atlas/1") + .header(AUTHORIZATION, authHeader) + ).andDo(restDocs.document()); + } + +} From 53ec9b4f1eea969470dd32e5a73a458bd98784d2 Mon Sep 17 00:00:00 2001 From: junpakPark <112045553+junpakPark@users.noreply.github.com> Date: Thu, 10 Aug 2023 17:18:36 +0900 Subject: [PATCH 07/22] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapbefine/location/LocationIntegrationTest.java | 12 +++--------- .../application/LocationQueryServiceTest.java | 7 +++++-- .../presentation/LocationControllerTest.java | 13 +++---------- .../mapbefine/topic/TopicIntegrationTest.java | 3 ++- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/backend/src/test/java/com/mapbefine/mapbefine/location/LocationIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/location/LocationIntegrationTest.java index ba0c9bb7..88fbeaeb 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/location/LocationIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/location/LocationIntegrationTest.java @@ -9,7 +9,6 @@ import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import org.apache.tomcat.util.codec.binary.Base64; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; @@ -17,15 +16,10 @@ public class LocationIntegrationTest extends IntegrationTest { - private String authHeader; + private final String authHeader = Base64.encodeBase64String( + "Basic member@naver.com".getBytes() + ); - @BeforeEach - void setAuthHeader() { - String email = "member@naver.com"; - authHeader = Base64.encodeBase64String( - ("Basic" + email).getBytes() - ); - } @Test @DisplayName("현재 위치의 좌표를 보내주면 주변 Topic을 핀 갯수 순으로 정렬하여 반환한다.") diff --git a/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java b/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java index 14c41607..3c934a1d 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java @@ -26,8 +26,9 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -@ServiceTest +@DataJpaTest class LocationQueryServiceTest { @Autowired @@ -36,7 +37,7 @@ class LocationQueryServiceTest { private MemberRepository memberRepository; @Autowired private TopicRepository topicRepository; - @Autowired + private LocationQueryService locationQueryService; private Member member; @@ -46,6 +47,8 @@ class LocationQueryServiceTest { @BeforeEach void setup() { + locationQueryService = new LocationQueryService(locationRepository); + member = memberRepository.save(MemberFixture.create("member", "member@naver.com", Role.ADMIN)); authMember = new Admin(member.getId()); diff --git a/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java index cf65842d..4f6a5d69 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java @@ -7,9 +7,6 @@ import com.mapbefine.mapbefine.common.RestDocsIntegration; import com.mapbefine.mapbefine.location.application.LocationQueryService; -import com.mapbefine.mapbefine.member.MemberFixture; -import com.mapbefine.mapbefine.member.domain.Member; -import com.mapbefine.mapbefine.member.domain.Role; import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; import java.time.LocalDateTime; import java.util.List; @@ -23,8 +20,6 @@ class LocationControllerTest extends RestDocsIntegration { - private static final String BASIC_FORMAT = "Basic %s"; - @MockBean private LocationQueryService locationQueryService; private String authHeader; @@ -32,10 +27,7 @@ class LocationControllerTest extends RestDocsIntegration { @BeforeEach void setUp() { - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); + authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); responses = List.of( new TopicResponse( @@ -56,7 +48,7 @@ void setUp() { @Test @DisplayName("현재 위치를 기준 토픽의 핀 개수로 나열한다.") - void findNearbyTopicsSortedByPinCount() throws Exception { + void findNearbyTopicsSortedByPinCount_Success() throws Exception { //given double latitude = 37; double longitude = 127; @@ -74,4 +66,5 @@ void findNearbyTopicsSortedByPinCount() throws Exception { .param("longitude", String.valueOf(longitude)) ).andDo(restDocs.document()); } + } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java index bb779cdd..cbff74ac 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java @@ -1,5 +1,6 @@ package com.mapbefine.mapbefine.topic; +import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.assertj.core.api.Assertions.assertThat; import com.mapbefine.mapbefine.common.IntegrationTest; @@ -35,7 +36,7 @@ class TopicIntegrationTest extends IntegrationTest { private static final String BASIC_FORMAT = "Basic %s"; - private static final String AUTHORIZATION = "Authorization"; + @Autowired private PinRepository pinRepository; From 8af79ae8161a04d4ec8f3118453133d3e8cfa872 Mon Sep 17 00:00:00 2001 From: junpakPark <112045553+junpakPark@users.noreply.github.com> Date: Thu, 10 Aug 2023 18:41:40 +0900 Subject: [PATCH 08/22] =?UTF-8?q?feat:=20=EC=B5=9C=EC=8B=A0=20=ED=86=A0?= =?UTF-8?q?=ED=94=BD=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapbefine/pin/domain/PinRepository.java | 1 + .../topic/application/TopicQueryService.java | 15 ++++++++++++++- .../topic/presentation/TopicController.java | 7 +++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/pin/domain/PinRepository.java b/backend/src/main/java/com/mapbefine/mapbefine/pin/domain/PinRepository.java index 38bbe505..11a2d95d 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/pin/domain/PinRepository.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/pin/domain/PinRepository.java @@ -22,4 +22,5 @@ public interface PinRepository extends JpaRepository { List findByCreatorId(Long creatorId); + List findAllByOrderByUpdatedAtDesc(); } diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java index 367f47d8..42edf02c 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java @@ -1,6 +1,8 @@ package com.mapbefine.mapbefine.topic.application; import com.mapbefine.mapbefine.auth.domain.AuthMember; +import com.mapbefine.mapbefine.pin.domain.Pin; +import com.mapbefine.mapbefine.pin.domain.PinRepository; import com.mapbefine.mapbefine.topic.domain.Topic; import com.mapbefine.mapbefine.topic.domain.TopicRepository; import com.mapbefine.mapbefine.topic.dto.response.TopicDetailResponse; @@ -13,9 +15,11 @@ @Transactional(readOnly = true) public class TopicQueryService { + private final PinRepository pinRepository; private final TopicRepository topicRepository; - public TopicQueryService(final TopicRepository topicRepository) { + public TopicQueryService(PinRepository pinRepository, TopicRepository topicRepository) { + this.pinRepository = pinRepository; this.topicRepository = topicRepository; } @@ -75,4 +79,13 @@ private void validateReadableTopics(AuthMember member, List topics) { } } + + public List findAllByOrderByUpdatedAtDesc(AuthMember member) { + return pinRepository.findAllByOrderByUpdatedAtDesc() + .stream() + .map(Pin::getTopic) + .filter(member::canRead) + .map(TopicResponse::from) + .toList(); + } } diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java index 1dd051bb..73aefe57 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java @@ -85,6 +85,13 @@ public ResponseEntity> findByIds( return ResponseEntity.ok(responses); } + @GetMapping("/newest") + public ResponseEntity> findAllByOrderByUpdatedAtDesc(AuthMember member) { + List responses = topicQueryService.findAllByOrderByUpdatedAtDesc(member); + + return ResponseEntity.ok(responses); + } + @LoginRequired @PutMapping("/{topicId}") public ResponseEntity update( From b075d3aa87e8cb3a2f13cfd956b2d0cf994e2e2f Mon Sep 17 00:00:00 2001 From: junpakPark <112045553+junpakPark@users.noreply.github.com> Date: Thu, 10 Aug 2023 21:29:20 +0900 Subject: [PATCH 09/22] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=A6=AC=ED=8C=A9=ED=84=B0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../topic/application/TopicQueryService.java | 2 +- .../application/LocationQueryServiceTest.java | 1 - .../presentation/LocationControllerTest.java | 5 +- .../mapbefine/topic/TopicIntegrationTest.java | 126 +++++++++--------- .../application/TopicQueryServiceTest.java | 50 ++++++- .../presentation/TopicControllerTest.java | 85 ++++++------ 6 files changed, 150 insertions(+), 119 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java index 42edf02c..5321afd4 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicQueryService.java @@ -79,11 +79,11 @@ private void validateReadableTopics(AuthMember member, List topics) { } } - public List findAllByOrderByUpdatedAtDesc(AuthMember member) { return pinRepository.findAllByOrderByUpdatedAtDesc() .stream() .map(Pin::getTopic) + .distinct() .filter(member::canRead) .map(TopicResponse::from) .toList(); diff --git a/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java b/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java index 3c934a1d..dcae1676 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/location/application/LocationQueryServiceTest.java @@ -4,7 +4,6 @@ import com.mapbefine.mapbefine.auth.domain.AuthMember; import com.mapbefine.mapbefine.auth.domain.member.Admin; -import com.mapbefine.mapbefine.common.annotation.ServiceTest; import com.mapbefine.mapbefine.location.LocationFixture; import com.mapbefine.mapbefine.location.domain.Coordinate; import com.mapbefine.mapbefine.location.domain.Location; diff --git a/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java index 4f6a5d69..3f87fadc 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java @@ -22,13 +22,12 @@ class LocationControllerTest extends RestDocsIntegration { @MockBean private LocationQueryService locationQueryService; - private String authHeader; + private final String authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); + private List responses; @BeforeEach void setUp() { - authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); - responses = List.of( new TopicResponse( 1L, diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java index cbff74ac..43a160f8 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java @@ -21,12 +21,15 @@ import com.mapbefine.mapbefine.topic.dto.request.TopicCreateRequest; import com.mapbefine.mapbefine.topic.dto.request.TopicMergeRequest; import com.mapbefine.mapbefine.topic.dto.request.TopicUpdateRequest; +import com.mapbefine.mapbefine.topic.dto.response.TopicDetailResponse; +import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import java.util.Collections; import java.util.List; import org.apache.tomcat.util.codec.binary.Base64; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -35,9 +38,6 @@ class TopicIntegrationTest extends IntegrationTest { - private static final String BASIC_FORMAT = "Basic %s"; - - @Autowired private PinRepository pinRepository; @@ -50,12 +50,28 @@ class TopicIntegrationTest extends IntegrationTest { @Autowired private MemberRepository memberRepository; + + private Member member; + private Topic topic; + private Location location; + private String authHeader; + + @BeforeEach + void setMember() { + member = memberRepository.save( + MemberFixture.create("other", "other@othter.com", Role.ADMIN) + ); + topic = topicRepository.save(TopicFixture.createPublicAndAllMembersTopic(member)); + location = locationRepository.save(LocationFixture.create()); + authHeader = Base64.encodeBase64String( + ("Basic " + member.getMemberInfo().getEmail()).getBytes() + ); + } + + @Test @DisplayName("Pin 목록 없이 Topic을 생성하면 201을 반환한다") void createNewTopicWithoutPins_Success() { - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); - TopicCreateRequest 준팍의_또간집 = new TopicCreateRequest( "준팍의 또간집", "https://map-befine-official.github.io/favicon.png", @@ -65,10 +81,6 @@ void createNewTopicWithoutPins_Success() { Collections.emptyList() ); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); - // when ExtractableResponse response = createNewTopic(준팍의_또간집, authHeader); @@ -77,8 +89,7 @@ void createNewTopicWithoutPins_Success() { assertThat(response.header("Location")).isNotBlank(); } - private ExtractableResponse createNewTopic(TopicCreateRequest request, - String authHeader) { + private ExtractableResponse createNewTopic(TopicCreateRequest request, String authHeader) { return RestAssured.given() .log().all() .header(AUTHORIZATION, authHeader) @@ -92,25 +103,14 @@ private ExtractableResponse createNewTopic(TopicCreateRequest request, @Test @DisplayName("Pin 목록과 함께 Topic을 생성하면 201을 반환한다") void createNewTopicWithPins_Success() { - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); - Location location = LocationFixture.create(); - locationRepository.save(location); - - Topic topic = TopicFixture.createPublicAndAllMembersTopic(member); - Pin pin = PinFixture.create(location, topic, member); - topicRepository.save(topic); + PinFixture.create(location, topic, member); List pins = pinRepository.findAll(); List pinIds = pins.stream() .map(Pin::getId) .toList(); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); - TopicCreateRequest 준팍의_또간집 = new TopicCreateRequest( "준팍의 또간집", "https://map-befine-official.github.io/favicon.png", @@ -132,13 +132,6 @@ void createNewTopicWithPins_Success() { @DisplayName("여러개의 토픽을 병합하면 201을 반환한다") void createMergeTopic_Success() { // given - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); - - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); - TopicCreateRequest 준팍의_또간집 = new TopicCreateRequest( "준팍의 또간집", "https://map-befine-official.github.io/favicon.png", @@ -188,13 +181,6 @@ void createMergeTopic_Success() { @Test @DisplayName("Topic을 수정하면 200을 반환한다") void updateTopic_Success() { - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); - - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); - ExtractableResponse newTopic = createNewTopic( new TopicCreateRequest( "준팍의 또간집", @@ -232,12 +218,6 @@ void updateTopic_Success() { @Test @DisplayName("Topic을 삭제하면 204를 반환한다") void deleteTopic_Success() { - Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - memberRepository.save(member); - - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); ExtractableResponse newTopic = createNewTopic( new TopicCreateRequest( "준팍의 또간집", @@ -267,14 +247,6 @@ void deleteTopic_Success() { @Test @DisplayName("Topic 목록을 조회하면 200을 반환한다") void findTopics_Success() { - //given - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); - - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); - // when ExtractableResponse response = RestAssured .given().log().all() @@ -292,12 +264,6 @@ void findTopics_Success() { @DisplayName("Topic 상세 정보를 조회하면 200을 반환한다") void findTopicDetail_Success() { //given - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); - - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); TopicCreateRequest request = new TopicCreateRequest( "topicName", "https://map-befine-official.github.io/favicon.png", @@ -327,12 +293,6 @@ void findTopicDetail_Success() { @DisplayName("Topic 상세 정보 여러개를 조회하면 200을 반환한다") void findTopicDetailsByIds_Success() { //given - Member member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); - - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); TopicCreateRequest request = new TopicCreateRequest( "topicName", "https://map-befine-official.github.io/favicon.png", @@ -358,7 +318,45 @@ void findTopicDetailsByIds_Success() { .then().log().all() .extract(); + List responses = response.jsonPath().getList(".", TopicDetailResponse.class); + // then assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(responses).hasSize(2); + } + + @Test + @DisplayName("") + void findAllByOrderByUpdatedAtDesc_Success() { + // given + Topic topic1 = topicRepository.save(TopicFixture.createByName("topic1", member)); + Topic topic2 = topicRepository.save(TopicFixture.createByName("topic2", member)); + Topic topic3 = topicRepository.save(TopicFixture.createByName("topic3", member)); + + List pins = List.of( + PinFixture.create(location, topic1, member), + PinFixture.create(location, topic2, member), + PinFixture.create(location, topic2, member), + PinFixture.create(location, topic3, member), + PinFixture.create(location, topic3, member), + PinFixture.create(location, topic3, member) + ); + + pinRepository.saveAll(pins); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .header(AUTHORIZATION, authHeader) + .accept(MediaType.APPLICATION_JSON_VALUE) + .when().get("/topics/newest") + .then().log().all() + .extract(); + + List topicResponses = response.jsonPath().getList(".", TopicResponse.class); + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(topicResponses).hasSize(3); + assertThat(topicResponses.get(0).pinCount()).isEqualTo(3); + assertThat(topicResponses.get(2).pinCount()).isEqualTo(1); } } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicQueryServiceTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicQueryServiceTest.java index 0dbbf7e8..30d001c3 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicQueryServiceTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicQueryServiceTest.java @@ -5,11 +5,16 @@ import com.mapbefine.mapbefine.auth.domain.AuthMember; import com.mapbefine.mapbefine.auth.domain.member.Guest; -import com.mapbefine.mapbefine.common.annotation.ServiceTest; +import com.mapbefine.mapbefine.location.LocationFixture; +import com.mapbefine.mapbefine.location.domain.Location; +import com.mapbefine.mapbefine.location.domain.LocationRepository; import com.mapbefine.mapbefine.member.MemberFixture; import com.mapbefine.mapbefine.member.domain.Member; import com.mapbefine.mapbefine.member.domain.MemberRepository; import com.mapbefine.mapbefine.member.domain.Role; +import com.mapbefine.mapbefine.pin.PinFixture; +import com.mapbefine.mapbefine.pin.domain.Pin; +import com.mapbefine.mapbefine.pin.domain.PinRepository; import com.mapbefine.mapbefine.topic.TopicFixture; import com.mapbefine.mapbefine.topic.domain.Topic; import com.mapbefine.mapbefine.topic.domain.TopicRepository; @@ -20,23 +25,30 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -@ServiceTest +@DataJpaTest class TopicQueryServiceTest { @Autowired - private TopicQueryService topicQueryService; + private TopicRepository topicRepository; @Autowired - private MemberRepository memberRepository; + private PinRepository pinRepository; @Autowired - private TopicRepository topicRepository; + private LocationRepository locationRepository; + @Autowired + private MemberRepository memberRepository; + + private TopicQueryService topicQueryService; private Member member; @BeforeEach void setup() { + topicQueryService = new TopicQueryService(pinRepository, topicRepository); + member = MemberFixture.create("member", "member@naver.com", Role.USER); memberRepository.save(member); } @@ -214,4 +226,32 @@ void findDetailByIds_Fail2() { .hasMessage("존재하지 않는 토픽이 존재합니다"); } + @Test + @DisplayName("핀 수정일 기준으로 토픽을 나열한다") + void findAllByOrderByUpdatedAtDesc_Success() { + // given + Location location = LocationFixture.create(); + locationRepository.save(location); + + List topics = List.of( + TopicFixture.createByName("5등", member), + TopicFixture.createByName("4등", member), + TopicFixture.createByName("3등", member), + TopicFixture.createByName("2등", member), + TopicFixture.createByName("1등", member) + + ); + topicRepository.saveAll(topics); + + List pins = topics.stream() + .map(topic -> PinFixture.create(location, topic, member)) + .toList(); + pinRepository.saveAll(pins); + + // when + List responses = topicQueryService.findAllByOrderByUpdatedAtDesc(new Guest()); + + // then + assertThat(responses).isNotEmpty(); + } } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java index 03cc13d9..b777d0aa 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java @@ -5,9 +5,6 @@ import static org.mockito.BDDMockito.given; import com.mapbefine.mapbefine.common.RestDocsIntegration; -import com.mapbefine.mapbefine.member.MemberFixture; -import com.mapbefine.mapbefine.member.domain.Member; -import com.mapbefine.mapbefine.member.domain.Role; import com.mapbefine.mapbefine.pin.dto.response.PinResponse; import com.mapbefine.mapbefine.topic.application.TopicCommandService; import com.mapbefine.mapbefine.topic.application.TopicQueryService; @@ -19,6 +16,7 @@ import com.mapbefine.mapbefine.topic.dto.response.TopicDetailResponse; import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; import java.time.LocalDateTime; +import java.time.Month; import java.util.List; import org.apache.tomcat.util.codec.binary.Base64; import org.junit.jupiter.api.DisplayName; @@ -27,9 +25,25 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -class TopicControllerTest extends RestDocsIntegration { // TODO: 2023/07/25 Image 칼람 추가됨으로 인해 수정 필요 +class TopicControllerTest extends RestDocsIntegration { + + public static final List RESPONSES = List.of( + new TopicResponse( + 1L, + "준팍의 또 토픽", + "https://map-befine-official.github.io/favicon.png", + 3, + LocalDateTime.of(2023, Month.AUGUST, 11, 10, 10, 10) + ), new TopicResponse( + 2L, + "준팍의 두번째 토픽", + "https://map-befine-official.github.io/favicon.png", + 5, + LocalDateTime.of(2023, Month.AUGUST, 10, 10, 10, 10) + ) + ); + private static final String AUTH_HEADER = Base64.encodeBase64String("Basic member@naver.com".getBytes()); - private static final String BASIC_FORMAT = "Basic %s"; @MockBean private TopicCommandService topicCommandService; @@ -37,15 +51,10 @@ class TopicControllerTest extends RestDocsIntegration { // TODO: 2023/07/25 Imag @MockBean private TopicQueryService topicQueryService; - private static final Member member = - MemberFixture.create("member", "member@naver.com", Role.USER); @Test @DisplayName("토픽 새로 생성") void create() throws Exception { - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); given(topicCommandService.saveTopic(any(), any())).willReturn(1L); TopicCreateRequest topicCreateRequest = new TopicCreateRequest( @@ -59,7 +68,7 @@ void create() throws Exception { mockMvc.perform( MockMvcRequestBuilders.post("/topics/new") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, AUTH_HEADER) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(topicCreateRequest)) ).andDo(restDocs.document()); @@ -68,10 +77,9 @@ void create() throws Exception { @Test @DisplayName("토픽 병합 생성") void mergeAndCreate() throws Exception { - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); + given(topicCommandService.merge(any(), any())).willReturn(1L); + TopicMergeRequest topicMergeRequest = new TopicMergeRequest( "준팍의 안갈집", "https://map-befine-official.github.io/favicon.png", @@ -83,7 +91,7 @@ void mergeAndCreate() throws Exception { mockMvc.perform( MockMvcRequestBuilders.post("/topics/merge") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, AUTH_HEADER) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(topicMergeRequest)) ).andDo(restDocs.document()); @@ -92,9 +100,7 @@ void mergeAndCreate() throws Exception { @Test @DisplayName("토픽 수정") void update() throws Exception { - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); + TopicUpdateRequest topicUpdateRequest = new TopicUpdateRequest( "준팍의 안갈집", "https://map-befine-official.github.io/favicon.png", @@ -105,7 +111,7 @@ void update() throws Exception { mockMvc.perform( MockMvcRequestBuilders.put("/topics/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, AUTH_HEADER) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(topicUpdateRequest)) ).andDo(restDocs.document()); @@ -114,48 +120,27 @@ void update() throws Exception { @Test @DisplayName("토픽 삭제") void delete() throws Exception { - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); + mockMvc.perform( MockMvcRequestBuilders.delete("/topics/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, AUTH_HEADER) ).andDo(restDocs.document()); } @Test @DisplayName("토픽 목록 조회") void findAll() throws Exception { - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); - List responses = List.of(new TopicResponse( - 1L, - "준팍의 또 토픽", - "https://map-befine-official.github.io/favicon.png", - 3, - LocalDateTime.now() - ), new TopicResponse( - 2L, - "준팍의 두번째 토픽", - "https://map-befine-official.github.io/favicon.png", - 5, - LocalDateTime.now() - )); - given(topicQueryService.findAllReadable(any())).willReturn(responses); + given(topicQueryService.findAllReadable(any())).willReturn(RESPONSES); mockMvc.perform( MockMvcRequestBuilders.get("/topics") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, AUTH_HEADER) ).andDo(restDocs.document()); } @Test @DisplayName("토픽 상세 조회") void findById() throws Exception { - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); TopicDetailResponse topicDetailResponse = new TopicDetailResponse( 1L, "준팍의 두번째 토픽", @@ -185,8 +170,18 @@ void findById() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/topics/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, AUTH_HEADER) ).andDo(restDocs.document()); } + @Test + @DisplayName("핀 수정일 기준으로 토픽을 나열한다") + void findAllByOrderByUpdatedAtDesc() throws Exception { + given(topicQueryService.findAllByOrderByUpdatedAtDesc(any())).willReturn(RESPONSES); + + mockMvc.perform( + MockMvcRequestBuilders.get("/topics/newest") + .header(AUTHORIZATION, AUTH_HEADER) + ).andDo(restDocs.document()); + } } From b6e45e74f6ce12f51cd06747afd28a914c783bc3 Mon Sep 17 00:00:00 2001 From: junpakPark <112045553+junpakPark@users.noreply.github.com> Date: Thu, 10 Aug 2023 23:28:49 +0900 Subject: [PATCH 10/22] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A1=9C=EC=A7=81=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mapbefine/mapbefine/atlas/domain/AtlasTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java b/backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java index 311b8098..6d4e8bee 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/atlas/domain/AtlasTest.java @@ -40,8 +40,8 @@ void success() { @ParameterizedTest @MethodSource(value = "memberTopicProvider") @DisplayName("입력값이 null이면 예외가 발생된다.") - void validation_fail() { - assertThatThrownBy(() -> Atlas.from(null, MEMBER)) + void validation_fail(Topic topic, Member member) { + assertThatThrownBy(() -> Atlas.from(topic, member)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("토픽과 멤버는 Null이어선 안됩니다."); } @@ -50,7 +50,7 @@ static Stream memberTopicProvider() { return Stream.of( Arguments.of(null, MEMBER), Arguments.of(TOPIC, null), - Arguments.of(TOPIC, MEMBER) + Arguments.of(null, null) ); } } From 8167a2c356b6375fda6fd1d38aa483c755f82e6a Mon Sep 17 00:00:00 2001 From: junpakPark Date: Fri, 11 Aug 2023 14:58:35 +0900 Subject: [PATCH 11/22] =?UTF-8?q?test:=20=EA=B0=9C=ED=96=89=20=EB=B0=8F=20?= =?UTF-8?q?DisplayName=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapbefine/topic/TopicIntegrationTest.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java index 43a160f8..59544048 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java @@ -23,9 +23,8 @@ import com.mapbefine.mapbefine.topic.dto.request.TopicUpdateRequest; import com.mapbefine.mapbefine.topic.dto.response.TopicDetailResponse; import com.mapbefine.mapbefine.topic.dto.response.TopicResponse; -import io.restassured.RestAssured; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; +import io.restassured.*; +import io.restassured.response.*; import java.util.Collections; import java.util.List; import org.apache.tomcat.util.codec.binary.Base64; @@ -58,14 +57,10 @@ class TopicIntegrationTest extends IntegrationTest { @BeforeEach void setMember() { - member = memberRepository.save( - MemberFixture.create("other", "other@othter.com", Role.ADMIN) - ); + member = memberRepository.save(MemberFixture.create("other", "other@othter.com", Role.ADMIN)); topic = topicRepository.save(TopicFixture.createPublicAndAllMembersTopic(member)); location = locationRepository.save(LocationFixture.create()); - authHeader = Base64.encodeBase64String( - ("Basic " + member.getMemberInfo().getEmail()).getBytes() - ); + authHeader = Base64.encodeBase64String(("Basic " + member.getMemberInfo().getEmail()).getBytes()); } @@ -326,7 +321,7 @@ void findTopicDetailsByIds_Success() { } @Test - @DisplayName("") + @DisplayName("핀이 추가/수정된 일자 기준 내림차순으로 토픽 목록을 조회할 경우, 200을 반환한다") void findAllByOrderByUpdatedAtDesc_Success() { // given Topic topic1 = topicRepository.save(TopicFixture.createByName("topic1", member)); From 573fc31c9134f7fa4eb1fe499d8f723c19c6da6e Mon Sep 17 00:00:00 2001 From: junpakPark Date: Fri, 11 Aug 2023 16:00:35 +0900 Subject: [PATCH 12/22] =?UTF-8?q?docs:=20restDocs=20snippets=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/topic.adoc | 3 +++ .../mapbefine/topic/presentation/TopicControllerTest.java | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/docs/asciidoc/topic.adoc b/backend/src/docs/asciidoc/topic.adoc index c634e693..09834238 100644 --- a/backend/src/docs/asciidoc/topic.adoc +++ b/backend/src/docs/asciidoc/topic.adoc @@ -12,6 +12,9 @@ operation::topic-controller-test/find-bests[snippets='http-request,http-response operation::topic-controller-test/find-by-id[snippets='http-request,http-response'] +=== 최신 토픽 목록 조회 +operation::topic-controller-test/find-all-by-order-by-updated-at-desc[snippets='http-request,http-response'] + === 토픽 생성 operation::topic-controller-test/create[snippets='http-request,http-response'] diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java index b777d0aa..0c9e7827 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java @@ -44,14 +44,12 @@ class TopicControllerTest extends RestDocsIntegration { ); private static final String AUTH_HEADER = Base64.encodeBase64String("Basic member@naver.com".getBytes()); - @MockBean private TopicCommandService topicCommandService; @MockBean private TopicQueryService topicQueryService; - @Test @DisplayName("토픽 새로 생성") void create() throws Exception { From d49b63253980aff170315d018e029dcb9decc54d Mon Sep 17 00:00:00 2001 From: junpakPark Date: Fri, 11 Aug 2023 16:36:13 +0900 Subject: [PATCH 13/22] =?UTF-8?q?feat:=20=ED=95=80=EC=9D=84=20=EB=82=98?= =?UTF-8?q?=EC=9D=98=20=ED=86=A0=ED=94=BD=EB=93=A4=EC=97=90=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/TopicCommandService.java | 27 +++++++++++++++---- .../topic/presentation/TopicController.java | 8 ++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java index 96e1d024..ec7d7a6b 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java @@ -158,6 +158,28 @@ private List getAllPinsFromTopics(List topics) { .toList(); } + public void copyPin(AuthMember member, Long topicId, List pinIds) { + Topic topic = findTopic(topicId); + validatePinCreateOrUpdateAuth(member, topic); + + if (pinIds.isEmpty()) { + throw new IllegalArgumentException("복사할 핀을 선택해주세요"); + } + copyPinsToTopic(member, topic, pinIds); + } + + private void validatePinCreateOrUpdateAuth(AuthMember member, Topic topic) { + if (member.canPinCreateOrUpdate(topic)) { + return; + } + throw new IllegalArgumentException("핀을 추가할 권한이 없습니다."); + } + + private Topic findTopic(Long topicId) { + return topicRepository.findById(topicId) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Topic입니다.")); + } + public void updateTopicInfo( AuthMember member, Long topicId, @@ -171,11 +193,6 @@ public void updateTopicInfo( topic.updateTopicStatus(request.publicity(), request.permission()); } - private Topic findTopic(Long topicId) { - return topicRepository.findById(topicId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Topic입니다.")); - } - private void validateUpdateAuth(AuthMember member, Topic topic) { if (member.canTopicUpdate(topic)) { return; diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java index 73aefe57..ffe3dcc2 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/presentation/TopicController.java @@ -58,6 +58,14 @@ public ResponseEntity mergeAndCreate( .build(); } + @LoginRequired + @PostMapping("/{topicId}/copy") + public ResponseEntity copyPin(AuthMember member, @PathVariable Long topicId, @RequestParam List pinIds) { + topicCommandService.copyPin(member, topicId, pinIds); + + return ResponseEntity.ok().build(); + } + @GetMapping public ResponseEntity> findAll(AuthMember member) { List topics = topicQueryService.findAllReadable(member); From dea2ee863ceb2001af2bfe70bc8aa6fe4d9b08ff Mon Sep 17 00:00:00 2001 From: junpakPark Date: Fri, 11 Aug 2023 19:48:40 +0900 Subject: [PATCH 14/22] =?UTF-8?q?test:=20copyPin=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EB=B0=8F=20restDocs?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/topic.adoc | 3 + .../application/TopicCommandService.java | 13 ++- .../mapbefine/topic/TopicIntegrationTest.java | 41 +++++++ .../application/TopicCommandServiceTest.java | 102 +++++++++--------- .../presentation/TopicControllerTest.java | 10 ++ 5 files changed, 111 insertions(+), 58 deletions(-) diff --git a/backend/src/docs/asciidoc/topic.adoc b/backend/src/docs/asciidoc/topic.adoc index 09834238..667e9998 100644 --- a/backend/src/docs/asciidoc/topic.adoc +++ b/backend/src/docs/asciidoc/topic.adoc @@ -23,6 +23,9 @@ operation::topic-controller-test/create[snippets='http-request,http-response'] operation::topic-controller-test/merge-and-create[snippets='http-request,http-response'] +== 토픽에 핀 추가 +operation::topic-controller-test/copy-pin[snippets='http-request,http-response'] + === 토픽 수정 operation::topic-controller-test/update[snippets='http-request,http-response'] diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java index ec7d7a6b..30477f9f 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java @@ -165,9 +165,15 @@ public void copyPin(AuthMember member, Long topicId, List pinIds) { if (pinIds.isEmpty()) { throw new IllegalArgumentException("복사할 핀을 선택해주세요"); } + copyPinsToTopic(member, topic, pinIds); } + private Topic findTopic(Long topicId) { + return topicRepository.findById(topicId) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Topic입니다.")); + } + private void validatePinCreateOrUpdateAuth(AuthMember member, Topic topic) { if (member.canPinCreateOrUpdate(topic)) { return; @@ -175,11 +181,6 @@ private void validatePinCreateOrUpdateAuth(AuthMember member, Topic topic) { throw new IllegalArgumentException("핀을 추가할 권한이 없습니다."); } - private Topic findTopic(Long topicId) { - return topicRepository.findById(topicId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Topic입니다.")); - } - public void updateTopicInfo( AuthMember member, Long topicId, @@ -197,7 +198,6 @@ private void validateUpdateAuth(AuthMember member, Topic topic) { if (member.canTopicUpdate(topic)) { return; } - throw new IllegalArgumentException("업데이트 권한이 없습니다."); } @@ -214,7 +214,6 @@ private void validateDeleteAuth(AuthMember member, Topic topic) { if (member.canDelete(topic)) { return; } - throw new IllegalArgumentException("삭제 권한이 없습니다."); } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java index 59544048..77036d21 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java @@ -173,6 +173,47 @@ void createMergeTopic_Success() { assertThat(response.header("Location")).isNotBlank(); } + @Test + @DisplayName("기존 토픽에 핀을 복사하면 200을 반환한다") + void copyPin_Success() { + // given + + TopicCreateRequest 준팍의_또간집 = new TopicCreateRequest( + "준팍의 또간집", + "https://map-befine-official.github.io/favicon.png", + "준팍이 2번 이상 간집 ", + Publicity.PUBLIC, + Permission.ALL_MEMBERS, + Collections.emptyList() + ); + + ExtractableResponse newTopic = createNewTopic(준팍의_또간집, authHeader); + long topicId = Long.parseLong(newTopic.header("Location").split("/")[2]); + + List pins = List.of(PinFixture.create(location, topic, member), + PinFixture.create(location, topic, member), + PinFixture.create(location, topic, member) + ); + + List pinIds = pinRepository.saveAll(pins).stream() + .map(Pin::getId) + .toList(); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .header(AUTHORIZATION, authHeader) + .accept(MediaType.APPLICATION_JSON_VALUE) + .param("pinIds", pinIds) + .when().post("/topics/{topicId}/copy", topicId) + .then().log().all() + .extract(); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + + } + @Test @DisplayName("Topic을 수정하면 200을 반환한다") void updateTopic_Success() { diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicCommandServiceTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicCommandServiceTest.java index f0bea115..40f7f647 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicCommandServiceTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/application/TopicCommandServiceTest.java @@ -16,6 +16,7 @@ import com.mapbefine.mapbefine.member.domain.Role; import com.mapbefine.mapbefine.pin.PinFixture; import com.mapbefine.mapbefine.pin.domain.Pin; +import com.mapbefine.mapbefine.pin.domain.PinRepository; import com.mapbefine.mapbefine.topic.TopicFixture; import com.mapbefine.mapbefine.topic.domain.Permission; import com.mapbefine.mapbefine.topic.domain.Publicity; @@ -44,6 +45,9 @@ class TopicCommandServiceTest { @Autowired private TopicRepository topicRepository; + @Autowired + private PinRepository pinRepository; + @Autowired private TopicCommandService topicCommandService; @@ -51,19 +55,23 @@ class TopicCommandServiceTest { private TopicQueryService topicQueryService; private Member member; + private Location location; + private AuthMember user; + private AuthMember guest; @BeforeEach void setUp() { - member = MemberFixture.create("member", "member@naver.com", Role.USER); - memberRepository.save(member); + member = memberRepository.save(MemberFixture.create("member", "member@naver.com", Role.USER)); + location = locationRepository.save(LocationFixture.create()); + + user = MemberFixture.createUser(member); + guest = new Guest(); } @Test @DisplayName("비어있는 토픽을 생성할 수 있다.") public void saveEmptyTopic_Success() { //given - AuthMember user = MemberFixture.createUser(member); - TopicCreateRequest request = TopicFixture.createPublicAndAllMembersCreateRequestWithPins( Collections.emptyList() @@ -85,7 +93,6 @@ public void saveEmptyTopic_Success() { @DisplayName("Guest는 비어있는 토픽을 생성할 수 없다.") public void saveEmptyTopic_Fail() { //given - AuthMember guest = new Guest(); TopicCreateRequest request = TopicFixture.createPublicAndAllMembersCreateRequestWithPins( Collections.emptyList() @@ -101,9 +108,6 @@ public void saveEmptyTopic_Fail() { @DisplayName("핀을 통해 새로운 토픽을 생성할 수 있다.") public void saveTopicWithPins_Success() { //given - Location location = LocationFixture.create(); - locationRepository.save(location); - Topic topic = TopicFixture.createPublicAndAllMembersTopic(member); Pin pin1 = PinFixture.create(location, topic, member); @@ -112,7 +116,6 @@ public void saveTopicWithPins_Success() { topicRepository.save(topic); //when - AuthMember user = MemberFixture.createUser(member); TopicCreateRequest request = TopicFixture.createPublicAndAllMembersCreateRequestWithPins( List.of(pin1.getId(), pin2.getId()) @@ -136,17 +139,13 @@ public void saveTopicWithPins_Success() { @DisplayName("Guest는 핀을 통해 새로운 토픽을 생성할 수 없다.") public void saveTopicWithPins_Fail1() { //given - Location location = LocationFixture.create(); - locationRepository.save(location); + Topic publicAndAllMembersTopic = TopicFixture.createPublicAndAllMembersTopic(member); - Topic topic = TopicFixture.createPublicAndAllMembersTopic(member); + Pin pin1 = PinFixture.create(location, publicAndAllMembersTopic, member); + Pin pin2 = PinFixture.create(location, publicAndAllMembersTopic, member); - Pin pin1 = PinFixture.create(location, topic, member); - Pin pin2 = PinFixture.create(location, topic, member); + topicRepository.save(publicAndAllMembersTopic); - topicRepository.save(topic); - - AuthMember guest = new Guest(); TopicCreateRequest request = TopicFixture.createPublicAndAllMembersCreateRequestWithPins( List.of(pin1.getId(), pin2.getId()) @@ -169,9 +168,6 @@ public void saveTopicWithPins_Fail2() { ); memberRepository.save(topicOwner); - Location location = LocationFixture.create(); - locationRepository.save(location); - Topic topic = TopicFixture.createPrivateAndGroupOnlyTopic(topicOwner); Pin pin1 = PinFixture.create(location, topic, member); @@ -179,7 +175,6 @@ public void saveTopicWithPins_Fail2() { topicRepository.save(topic); - AuthMember user = MemberFixture.createUser(member); TopicCreateRequest request = TopicFixture.createPublicAndAllMembersCreateRequestWithPins( List.of(pin1.getId(), pin2.getId()) @@ -197,9 +192,6 @@ public void merge_Success() { Topic topic1 = TopicFixture.createPublicAndAllMembersTopic(member); Topic topic2 = TopicFixture.createPublicAndAllMembersTopic(member); - Location location = LocationFixture.create(); - locationRepository.save(location); - Pin pin1 = PinFixture.create(location, topic1, member); Pin pin2 = PinFixture.create(location, topic1, member); Pin pin3 = PinFixture.create(location, topic2, member); @@ -209,7 +201,6 @@ public void merge_Success() { topicRepository.save(topic2); //when - AuthMember user = MemberFixture.createUser(member); TopicMergeRequest request = TopicFixture.createPublicAndAllMembersMergeRequestWithTopics( List.of(topic1.getId(), topic2.getId()) @@ -235,16 +226,12 @@ public void merge_Success() { @DisplayName("Guest는 기존의 토픽들을 통해 새로운 토픽을 생성할 수 없다.") public void merge_Fail1() { //given - Location location = LocationFixture.create(); - locationRepository.save(location); - - Topic topic = TopicFixture.createPrivateAndGroupOnlyTopic(member); - topicRepository.save(topic); + Topic privateAndGroupOnlyTopic = TopicFixture.createPrivateAndGroupOnlyTopic(member); + topicRepository.save(privateAndGroupOnlyTopic); - AuthMember guest = new Guest(); TopicMergeRequest request = TopicFixture.createPublicAndAllMembersMergeRequestWithTopics( - List.of(topic.getId()) + List.of(privateAndGroupOnlyTopic.getId()) ); //when then @@ -264,13 +251,9 @@ public void merge_Fail2() { ); memberRepository.save(topicOwner); - Location location = LocationFixture.create(); - locationRepository.save(location); - Topic topic = TopicFixture.createPrivateAndGroupOnlyTopic(topicOwner); topicRepository.save(topic); - AuthMember user = MemberFixture.createUser(member); TopicMergeRequest request = TopicFixture.createPublicAndAllMembersMergeRequestWithTopics( List.of(topic.getId()) @@ -282,13 +265,42 @@ public void merge_Fail2() { .hasMessage("복사할 수 없는 토픽이 존재합니다."); } + @Test + @DisplayName("핀을 권한이 있는 토픽에 복사할 수 있다.") + void copyPin_Success() { + // given + Topic source = topicRepository.save(TopicFixture.createPublicAndAllMembersTopic(member)); + + List sourcePins = List.of( + PinFixture.create(location, source, member), + PinFixture.create(location, source, member), + PinFixture.create(location, source, member) + ); + pinRepository.saveAll(sourcePins); + + List pinIds = sourcePins.stream() + .map(Pin::getId) + .toList(); + + Topic target = topicRepository.save(TopicFixture.createPublicAndAllMembersTopic(member)); + + // when + topicCommandService.copyPin(user, target.getId(), pinIds); + + // then + List targetPins = target.getPins(); + Pin targetPin = targetPins.get(0); + Pin sourcePin = sourcePins.get(0); + + assertThat(targetPins).hasSize(sourcePins.size()); + assertThat(targetPin.getId()).isNotEqualTo(sourcePin.getId()); + assertThat(targetPin.getPinInfo().getName()).isEqualTo(sourcePin.getPinInfo().getName()); + } + @Test @DisplayName("토픽의 정보를 수정할 수 있다.") public void updateTopicInfo_Success() { //given - Location location = LocationFixture.create(); - locationRepository.save(location); - Topic topic = TopicFixture.createPrivateAndGroupOnlyTopic(member); topicRepository.save(topic); @@ -325,14 +337,10 @@ public void updateTopicInfo_Fail() { ); memberRepository.save(topicOwner); - Location location = LocationFixture.create(); - locationRepository.save(location); - Topic topic = TopicFixture.createPublicAndAllMembersTopic(topicOwner); topicRepository.save(topic); //when then - AuthMember user = MemberFixture.createUser(member); TopicUpdateRequest request = new TopicUpdateRequest( "수정된 이름", "https://map-befine-official.github.io/favicon.png", @@ -357,9 +365,6 @@ public void delete_Success() { ); memberRepository.save(admin); - Location location = LocationFixture.create(); - locationRepository.save(location); - Topic topic = TopicFixture.createPublicAndAllMembersTopic(admin); topicRepository.save(topic); @@ -380,15 +385,10 @@ public void delete_Success() { @DisplayName("Admin이 아닌 경우, 토픽을 삭제할 수 없다.") public void delete_Fail() { //given - Location location = LocationFixture.create(); - locationRepository.save(location); - Topic topic = TopicFixture.createPublicAndAllMembersTopic(member); topicRepository.save(topic); //when then - AuthMember user = MemberFixture.createUser(member); - assertThatThrownBy(() -> topicCommandService.delete(user, topic.getId())) .isInstanceOf(IllegalArgumentException.class) .hasMessage("삭제 권한이 없습니다."); diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java index 0c9e7827..f1c8ae8e 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java @@ -95,6 +95,16 @@ void mergeAndCreate() throws Exception { ).andDo(restDocs.document()); } + @Test + @DisplayName("핀을 권한이 있는 토픽에 복사할 수 있다.") + void copyPin() throws Exception { + + mockMvc.perform( + MockMvcRequestBuilders.post("/topics/1/copy?pinIds=1,2,3") + .header(AUTHORIZATION, AUTH_HEADER) + ).andDo(restDocs.document()); + } + @Test @DisplayName("토픽 수정") void update() throws Exception { From fd4ab32b17f9c58dbd9d6c3cba2adece782ac847 Mon Sep 17 00:00:00 2001 From: junpakPark Date: Sun, 13 Aug 2023 15:17:38 +0900 Subject: [PATCH 15/22] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EA=B0=9C=ED=96=89=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../topic/application/TopicCommandService.java | 10 +++++++--- .../mapbefine/topic/TopicIntegrationTest.java | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java index 30477f9f..2b087856 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java @@ -162,9 +162,7 @@ public void copyPin(AuthMember member, Long topicId, List pinIds) { Topic topic = findTopic(topicId); validatePinCreateOrUpdateAuth(member, topic); - if (pinIds.isEmpty()) { - throw new IllegalArgumentException("복사할 핀을 선택해주세요"); - } + validateCopyPinSelected(pinIds); copyPinsToTopic(member, topic, pinIds); } @@ -181,6 +179,12 @@ private void validatePinCreateOrUpdateAuth(AuthMember member, Topic topic) { throw new IllegalArgumentException("핀을 추가할 권한이 없습니다."); } + private void validateCopyPinSelected(List pinIds) { + if (pinIds.isEmpty()) { + throw new IllegalArgumentException("복사할 핀을 선택해주세요"); + } + } + public void updateTopicInfo( AuthMember member, Long topicId, diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java index 77036d21..e193fd8f 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/TopicIntegrationTest.java @@ -177,7 +177,6 @@ void createMergeTopic_Success() { @DisplayName("기존 토픽에 핀을 복사하면 200을 반환한다") void copyPin_Success() { // given - TopicCreateRequest 준팍의_또간집 = new TopicCreateRequest( "준팍의 또간집", "https://map-befine-official.github.io/favicon.png", @@ -190,7 +189,8 @@ void copyPin_Success() { ExtractableResponse newTopic = createNewTopic(준팍의_또간집, authHeader); long topicId = Long.parseLong(newTopic.header("Location").split("/")[2]); - List pins = List.of(PinFixture.create(location, topic, member), + List pins = List.of( + PinFixture.create(location, topic, member), PinFixture.create(location, topic, member), PinFixture.create(location, topic, member) ); From a65cede864290c3ca9da334621b9ea22dfaac700 Mon Sep 17 00:00:00 2001 From: junpakPark Date: Sun, 13 Aug 2023 15:19:06 +0900 Subject: [PATCH 16/22] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapbefine/topic/application/TopicCommandService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java index 2b087856..98dd79d6 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/topic/application/TopicCommandService.java @@ -160,7 +160,7 @@ private List getAllPinsFromTopics(List topics) { public void copyPin(AuthMember member, Long topicId, List pinIds) { Topic topic = findTopic(topicId); - validatePinCreateOrUpdateAuth(member, topic); + validatePinCreateOrUpdateAuthInTopic(member, topic); validateCopyPinSelected(pinIds); @@ -172,7 +172,7 @@ private Topic findTopic(Long topicId) { .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Topic입니다.")); } - private void validatePinCreateOrUpdateAuth(AuthMember member, Topic topic) { + private void validatePinCreateOrUpdateAuthInTopic(AuthMember member, Topic topic) { if (member.canPinCreateOrUpdate(topic)) { return; } From 85e5e791385e5ef8f16d500189d3eb592c7cf778 Mon Sep 17 00:00:00 2001 From: yoondgu Date: Wed, 16 Aug 2023 11:31:05 +0900 Subject: [PATCH 17/22] =?UTF-8?q?refactor:=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20API=20=EB=AA=85=EC=84=B8=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 여러 회원에 대한 권한을 한번에 부여할 수 있도록 변경 - 불필요한 권한 id 반환하지 않도록 변경 - 변경 사항 RestDocs 반영 - 관련 테스트코드 수정 --- .../application/PermissionCommandService.java | 47 +++---- .../dto/request/PermissionRequest.java | 4 +- .../presentation/PermissionController.java | 5 +- .../permission/PermissionIntegrationTest.java | 12 +- .../PermissionCommandServiceTest.java | 117 ++++++++++-------- .../PermissionControllerTest.java | 7 +- 6 files changed, 97 insertions(+), 95 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/permission/application/PermissionCommandService.java b/backend/src/main/java/com/mapbefine/mapbefine/permission/application/PermissionCommandService.java index 4a64110f..b7b94db2 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/permission/application/PermissionCommandService.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/permission/application/PermissionCommandService.java @@ -8,6 +8,7 @@ import com.mapbefine.mapbefine.permission.dto.request.PermissionRequest; import com.mapbefine.mapbefine.topic.domain.Topic; import com.mapbefine.mapbefine.topic.domain.TopicRepository; +import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; import org.springframework.stereotype.Service; @@ -31,40 +32,41 @@ public PermissionCommandService( this.permissionRepository = permissionRepository; } - public Long savePermission(AuthMember authMember, PermissionRequest request) { - validateUser(authMember); - validateSelfPermission(authMember, request); - validateDuplicatePermission(request); - + public void savePermission(AuthMember authMember, PermissionRequest request) { + validateGuest(authMember); Topic topic = findTopic(request); validateMemberCanTopicUpdate(authMember, topic); - Member member = findMember(request); - Permission permission = - Permission.createPermissionAssociatedWithTopicAndMember(topic, member); + List members = findTargetMembers(request); + List permissions = createPermissions(authMember, topic, members); - return permissionRepository.save(permission).getId(); + permissionRepository.saveAll(permissions); } - private void validateUser(AuthMember authMember) { + private void validateGuest(AuthMember authMember) { if (Objects.isNull(authMember.getMemberId())) { throw new IllegalArgumentException("Guest는 권한을 줄 수 없습니다."); } } - private void validateSelfPermission(AuthMember authMember, PermissionRequest request) { - Long sourceMemberId = authMember.getMemberId(); - Long targetMemberId = request.memberId(); + private List createPermissions( + AuthMember authMember, + Topic topic, + List members + ) { + return members.stream() + .filter(member -> isNotSelfMember(authMember, member)) + .filter(member -> isNotWithPermission(topic.getId(), member)) + .map(member -> Permission.createPermissionAssociatedWithTopicAndMember(topic, member)) + .toList(); + } - if (sourceMemberId.equals(targetMemberId)) { - throw new IllegalArgumentException("본인에게 권한을 줄 수 없습니다."); - } + private boolean isNotWithPermission(Long topicId, Member member) { + return !permissionRepository.existsByTopicIdAndMemberId(topicId, member.getId()); } - private void validateDuplicatePermission(PermissionRequest request) { - if (permissionRepository.existsByTopicIdAndMemberId(request.topicId(), request.memberId())) { - throw new IllegalArgumentException("권한은 중복으로 줄 수 없습니다."); - } + private boolean isNotSelfMember(AuthMember authMember, Member member) { + return !Objects.equals(authMember.getMemberId(), member.getId()); } private Topic findTopic(PermissionRequest request) { @@ -79,9 +81,8 @@ private void validateMemberCanTopicUpdate(AuthMember authMember, Topic topic) { throw new IllegalArgumentException("해당 지도에서 다른 유저에게 권한을 줄 수 없습니다."); } - private Member findMember(PermissionRequest request) { - return memberRepository.findById(request.memberId()) - .orElseThrow(NoSuchElementException::new); + private List findTargetMembers(PermissionRequest request) { + return memberRepository.findAllById(request.memberIds()); } public void deleteMemberTopicPermission(AuthMember authMember, Long permissionId) { diff --git a/backend/src/main/java/com/mapbefine/mapbefine/permission/dto/request/PermissionRequest.java b/backend/src/main/java/com/mapbefine/mapbefine/permission/dto/request/PermissionRequest.java index a0dd1f42..85ccd94b 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/permission/dto/request/PermissionRequest.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/permission/dto/request/PermissionRequest.java @@ -1,7 +1,9 @@ package com.mapbefine.mapbefine.permission.dto.request; +import java.util.List; + public record PermissionRequest( Long topicId, - Long memberId + List memberIds ) { } diff --git a/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java b/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java index 2cd73280..8bfc9091 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java @@ -7,7 +7,6 @@ import com.mapbefine.mapbefine.permission.dto.request.PermissionRequest; import com.mapbefine.mapbefine.permission.dto.response.PermissionDetailResponse; import com.mapbefine.mapbefine.permission.dto.response.PermissionResponse; -import java.net.URI; import java.util.List; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -36,9 +35,9 @@ public PermissionController( @LoginRequired @PostMapping public ResponseEntity addPermission(AuthMember authMember, @RequestBody PermissionRequest request) { - Long savedId = permissionCommandService.savePermission(authMember, request); + permissionCommandService.savePermission(authMember, request); - return ResponseEntity.created(URI.create("/permissions/" + savedId)).build(); + return ResponseEntity.ok().build(); } @LoginRequired diff --git a/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java index 9149ecdf..a1755ad7 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java @@ -1,7 +1,7 @@ package com.mapbefine.mapbefine.permission; import static com.mapbefine.mapbefine.oauth.domain.OauthServerType.KAKAO; -import static io.restassured.RestAssured.given; +import static io.restassured.RestAssured.*; import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.assertj.core.api.Assertions.assertThat; @@ -21,9 +21,8 @@ import com.mapbefine.mapbefine.topic.TopicFixture; import com.mapbefine.mapbefine.topic.domain.Topic; import com.mapbefine.mapbefine.topic.domain.TopicRepository; -import io.restassured.common.mapper.TypeRef; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; +import io.restassured.common.mapper.*; +import io.restassured.response.*; import java.time.LocalDateTime; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -85,7 +84,7 @@ void addPermission() { Topic topic = topicRepository.save(TopicFixture.createByName("topicName", creator)); // when - PermissionRequest request = new PermissionRequest(topic.getId(), user1.getId()); + PermissionRequest request = new PermissionRequest(topic.getId(), List.of(user1.getId())); ExtractableResponse response = given().log().all() .header(AUTHORIZATION, creatorAuthHeader) @@ -96,8 +95,7 @@ void addPermission() { .extract(); // then - assertThat(response.header("Location")).isNotBlank(); - assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); } @Test diff --git a/backend/src/test/java/com/mapbefine/mapbefine/permission/application/PermissionCommandServiceTest.java b/backend/src/test/java/com/mapbefine/mapbefine/permission/application/PermissionCommandServiceTest.java index ee1f2c0d..c533299d 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/permission/application/PermissionCommandServiceTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/permission/application/PermissionCommandServiceTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import com.mapbefine.mapbefine.auth.domain.AuthMember; import com.mapbefine.mapbefine.auth.domain.member.Admin; @@ -48,22 +49,21 @@ void saveMemberTopicPermissionByAdmin() { Member member = memberRepository.save( MemberFixture.create("members", "members@naver.com", Role.USER)); Topic topic = topicRepository.save(TopicFixture.createByName("topic", admin)); + + // when AuthMember authAdmin = new Admin(admin.getId()); + Long permissionTargetMemberId = member.getId(); PermissionRequest request = new PermissionRequest( topic.getId(), - member.getId() + List.of(permissionTargetMemberId) ); - - // when - Long savedId = permissionCommandService.savePermission(authAdmin, request); - Permission permission = permissionRepository.findById(savedId) - .orElseThrow(NoSuchElementException::new); - Member memberWithPermission = permission.getMember(); + permissionCommandService.savePermission(authAdmin, request); // then - assertThat(member).usingRecursiveComparison() - .ignoringFields("createdAt", "updatedAt") - .isEqualTo(memberWithPermission); + Member memberWithPermission = memberRepository.findById(permissionTargetMemberId) + .orElseThrow(NoSuchElementException::new); + assertThat(memberWithPermission.getTopicsWithPermissions()) + .contains(topic); } @Test @@ -75,26 +75,25 @@ void saveMemberTopicPermissionByCreator() { Member member = memberRepository.save( MemberFixture.create("members", "members@naver.com", Role.USER)); Topic topic = topicRepository.save(TopicFixture.createByName("topic", creator)); + + // when AuthMember authCreator = new User( creator.getId(), getCreatedTopics(creator), getTopicsWithPermission(creator) ); + Long permissionTargetMemberId = member.getId(); PermissionRequest request = new PermissionRequest( topic.getId(), - member.getId() + List.of(permissionTargetMemberId) ); - - // when - Long savedId = permissionCommandService.savePermission(authCreator, request); - Permission permission = permissionRepository.findById(savedId) - .orElseThrow(NoSuchElementException::new); - Member memberWithPermission = permission.getMember(); + permissionCommandService.savePermission(authCreator, request); // then - assertThat(member).usingRecursiveComparison() - .ignoringFields("createdAt", "updatedAt") - .isEqualTo(memberWithPermission); + Member memberWithPermission = memberRepository.findById(permissionTargetMemberId) + .orElseThrow(NoSuchElementException::new); + assertThat(memberWithPermission.getTopicsWithPermissions()) + .contains(topic); } @Test @@ -108,6 +107,8 @@ void saveMemberTopicPermissionByUser() { Member member = memberRepository.save( MemberFixture.create("memberss", "memberss@naver.com", Role.USER)); Topic topic = topicRepository.save(TopicFixture.createByName("topic", creator)); + + // when AuthMember authNotCreator = new User( notCreator.getId(), getCreatedTopics(notCreator), @@ -115,10 +116,10 @@ void saveMemberTopicPermissionByUser() { ); PermissionRequest request = new PermissionRequest( topic.getId(), - member.getId() + List.of(member.getId()) ); - // when then + // then assertThatThrownBy(() -> permissionCommandService.savePermission(authNotCreator, request)) .isInstanceOf(IllegalArgumentException.class); } @@ -132,41 +133,49 @@ void saveMemberTopicPermissionByGuest() { Member member = memberRepository.save( MemberFixture.create("memberss", "memberss@naver.com", Role.USER)); Topic topic = topicRepository.save(TopicFixture.createByName("topic", creator)); + + // when AuthMember guest = new Guest(); + Long savedId = member.getId(); PermissionRequest request = new PermissionRequest( topic.getId(), - member.getId() + List.of(savedId) ); - // when then + // then assertThatThrownBy(() -> permissionCommandService.savePermission(guest, request)) .isInstanceOf(IllegalArgumentException.class); } @Test - @DisplayName("본인에게 권한을 주려하는 경우 예외가 발생한다.") - void saveMemberTopicPermissionByCreator_whenSelf_thenFail() { + @DisplayName("본인에게 권한을 주는 요청에 대해서는 이미 권한을 부여한 것으로 판단해 DB에 반영하지 않는다.") + void saveSelfTopicPermissionByCreator() { // given Member creator = memberRepository.save( MemberFixture.create("member", "member@naver.com", Role.USER)); + Long creatorId = creator.getId(); Topic topic = topicRepository.save(TopicFixture.createByName("topic", creator)); + Long topicId = topic.getId(); + + // when + PermissionRequest request = new PermissionRequest( + topicId, + List.of(creatorId) + ); AuthMember authCreator = new User( - creator.getId(), + creatorId, getCreatedTopics(creator), getTopicsWithPermission(creator) ); - PermissionRequest request = new PermissionRequest( - topic.getId(), - creator.getId() - ); + permissionCommandService.savePermission(authCreator, request); - // when then - assertThatThrownBy(() -> permissionCommandService.savePermission(authCreator, request)) - .isInstanceOf(IllegalArgumentException.class); + // then + assertThat(permissionRepository.existsByTopicIdAndMemberId(topicId, creatorId)) + .isFalse(); } @Test - @DisplayName("이미 권한을 부여 받은 사람에게 권한을 주는 경우 예외가 발생한다.") + @DisplayName("이미 권한을 부여 받은 사람에게 권한을 주는 경우 이미 권한을 부여한 것으로 판단한다.") void saveMemberTopicPermissionByCreator_whenDuplicate_thenFail() { // given Member creator = memberRepository.save( @@ -184,22 +193,24 @@ void saveMemberTopicPermissionByCreator_whenDuplicate_thenFail() { ) ); Topic topic = topicRepository.save(TopicFixture.createByName("topic", creator)); + Long topicId = topic.getId(); Permission permission = Permission.createPermissionAssociatedWithTopicAndMember(topic, member); permissionRepository.save(permission); + + // when + PermissionRequest request = new PermissionRequest( + topicId, + List.of(member.getId()) + ); AuthMember authCreator = new User( creator.getId(), getCreatedTopics(creator), getTopicsWithPermission(creator) ); - PermissionRequest request = new PermissionRequest( - topic.getId(), - member.getId() - ); - // when then - assertThatThrownBy(() -> permissionCommandService.savePermission(authCreator, request)) - .isInstanceOf(IllegalArgumentException.class); + // then + assertDoesNotThrow(() -> permissionCommandService.savePermission(authCreator, request)); } @Test @@ -211,16 +222,16 @@ void deleteMemberTopicPermissionByAdmin() { Member member = memberRepository.save( MemberFixture.create("members", "members@naver.com", Role.USER)); Topic topic = topicRepository.save(TopicFixture.createByName("topic", admin)); - AuthMember authAdmin = new Admin(admin.getId()); - - // when Permission permission = Permission.createPermissionAssociatedWithTopicAndMember(topic, member); Long savedId = permissionRepository.save(permission).getId(); + + // when + AuthMember authAdmin = new Admin(admin.getId()); permissionCommandService.deleteMemberTopicPermission(authAdmin, savedId); // then - assertThat(memberRepository.existsById(savedId)).isFalse(); + assertThat(permissionRepository.existsById(savedId)).isFalse(); } @Test @@ -245,7 +256,7 @@ void deleteMemberTopicPermissionByCreator() { permissionCommandService.deleteMemberTopicPermission(authCreator, savedId); // then - assertThat(memberRepository.existsById(savedId)).isFalse(); + assertThat(permissionRepository.existsById(savedId)).isFalse(); } @Test @@ -271,10 +282,8 @@ void deleteMemberTopicPermissionByUser() { Long savedId = permissionRepository.save(permission).getId(); // then - assertThatThrownBy(() -> permissionCommandService.deleteMemberTopicPermission( - authNonCreator, - savedId - )).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> permissionCommandService.deleteMemberTopicPermission(authNonCreator, savedId)) + .isInstanceOf(IllegalArgumentException.class); } @Test @@ -295,10 +304,8 @@ void deleteMemberTopicPermissionByCreator_whenNoneExistsPermission_thenFail() { ); // when then - assertThatThrownBy(() -> permissionCommandService.deleteMemberTopicPermission( - authCreator, - Long.MAX_VALUE - )).isInstanceOf(NoSuchElementException.class); + assertThatThrownBy(() -> permissionCommandService.deleteMemberTopicPermission(authCreator, Long.MAX_VALUE)) + .isInstanceOf(NoSuchElementException.class); } private List getTopicsWithPermission(Member member) { diff --git a/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java index aa9b1db6..76a46401 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java @@ -10,7 +10,6 @@ import com.mapbefine.mapbefine.member.domain.Role; import com.mapbefine.mapbefine.member.dto.response.MemberDetailResponse; import com.mapbefine.mapbefine.member.dto.response.MemberResponse; -import com.mapbefine.mapbefine.permission.application.PermissionCommandService; import com.mapbefine.mapbefine.permission.application.PermissionQueryService; import com.mapbefine.mapbefine.permission.dto.request.PermissionRequest; import com.mapbefine.mapbefine.permission.dto.response.PermissionDetailResponse; @@ -26,8 +25,6 @@ class PermissionControllerTest extends RestDocsIntegration { - @MockBean - private PermissionCommandService permissionCommandService; @MockBean private PermissionQueryService permissionQueryService; @@ -35,13 +32,11 @@ class PermissionControllerTest extends RestDocsIntegration { @DisplayName("권한 추가") void addPermission() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - PermissionRequest request = new PermissionRequest(1L, 2L); + PermissionRequest request = new PermissionRequest(1L, List.of(1L, 2L, 3L)); String authHeader = Base64.encodeBase64String( ("Basic " + member.getMemberInfo().getEmail()).getBytes() ); - given(permissionCommandService.savePermission(any(), any())).willReturn(1L); - mockMvc.perform( MockMvcRequestBuilders.post("/permissions") .header(AUTHORIZATION, authHeader) From 13470419c494d72c1e365551f00c74102ec74695 Mon Sep 17 00:00:00 2001 From: yoondgu Date: Wed, 16 Aug 2023 11:45:49 +0900 Subject: [PATCH 18/22] =?UTF-8?q?fix:=20=EA=B6=8C=ED=95=9C=20=EB=B6=80?= =?UTF-8?q?=EC=97=AC=20API=20=EC=9D=91=EB=8B=B5=EC=BD=94=EB=93=9C=20201?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../permission/presentation/PermissionController.java | 3 ++- .../mapbefine/permission/PermissionIntegrationTest.java | 2 +- .../permission/presentation/PermissionControllerTest.java | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java b/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java index 8bfc9091..bdc6a0e6 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/permission/presentation/PermissionController.java @@ -8,6 +8,7 @@ import com.mapbefine.mapbefine.permission.dto.response.PermissionDetailResponse; import com.mapbefine.mapbefine.permission.dto.response.PermissionResponse; import java.util.List; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -37,7 +38,7 @@ public PermissionController( public ResponseEntity addPermission(AuthMember authMember, @RequestBody PermissionRequest request) { permissionCommandService.savePermission(authMember, request); - return ResponseEntity.ok().build(); + return ResponseEntity.status(HttpStatus.CREATED).build(); } @LoginRequired diff --git a/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java index a1755ad7..20f9072a 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/permission/PermissionIntegrationTest.java @@ -95,7 +95,7 @@ void addPermission() { .extract(); // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); } @Test diff --git a/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java index 76a46401..e4d491e3 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java @@ -10,6 +10,7 @@ import com.mapbefine.mapbefine.member.domain.Role; import com.mapbefine.mapbefine.member.dto.response.MemberDetailResponse; import com.mapbefine.mapbefine.member.dto.response.MemberResponse; +import com.mapbefine.mapbefine.permission.application.PermissionCommandService; import com.mapbefine.mapbefine.permission.application.PermissionQueryService; import com.mapbefine.mapbefine.permission.dto.request.PermissionRequest; import com.mapbefine.mapbefine.permission.dto.response.PermissionDetailResponse; @@ -27,15 +28,15 @@ class PermissionControllerTest extends RestDocsIntegration { @MockBean private PermissionQueryService permissionQueryService; + @MockBean + private PermissionCommandService permissionCommandService; @Test @DisplayName("권한 추가") void addPermission() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); PermissionRequest request = new PermissionRequest(1L, List.of(1L, 2L, 3L)); - String authHeader = Base64.encodeBase64String( - ("Basic " + member.getMemberInfo().getEmail()).getBytes() - ); + String authHeader = testAuthHeaderProvider.createAuthHeader(member); mockMvc.perform( MockMvcRequestBuilders.post("/permissions") From 0f075438280e5853197e3ad4101fdde8767f8954 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Wed, 16 Aug 2023 13:36:25 +0900 Subject: [PATCH 19/22] =?UTF-8?q?chore=20:=20=EA=B0=9C=EB=B0=9C=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EC=97=90=EC=84=9C=EB=8A=94=20ddl-auto=20=3D=20update?= =?UTF-8?q?=20=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/resources/application-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/resources/application-dev.yml b/backend/src/main/resources/application-dev.yml index 8db955b8..f49a321c 100644 --- a/backend/src/main/resources/application-dev.yml +++ b/backend/src/main/resources/application-dev.yml @@ -10,7 +10,7 @@ spring: format_sql: true show-sql: true hibernate: - ddl-auto: none + ddl-auto: update logging: level: org: From 17648afe0d08e90fba11427de0798d7a655f0e83 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Wed, 16 Aug 2023 13:36:53 +0900 Subject: [PATCH 20/22] =?UTF-8?q?fix=20:=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20=ED=98=95=EC=8B=9D=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/member.adoc | 3 ++- .../presentation/BookmarkController.java | 14 +++++++------- .../common/interceptor/AuthInterceptor.java | 10 +++++++++- .../bookmark/BookmarkIntegrationTest.java | 10 +++++----- .../presentation/BookmarkControllerTest.java | 16 ++++++---------- .../mapbefine/common/TestAuthHeaderProvider.java | 4 ++++ .../presentation/MemberControllerTest.java | 2 +- 7 files changed, 34 insertions(+), 25 deletions(-) diff --git a/backend/src/docs/asciidoc/member.adoc b/backend/src/docs/asciidoc/member.adoc index bbc5f6ad..94ffcb6e 100644 --- a/backend/src/docs/asciidoc/member.adoc +++ b/backend/src/docs/asciidoc/member.adoc @@ -8,7 +8,6 @@ operation::member-controller-test/find-all-member[snippets='http-request,http-re operation::member-controller-test/find-member-by-id[snippets='http-request,http-response'] - === 유저의 나의 지도 목록 조회 operation::member-controller-test/find-my-all-topics[snippets='http-request,http-response'] @@ -22,3 +21,5 @@ operation::member-controller-test/find-my-all-pins[snippets='http-request,http-r operation::member-controller-test/find-all-topics-in-atlas[snippets='http-request,http-response'] === 유저의 즐겨찾기 조회 + +operation::member-controller-test/find-all-topics-in-bookmark[snippets='http-request,http-response'] diff --git a/backend/src/main/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkController.java b/backend/src/main/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkController.java index 7c9f7f72..c66af190 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkController.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkController.java @@ -22,23 +22,23 @@ public BookmarkController(BookmarkCommandService bookmarkCommandService) { } @LoginRequired - @PostMapping + @PostMapping("/topics") public ResponseEntity addTopicInBookmark( AuthMember authMember, - @RequestParam Long topicId + @RequestParam Long id ) { - Long bookmarkId = bookmarkCommandService.addTopicInBookmark(authMember, topicId); + Long bookmarkId = bookmarkCommandService.addTopicInBookmark(authMember, id); - return ResponseEntity.created(URI.create("/bookmarks/" + bookmarkId)).build(); + return ResponseEntity.created(URI.create("/bookmarks/topics" + bookmarkId)).build(); } @LoginRequired - @DeleteMapping + @DeleteMapping("/topics") public ResponseEntity deleteTopicInBookmark( AuthMember authMember, - @RequestParam Long topicId + @RequestParam Long id ) { - bookmarkCommandService.deleteTopicInBookmark(authMember, topicId); + bookmarkCommandService.deleteTopicInBookmark(authMember, id); return ResponseEntity.noContent().build(); } diff --git a/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java b/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java index 2f7ece05..aac1ae1a 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java @@ -49,11 +49,19 @@ public boolean preHandle( if (isLoginRequired((HandlerMethod) handler)) { // TODO: 2023/08/11 isMember false이면 403 반환 - return authService.isMember(memberId); + boolean isMember = authService.isMember(memberId); + validateMember(isMember); } + return true; } + private void validateMember(boolean isMember) { + if (!isMember) { + throw new IllegalArgumentException("조회되지 않는 회원입니다."); + } + } + private boolean isAuthMemberNotRequired(HandlerMethod handlerMethod) { return Arrays.stream(handlerMethod.getMethodParameters()) .noneMatch(parameter -> parameter.getParameterType().equals(AuthMember.class)); diff --git a/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java index 7994c412..69451e50 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java @@ -50,14 +50,14 @@ void addTopicInBookmark_Success() { //when ExtractableResponse response = given().log().all() .header(AUTHORIZATION, otherUserAuthHeader) - .param("topicId", topic.getId()) - .when().post("/bookmarks") + .param("id", topic.getId()) + .when().post("/bookmarks/topics") .then().log().all() .extract(); //then assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); - assertThat(response.header("Location")).startsWith("/bookmarks/") + assertThat(response.header("Location")).startsWith("/bookmarks/topics") .isNotNull(); } @@ -79,8 +79,8 @@ void deleteTopicInBookmark_Success() { //when then given().log().all() .header(AUTHORIZATION, creatorAuthHeader) - .param("topicId", topic.getId()) - .when().delete("/bookmarks") + .param("id", topic.getId()) + .when().delete("/bookmarks/topics") .then().log().all() .statusCode(HttpStatus.NO_CONTENT.value()); } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkControllerTest.java index be18fa06..e5076254 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/bookmark/presentation/BookmarkControllerTest.java @@ -22,28 +22,24 @@ class BookmarkControllerTest extends RestDocsIntegration { @Test @DisplayName("토픽을 유저의 즐겨찾기에 추가") public void addTopicInBookmark() throws Exception { - String authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); - given(bookmarkCommandService.addTopicInBookmark(any(), any())).willReturn(1L); mockMvc.perform( - MockMvcRequestBuilders.post("/bookmarks") - .header(AUTHORIZATION, authHeader) - .param("topicId", String.valueOf(1L)) + MockMvcRequestBuilders.post("/bookmarks/topics") + .queryParam("id", String.valueOf(1)) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @Test @DisplayName("유저의 토픽 즐겨찾기 목록 삭제") public void deleteTopicInBookmark() throws Exception { - String authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); - doNothing().when(bookmarkCommandService).deleteTopicInBookmark(any(), any()); mockMvc.perform( - MockMvcRequestBuilders.delete("/bookmarks") - .param("topicId", String.valueOf(1L)) - .header(AUTHORIZATION, authHeader) + MockMvcRequestBuilders.delete("/bookmarks/topics") + .queryParam("id", String.valueOf(1L)) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/common/TestAuthHeaderProvider.java b/backend/src/test/java/com/mapbefine/mapbefine/common/TestAuthHeaderProvider.java index c11c60e4..efa0749a 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/common/TestAuthHeaderProvider.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/common/TestAuthHeaderProvider.java @@ -20,6 +20,10 @@ public String createAuthHeader(Member member) { return TOKEN_TYPE + generateToken(memberId); } + public String createAuthHeaderById(Long memberId) { + return TOKEN_TYPE + generateToken(memberId); + } + public String createResponseAccessTokenById(Long id) { return generateToken(id); } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java index 2c422194..7acd8fc6 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java @@ -167,7 +167,7 @@ void findMyAllTopics() throws Exception { ) ); - given(memberQueryService.findAllTopicsInBookmark(any())).willReturn(responses); + given(memberQueryService.findMyAllTopics(any())).willReturn(responses); mockMvc.perform( MockMvcRequestBuilders.get("/members/my/topics") From c1c0134afd572720ca44c79d159beea58bb79337 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Wed, 16 Aug 2023 13:47:12 +0900 Subject: [PATCH 21/22] =?UTF-8?q?fix=20:=20RestDocs=20=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/AtlasControllerTest.java | 8 ++-- .../bookmark/BookmarkIntegrationTest.java | 5 ++- .../presentation/LocationControllerTest.java | 3 +- .../presentation/MemberControllerTest.java | 15 ++++--- .../PermissionControllerTest.java | 18 ++------ .../pin/presentation/PinControllerTest.java | 42 ++++--------------- .../presentation/TopicControllerTest.java | 17 ++++---- 7 files changed, 35 insertions(+), 73 deletions(-) diff --git a/backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java index ae65c2fa..f112c176 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/atlas/presentation/AtlasControllerTest.java @@ -4,7 +4,9 @@ import com.mapbefine.mapbefine.atlas.application.AtlasCommandService; import com.mapbefine.mapbefine.common.RestDocsIntegration; +import com.mapbefine.mapbefine.common.TestAuthHeaderProvider; import org.apache.tomcat.util.codec.binary.Base64; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; @@ -15,15 +17,13 @@ class AtlasControllerTest extends RestDocsIntegration { @MockBean private AtlasCommandService atlasCommandService; - private final String authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); - @Test @DisplayName("모아보기에 지도를 추가한다") void addTopicToAtlas() throws Exception { // then mockMvc.perform( MockMvcRequestBuilders.post("/atlas/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -33,7 +33,7 @@ void removeTopicFromAtlas() throws Exception { // then mockMvc.perform( MockMvcRequestBuilders.delete("/atlas/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java b/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java index 69451e50..bbe7e6ff 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/bookmark/BookmarkIntegrationTest.java @@ -1,6 +1,6 @@ package com.mapbefine.mapbefine.bookmark; -import static io.restassured.RestAssured.*; +import static io.restassured.RestAssured.given; import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.assertj.core.api.Assertions.assertThat; @@ -14,7 +14,8 @@ import com.mapbefine.mapbefine.topic.TopicFixture; import com.mapbefine.mapbefine.topic.domain.Topic; import com.mapbefine.mapbefine.topic.domain.TopicRepository; -import io.restassured.response.*; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java index 93276f74..97b55f91 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/location/presentation/LocationControllerTest.java @@ -22,7 +22,6 @@ class LocationControllerTest extends RestDocsIntegration { @MockBean private LocationQueryService locationQueryService; - private final String authHeader = Base64.encodeBase64String("Basic member@naver.com".getBytes()); private List responses; @@ -67,7 +66,7 @@ void findNearbyTopicsSortedByPinCount() throws Exception { //then mockMvc.perform( MockMvcRequestBuilders.get("/locations/bests") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .param("latitude", String.valueOf(latitude)) .param("longitude", String.valueOf(longitude)) diff --git a/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java index 7acd8fc6..0ee0b807 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/member/presentation/MemberControllerTest.java @@ -14,6 +14,7 @@ import java.time.LocalDateTime; import java.util.List; import org.apache.tomcat.util.codec.binary.Base64; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; @@ -21,8 +22,6 @@ class MemberControllerTest extends RestDocsIntegration { - private final static String AUTH_HEADER = Base64.encodeBase64String("Basic member@naver.com".getBytes()); - @MockBean private MemberQueryService memberQueryService; @@ -46,7 +45,7 @@ void findAllMember() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/members") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -65,7 +64,7 @@ void findMemberById() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/members/1") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -100,7 +99,7 @@ void findAllTopicsInAtlas() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/members/my/atlas") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -136,7 +135,7 @@ void findAllTopicsInBookmark() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/members/my/bookmarks") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -171,7 +170,7 @@ void findMyAllTopics() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/members/my/topics") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -202,7 +201,7 @@ void findMyAllPins() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/members/my/pins") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java index e4d491e3..a9164d57 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/permission/presentation/PermissionControllerTest.java @@ -36,11 +36,10 @@ class PermissionControllerTest extends RestDocsIntegration { void addPermission() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); PermissionRequest request = new PermissionRequest(1L, List.of(1L, 2L, 3L)); - String authHeader = testAuthHeaderProvider.createAuthHeader(member); mockMvc.perform( MockMvcRequestBuilders.post("/permissions") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request)) ).andDo(restDocs.document()); @@ -50,13 +49,10 @@ void addPermission() throws Exception { @DisplayName("권한 삭제") void deletePermission() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - ("Basic " + member.getMemberInfo().getEmail()).getBytes() - ); mockMvc.perform( MockMvcRequestBuilders.delete("/permissions/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -81,15 +77,12 @@ void findAllTopicPermissions() throws Exception { ) ) ); - String authHeader = Base64.encodeBase64String( - ("Basic " + permissionResponses.get(0).memberResponse().email()).getBytes() - ); given(permissionQueryService.findAllTopicPermissions(any())).willReturn(permissionResponses); mockMvc.perform( MockMvcRequestBuilders.get("/permissions/topics/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -107,15 +100,12 @@ void findPermissionById() throws Exception { LocalDateTime.now() ) ); - String authHeader = Base64.encodeBase64String( - ("Basic " + permissionDetailResponse.memberDetailResponse().email()).getBytes() - ); given(permissionQueryService.findPermissionById(any())).willReturn(permissionDetailResponse); mockMvc.perform( MockMvcRequestBuilders.get("/permissions/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/pin/presentation/PinControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/pin/presentation/PinControllerTest.java index af543df3..a46b8399 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/pin/presentation/PinControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/pin/presentation/PinControllerTest.java @@ -30,8 +30,6 @@ class PinControllerTest extends RestDocsIntegration { - private static final String BASIC_FORMAT = "Basic %s"; - private static final List BASE_IMAGES = List.of("https://map-befine-official.github.io/favicon.png"); @MockBean @@ -44,9 +42,6 @@ class PinControllerTest extends RestDocsIntegration { @DisplayName("핀 추가") void add() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); given(pinCommandService.save(any(), any())).willReturn(1L); PinCreateRequest pinCreateRequest = new PinCreateRequest( @@ -61,7 +56,7 @@ void add() throws Exception { mockMvc.perform( MockMvcRequestBuilders.post("/pins") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(pinCreateRequest)) ).andDo(restDocs.document()); @@ -71,9 +66,6 @@ void add() throws Exception { @DisplayName("핀 수정") void update() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); PinUpdateRequest pinUpdateRequest = new PinUpdateRequest( "매튜의 안갈집", @@ -82,7 +74,7 @@ void update() throws Exception { mockMvc.perform( MockMvcRequestBuilders.put("/pins/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(pinUpdateRequest)) ).andDo(restDocs.document()); @@ -92,13 +84,10 @@ void update() throws Exception { @DisplayName("핀 삭제") void delete() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); mockMvc.perform( MockMvcRequestBuilders.delete("/pins/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -106,9 +95,6 @@ void delete() throws Exception { @DisplayName("핀 상세 조회") void findById() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); PinDetailResponse pinDetailResponse = new PinDetailResponse( 1L, @@ -126,7 +112,7 @@ void findById() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/pins/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document( requestHeaders( headerWithName(AUTHORIZATION).optional().description("Optional") @@ -138,9 +124,6 @@ void findById() throws Exception { @DisplayName("핀 목록 조회") void findAll() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); List pinResponses = List.of( new PinResponse( @@ -166,7 +149,7 @@ void findAll() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/pins") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document( requestHeaders( headerWithName(AUTHORIZATION).optional().description("Optional") @@ -177,9 +160,6 @@ void findAll() throws Exception { @DisplayName("핀 이미지 추가") void addImage() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); PinImageCreateRequest pinImageCreateRequest = new PinImageCreateRequest( 1L, @@ -188,7 +168,7 @@ void addImage() throws Exception { mockMvc.perform( MockMvcRequestBuilders.post("/pins/images") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(pinImageCreateRequest)) ).andDo(restDocs.document()); @@ -198,13 +178,10 @@ void addImage() throws Exception { @DisplayName("핀 이미지 삭제") void removeImage() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); mockMvc.perform( MockMvcRequestBuilders.delete("/pins/images/1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) ).andDo(restDocs.document()); } @@ -214,9 +191,6 @@ void removeImage() throws Exception { @DisplayName("멤버 Id를 입력하면 해당 멤버가 만든 핀 목록을 조회할 수 있다.") void findAllPinsByMemberId() throws Exception { Member member = MemberFixture.create("member", "member@naver.com", Role.ADMIN); - String authHeader = Base64.encodeBase64String( - String.format(BASIC_FORMAT, member.getMemberInfo().getEmail()).getBytes() - ); List pinResponses = List.of( new PinResponse( @@ -243,7 +217,7 @@ void findAllPinsByMemberId() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/pins/members?id=1") - .header(AUTHORIZATION, authHeader) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } diff --git a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java index 34c5fe0d..bab5fa2d 100644 --- a/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java +++ b/backend/src/test/java/com/mapbefine/mapbefine/topic/presentation/TopicControllerTest.java @@ -26,7 +26,6 @@ class TopicControllerTest extends RestDocsIntegration { // TODO: 2023/07/25 Image 칼람 추가됨으로 인해 수정 필요 - private static final String AUTH_HEADER = Base64.encodeBase64String("Basic member@naver.com".getBytes()); private static final List RESPONSES = List.of(new TopicResponse( 1L, "준팍의 또 토픽", @@ -71,7 +70,7 @@ void create() throws Exception { mockMvc.perform( MockMvcRequestBuilders.post("/topics/new") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(topicCreateRequest)) ).andDo(restDocs.document()); @@ -94,7 +93,7 @@ void mergeAndCreate() throws Exception { mockMvc.perform( MockMvcRequestBuilders.post("/topics/merge") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(topicMergeRequest)) ).andDo(restDocs.document()); @@ -114,7 +113,7 @@ void update() throws Exception { mockMvc.perform( MockMvcRequestBuilders.put("/topics/1") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(topicUpdateRequest)) ).andDo(restDocs.document()); @@ -126,7 +125,7 @@ void delete() throws Exception { mockMvc.perform( MockMvcRequestBuilders.delete("/topics/1") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -139,7 +138,7 @@ void findAll() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/topics") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -181,7 +180,7 @@ void findById() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/topics/1") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -192,7 +191,7 @@ void findAllByOrderByUpdatedAtDesc() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/topics/newest") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } @@ -203,7 +202,7 @@ void findAllTopicsByMemberId() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get("/topics/members?id=1") - .header(AUTHORIZATION, AUTH_HEADER) + .header(AUTHORIZATION, testAuthHeaderProvider.createAuthHeaderById(1L)) ).andDo(restDocs.document()); } From be05418a1e477135867524bf4e2580c01755bae7 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Wed, 16 Aug 2023 13:50:54 +0900 Subject: [PATCH 22/22] =?UTF-8?q?refactor=20:=20validateMember=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapbefine/common/interceptor/AuthInterceptor.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java b/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java index aac1ae1a..fafbb298 100644 --- a/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java +++ b/backend/src/main/java/com/mapbefine/mapbefine/common/interceptor/AuthInterceptor.java @@ -49,17 +49,18 @@ public boolean preHandle( if (isLoginRequired((HandlerMethod) handler)) { // TODO: 2023/08/11 isMember false이면 403 반환 - boolean isMember = authService.isMember(memberId); - validateMember(isMember); + validateMember(memberId); } return true; } - private void validateMember(boolean isMember) { - if (!isMember) { - throw new IllegalArgumentException("조회되지 않는 회원입니다."); + private void validateMember(Long memberId) { + if (authService.isMember(memberId)) { + return; } + + throw new IllegalArgumentException("조회되지 않는 회원입니다."); } private boolean isAuthMemberNotRequired(HandlerMethod handlerMethod) {