From d7acfa937a55b7ac30f38aaaebabde64d399fbb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9A=B0=EC=9E=AC?= Date: Tue, 12 Oct 2021 01:15:53 +0900 Subject: [PATCH] =?UTF-8?q?[#54]=20temp:=20vo=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=EC=83=9D=EC=84=B1=EC=9E=90=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../follow/application/FollowService.java | 39 ++++++++++++++++++- .../follow/domain/FollowRepository.java | 4 ++ .../domain/follow/domain/Followings.java | 38 ++++++++++++++++++ .../domain/user/domain/persist/User.java | 11 +++--- .../follow/application/FollowServiceTest.java | 4 +- .../domain/user/domain/persist/UserTest.java | 7 ++-- 6 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/study/realworld/domain/follow/domain/Followings.java diff --git a/src/main/java/com/study/realworld/domain/follow/application/FollowService.java b/src/main/java/com/study/realworld/domain/follow/application/FollowService.java index 2d2be9b7..3ece95d7 100644 --- a/src/main/java/com/study/realworld/domain/follow/application/FollowService.java +++ b/src/main/java/com/study/realworld/domain/follow/application/FollowService.java @@ -1,18 +1,55 @@ package com.study.realworld.domain.follow.application; +import com.study.realworld.domain.follow.domain.Follow; import com.study.realworld.domain.follow.domain.FollowQueryDslRepository; import com.study.realworld.domain.follow.domain.FollowRepository; +import com.study.realworld.domain.follow.dto.FollowableDto; +import com.study.realworld.domain.user.domain.persist.User; +import com.study.realworld.domain.user.domain.persist.UserRepository; +import com.study.realworld.domain.user.error.exception.IdentityNotFoundException; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +@Transactional(readOnly = true) @Service public class FollowService { + private final UserRepository userRepository; private final FollowRepository followRepository; private final FollowQueryDslRepository followQueryDslRepository; - public FollowService(final FollowRepository followRepository, final FollowQueryDslRepository followQueryDslRepository) { + public FollowService(final UserRepository userRepository, final FollowRepository followRepository, final FollowQueryDslRepository followQueryDslRepository) { + this.userRepository = userRepository; this.followRepository = followRepository; this.followQueryDslRepository = followQueryDslRepository; } + public Follow following(final Long myId, final Long targetId) { + final User me = findUserById(myId); + final User target = findUserById(targetId); + final Follow follow = follow(target, me); + me.addFollowing(follow); + return followRepository.save(follow); + } + + public User unfollowing(final Long myId, final Long targetId) { + final User me = findUserById(myId); + final User target = findUserById(targetId); + final Follow follow = followRepository.findByFollowingAndFollower(target, me).orElseThrow(IllegalArgumentException::new); + followRepository.delete(follow); + return me; + } + + private Follow follow(final User following, final User follower) { + return Follow.Builder() + .following(following) + .follower(follower) + .build(); + } + + private User findUserById(final Long id) { + return userRepository.findById(id).orElseThrow(() -> new IdentityNotFoundException(id)); + } + + } diff --git a/src/main/java/com/study/realworld/domain/follow/domain/FollowRepository.java b/src/main/java/com/study/realworld/domain/follow/domain/FollowRepository.java index 36913e40..8ee72409 100644 --- a/src/main/java/com/study/realworld/domain/follow/domain/FollowRepository.java +++ b/src/main/java/com/study/realworld/domain/follow/domain/FollowRepository.java @@ -1,9 +1,13 @@ package com.study.realworld.domain.follow.domain; +import com.study.realworld.domain.user.domain.persist.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface FollowRepository extends JpaRepository { + Optional findByFollowingAndFollower(User following, User follower); } diff --git a/src/main/java/com/study/realworld/domain/follow/domain/Followings.java b/src/main/java/com/study/realworld/domain/follow/domain/Followings.java new file mode 100644 index 00000000..751fac1a --- /dev/null +++ b/src/main/java/com/study/realworld/domain/follow/domain/Followings.java @@ -0,0 +1,38 @@ +package com.study.realworld.domain.follow.domain; + +import javax.persistence.CascadeType; +import javax.persistence.Embeddable; +import javax.persistence.OneToMany; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +@Embeddable +public class Followings { + + @OneToMany(mappedBy = "following", cascade = CascadeType.ALL, orphanRemoval = true) + private Set followings = new HashSet<>(); + + public Followings() { + } + + public Followings(final Set followings) { + this.followings = followings; + } + + public void add(final Follow following) { + validateArgumentNull(following); + followings.add(following); + } + + private void validateArgumentNull(final Follow following) { + if(Objects.isNull(following)) { + throw new IllegalArgumentException(); + } + } + + public Set getFollowings() { + return followings; + } + +} diff --git a/src/main/java/com/study/realworld/domain/user/domain/persist/User.java b/src/main/java/com/study/realworld/domain/user/domain/persist/User.java index d0b5e2b5..6d080216 100644 --- a/src/main/java/com/study/realworld/domain/user/domain/persist/User.java +++ b/src/main/java/com/study/realworld/domain/user/domain/persist/User.java @@ -2,13 +2,13 @@ import com.study.realworld.domain.BaseTimeEntity; import com.study.realworld.domain.follow.domain.Follow; +import com.study.realworld.domain.follow.domain.Followings; import com.study.realworld.domain.user.domain.vo.*; import com.study.realworld.domain.user.error.exception.PasswordMissMatchException; import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; -import java.util.HashSet; import java.util.Set; import static java.util.Objects.isNull; @@ -48,8 +48,8 @@ public class User extends BaseTimeEntity { @Column(name = "image")) private Image image; - @OneToMany(mappedBy = "following") - private Set followings = new HashSet<>(); + @Embedded + private Followings followings = new Followings(); protected User() { } @@ -91,8 +91,7 @@ public User changeImage(final Image image) { return this; } - public User addfollowing(final Follow following) { - validateArgumentNull(following); + public User addFollowing(final Follow following) { followings.add(following); following.changeFollower(this); return this; @@ -128,7 +127,7 @@ public Password password() { return password; } - public Set followings() { + public Followings followings() { return followings; } diff --git a/src/test/java/com/study/realworld/domain/follow/application/FollowServiceTest.java b/src/test/java/com/study/realworld/domain/follow/application/FollowServiceTest.java index 046ab19e..97aa3bdc 100644 --- a/src/test/java/com/study/realworld/domain/follow/application/FollowServiceTest.java +++ b/src/test/java/com/study/realworld/domain/follow/application/FollowServiceTest.java @@ -2,6 +2,7 @@ import com.study.realworld.domain.follow.domain.FollowQueryDslRepository; import com.study.realworld.domain.follow.domain.FollowRepository; +import com.study.realworld.domain.user.domain.persist.UserRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -14,13 +15,14 @@ @ExtendWith(MockitoExtension.class) class FollowServiceTest { + @Mock private UserRepository userRepository; @Mock private FollowRepository followRepository; @Mock private FollowQueryDslRepository followQueryDslRepository; @DisplayName("FollowService 인스턴스 생성자 테스트") @Test void constructor_test() { - final FollowService followService = new FollowService(followRepository, followQueryDslRepository); + final FollowService followService = new FollowService(userRepository, followRepository, followQueryDslRepository); assertAll( () -> assertThat(followService).isNotNull(), diff --git a/src/test/java/com/study/realworld/domain/user/domain/persist/UserTest.java b/src/test/java/com/study/realworld/domain/user/domain/persist/UserTest.java index a11b0dbe..648032e1 100644 --- a/src/test/java/com/study/realworld/domain/user/domain/persist/UserTest.java +++ b/src/test/java/com/study/realworld/domain/user/domain/persist/UserTest.java @@ -1,7 +1,6 @@ package com.study.realworld.domain.user.domain.persist; import com.study.realworld.domain.follow.domain.Follow; -import com.study.realworld.domain.user.domain.persist.User; import com.study.realworld.domain.user.domain.vo.*; import com.study.realworld.domain.user.error.exception.PasswordMissMatchException; import org.junit.jupiter.api.DisplayName; @@ -106,11 +105,11 @@ void following_test() { final User following = userBuilder(new Email(EMAIL), new Name(USERNAME), new Password(PASSWORD), new Bio(BIO), new Image(IMAGE)); final User follower = userBuilder(new Email("Email2@email.com"), new Name("differentUserName"), new Password("Password2"), new Bio("Bio2"), new Image("Image2")); final Follow follow = followBuilder(following, follower); - follower.addfollowing(follow); + follower.addFollowing(follow); assertAll( - () -> assertThat(follower.followings().size()).isEqualTo(1), - () -> assertThat(follower.followings().contains(follow)).isTrue() + () -> assertThat(follower.followings().getFollowings().size()).isEqualTo(1), + () -> assertThat(follower.followings().getFollowings().contains(follow)).isTrue() ); }