diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..82252c7 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,6 @@ +# 관련 이슈 + +# 변경 사항 +1. + +# 참고 사항 \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follow/controller/FollowController.kt b/sns_service/src/main/kotlin/joryu/sns_service/follow/controller/FollowController.kt new file mode 100644 index 0000000..bae7c11 --- /dev/null +++ b/sns_service/src/main/kotlin/joryu/sns_service/follow/controller/FollowController.kt @@ -0,0 +1,26 @@ +package joryu.sns_service.follow.controller + +import joryu.sns_service.follow.dto.request.FollowRequest +import joryu.sns_service.follow.dto.request.UnFollowRequest +import joryu.sns_service.follow.service.FollowService +import lombok.RequiredArgsConstructor +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/follow") +class FollowController( + private val followService: FollowService +) { + @PostMapping("/{fromProfileId}") + fun follow(@PathVariable("fromProfileId") fromProfileId: Long, @RequestBody followRequest: FollowRequest): ResponseEntity { + followService.follow(fromProfileId, followRequest.toProfileId) + return ResponseEntity.ok().build() + } + + @DeleteMapping("/{fromProfileId}") + fun unFollow(@PathVariable("fromProfileId") fromProfileId: Long, @RequestBody unFollowRequest: UnFollowRequest): ResponseEntity { + followService.unFollow(fromProfileId, unFollowRequest.toProfileId) + return ResponseEntity.ok().build() + } +} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follow/dto/request/FollowRequest.kt b/sns_service/src/main/kotlin/joryu/sns_service/follow/dto/request/FollowRequest.kt new file mode 100644 index 0000000..a7657c1 --- /dev/null +++ b/sns_service/src/main/kotlin/joryu/sns_service/follow/dto/request/FollowRequest.kt @@ -0,0 +1,4 @@ +package joryu.sns_service.follow.dto.request + +data class FollowRequest(val toProfileId: Long) { +} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follow/dto/request/UnFollowRequest.kt b/sns_service/src/main/kotlin/joryu/sns_service/follow/dto/request/UnFollowRequest.kt new file mode 100644 index 0000000..fd0b627 --- /dev/null +++ b/sns_service/src/main/kotlin/joryu/sns_service/follow/dto/request/UnFollowRequest.kt @@ -0,0 +1,4 @@ +package joryu.sns_service.follow.dto.request + +data class UnFollowRequest(val toProfileId: Long) { +} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follow/entity/Follow.kt b/sns_service/src/main/kotlin/joryu/sns_service/follow/entity/Follow.kt new file mode 100644 index 0000000..26238d7 --- /dev/null +++ b/sns_service/src/main/kotlin/joryu/sns_service/follow/entity/Follow.kt @@ -0,0 +1,28 @@ +package joryu.sns_service.follow.entity + +import jakarta.persistence.* +import joryu.sns_service.common.entity.BaseEntity +import joryu.sns_service.profile.entity.Profile + +@Table(name = "follow") +@Entity +class Follow( + @Id + @Column(name = "follow_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long?, + + @ManyToOne + @JoinColumn + val fromProfile: Profile?, + + @ManyToOne + @JoinColumn + val toProfile: Profile? +) : BaseEntity() { + constructor() : this(null, null, null) + constructor(fromProfile: Profile, toProfile: Profile) : this(null, fromProfile, toProfile) { + toProfile.addFollower(this) + fromProfile.addFollowing(this) + } +} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follow/repository/FollowRepository.kt b/sns_service/src/main/kotlin/joryu/sns_service/follow/repository/FollowRepository.kt new file mode 100644 index 0000000..ec99374 --- /dev/null +++ b/sns_service/src/main/kotlin/joryu/sns_service/follow/repository/FollowRepository.kt @@ -0,0 +1,11 @@ +package joryu.sns_service.follow.repository + +import joryu.sns_service.follow.entity.Follow +import joryu.sns_service.profile.entity.Profile +import org.springframework.data.jpa.repository.JpaRepository + +interface FollowRepository : JpaRepository { + fun deleteByFromProfileAndToProfile(fromProfile: Profile, toProfile: Profile) + fun findAllByToProfile(toProfile: Profile): MutableList + fun findAllByFromProfile(fromProfile: Profile): MutableList +} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follow/service/FollowService.kt b/sns_service/src/main/kotlin/joryu/sns_service/follow/service/FollowService.kt new file mode 100644 index 0000000..9d1542c --- /dev/null +++ b/sns_service/src/main/kotlin/joryu/sns_service/follow/service/FollowService.kt @@ -0,0 +1,37 @@ +package joryu.sns_service.follow.service + +import joryu.sns_service.follow.entity.Follow +import joryu.sns_service.follow.repository.FollowRepository +import joryu.sns_service.profile.exception.ProfileBaseException +import joryu.sns_service.profile.exception.ProfileExceptionEnums +import joryu.sns_service.profile.repository.ProfileRepository +import lombok.RequiredArgsConstructor +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +@RequiredArgsConstructor +class FollowService( + private val followRepository: FollowRepository, + private val profileRepository: ProfileRepository +) { + + @Transactional + fun follow(fromProfileId: Long, toProfileId: Long) { + val fromProfile = profileRepository.findById(fromProfileId) + .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } + val toProfile = profileRepository.findById(toProfileId) + .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } + val follow = Follow(fromProfile, toProfile) + followRepository.save(follow) + } + + @Transactional + fun unFollow(fromProfileId: Long, toProfileId: Long) { + val fromProfile = profileRepository.findById(fromProfileId) + .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } + val toProfile = profileRepository.findById(toProfileId) + .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } + followRepository.deleteByFromProfileAndToProfile(fromProfile, toProfile) + } +} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follower/controller/FollowerController.kt b/sns_service/src/main/kotlin/joryu/sns_service/follower/controller/FollowerController.kt deleted file mode 100644 index 9d1b0a2..0000000 --- a/sns_service/src/main/kotlin/joryu/sns_service/follower/controller/FollowerController.kt +++ /dev/null @@ -1,40 +0,0 @@ -package joryu.sns_service.follower.controller - -import joryu.sns_service.follower.dto.request.FollowRequest -import joryu.sns_service.follower.dto.request.UnFollowRequest -import joryu.sns_service.follower.dto.response.AllFollowingProfilesResponse -import joryu.sns_service.follower.entity.Follower -import joryu.sns_service.follower.service.FollowerService -import lombok.RequiredArgsConstructor -import org.springframework.http.ResponseEntity -import org.springframework.stereotype.Controller -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.RequestBody -import org.springframework.web.bind.annotation.RequestMapping - -@Controller -@RequestMapping("/follow") -@RequiredArgsConstructor -class FollowerController( - private val followerService: FollowerService -) { - @PostMapping("/{followerProfileId}") - fun follow(@PathVariable("followerProfileId") followerProfileId: Long, @RequestBody followRequest: FollowRequest): ResponseEntity { - followerService.followUp(followerProfileId, followRequest) - return ResponseEntity.ok().build() - } - - @DeleteMapping("/{followerProfileId}") - fun unFollow(@PathVariable("followerProfileId") followerProfileId: Long, @RequestBody unFollowRequest: UnFollowRequest): ResponseEntity { - followerService.unFollow(followerProfileId, unFollowRequest) - return ResponseEntity.ok().build() - } - - @GetMapping("/{followerProfileId}") - fun findAllFollowersByProfileId(@PathVariable("followerProfileId") followerProfileId: Long): ResponseEntity> { - return ResponseEntity.ok().body(followerService.getAllFollowingProfileByFollowerId(followerProfileId)) - } -} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/request/FollowRequest.kt b/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/request/FollowRequest.kt deleted file mode 100644 index 2842fd8..0000000 --- a/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/request/FollowRequest.kt +++ /dev/null @@ -1,4 +0,0 @@ -package joryu.sns_service.follower.dto.request - -data class FollowRequest(val profileId: Long) { -} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/request/UnFollowRequest.kt b/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/request/UnFollowRequest.kt deleted file mode 100644 index adc3d29..0000000 --- a/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/request/UnFollowRequest.kt +++ /dev/null @@ -1,4 +0,0 @@ -package joryu.sns_service.follower.dto.request - -data class UnFollowRequest(val profileId: Long) { -} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/response/AllFollowingProfilesResponse.kt b/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/response/AllFollowingProfilesResponse.kt deleted file mode 100644 index 1a46371..0000000 --- a/sns_service/src/main/kotlin/joryu/sns_service/follower/dto/response/AllFollowingProfilesResponse.kt +++ /dev/null @@ -1,4 +0,0 @@ -package joryu.sns_service.follower.dto.response - -data class AllFollowingProfilesResponse(val profileId: Long) { -} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follower/entity/Follower.kt b/sns_service/src/main/kotlin/joryu/sns_service/follower/entity/Follower.kt deleted file mode 100644 index 1b08a77..0000000 --- a/sns_service/src/main/kotlin/joryu/sns_service/follower/entity/Follower.kt +++ /dev/null @@ -1,25 +0,0 @@ -package joryu.sns_service.follower.entity - -import jakarta.persistence.* -import joryu.sns_service.profile.entity.Profile - -@Table(name = "follower") -@Entity -data class Follower( - @Id - @Column(name = "follower_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long?, - - @ManyToOne - @JoinColumn(name = "profile_id") - val followingProfile: Profile?, - - @Column(name = "follower_profile_id") - val followerProfileId: Long? -) { - constructor() : this(null, null, null) - constructor(followingProfile: Profile, followerProfileId: Long) : this(null, followingProfile, followerProfileId) { - followingProfile.addFollower(this) - } -} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follower/repository/FollowerRepository.kt b/sns_service/src/main/kotlin/joryu/sns_service/follower/repository/FollowerRepository.kt deleted file mode 100644 index 8518fac..0000000 --- a/sns_service/src/main/kotlin/joryu/sns_service/follower/repository/FollowerRepository.kt +++ /dev/null @@ -1,10 +0,0 @@ -package joryu.sns_service.follower.repository - -import joryu.sns_service.follower.entity.Follower -import joryu.sns_service.profile.entity.Profile -import org.springframework.data.jpa.repository.JpaRepository - -interface FollowerRepository : JpaRepository { - fun findAllByFollowerProfileId(followerProfileId: Long): MutableList - fun deleteByFollowingProfileAndFollowerProfileId(profile: Profile, followerProfileId: Long) -} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/follower/service/FollowerService.kt b/sns_service/src/main/kotlin/joryu/sns_service/follower/service/FollowerService.kt deleted file mode 100644 index 3ddb605..0000000 --- a/sns_service/src/main/kotlin/joryu/sns_service/follower/service/FollowerService.kt +++ /dev/null @@ -1,43 +0,0 @@ -package joryu.sns_service.follower.service - -import joryu.sns_service.follower.dto.request.FollowRequest -import joryu.sns_service.follower.dto.request.UnFollowRequest -import joryu.sns_service.follower.dto.response.AllFollowingProfilesResponse -import joryu.sns_service.follower.entity.Follower -import joryu.sns_service.follower.repository.FollowerRepository -import joryu.sns_service.profile.exception.ProfileBaseException -import joryu.sns_service.profile.exception.ProfileExceptionEnums -import joryu.sns_service.profile.repository.ProfileRepository -import lombok.RequiredArgsConstructor -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional - -@Service -@RequiredArgsConstructor -class FollowerService( - private val followerRepository: FollowerRepository, - private val profileRepository: ProfileRepository -) { - - @Transactional - fun followUp(followerProfileId: Long, followRequest: FollowRequest) { - val requestProfile = profileRepository.findById(followRequest.profileId) - .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } - val follower = Follower(requestProfile, followerProfileId) - followerRepository.save(follower) - } - - @Transactional - fun unFollow(followerProfileId: Long, unFollowRequest: UnFollowRequest) { - val requestProfile = profileRepository.findById(unFollowRequest.profileId) - .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } - followerRepository.deleteByFollowingProfileAndFollowerProfileId(requestProfile, followerProfileId) - } - - @Transactional(readOnly = true) - fun getAllFollowingProfileByFollowerId(followerProfileId: Long) : List { - val followingProfiles : MutableList = followerRepository.findAllByFollowerProfileId(followerProfileId) - return followingProfiles.map { profile -> profile.followingProfile?.let { AllFollowingProfilesResponse(it.id) } } - } - -} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/profile/controller/ProfileApiController.kt b/sns_service/src/main/kotlin/joryu/sns_service/profile/controller/ProfileApiController.kt index d9b1eda..6e0a418 100644 --- a/sns_service/src/main/kotlin/joryu/sns_service/profile/controller/ProfileApiController.kt +++ b/sns_service/src/main/kotlin/joryu/sns_service/profile/controller/ProfileApiController.kt @@ -2,16 +2,15 @@ package joryu.sns_service.profile.controller import joryu.sns_service.profile.dto.request.ProfileCreateRequest import joryu.sns_service.profile.dto.request.ProfileUpdateRequest +import joryu.sns_service.profile.dto.response.AllProfileResponse import joryu.sns_service.profile.dto.response.ProfileInfoResponse -import joryu.sns_service.profile.entity.Profile import joryu.sns_service.profile.service.ProfileService import lombok.RequiredArgsConstructor import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity -import org.springframework.stereotype.Controller import org.springframework.web.bind.annotation.* -@Controller +@RestController @RequestMapping("/profile") @RequiredArgsConstructor class ProfileApiController( @@ -19,21 +18,21 @@ class ProfileApiController( ) { @PostMapping() - fun createProfile(@RequestBody profileCreateRequest: ProfileCreateRequest): ResponseEntity { - val profile = profileService.create(profileCreateRequest) - return ResponseEntity(profile, HttpStatus.OK) + fun createProfile(@RequestBody profileCreateRequest: ProfileCreateRequest): ResponseEntity { + val profileInfo = profileService.create(profileCreateRequest) + return ResponseEntity(profileInfo, HttpStatus.OK) } @GetMapping("/{id}") fun findProfile(@PathVariable id: Long): ResponseEntity { - val profile = profileService.findOneById(id) - return ResponseEntity(profile, HttpStatus.OK) + val profileInfo = profileService.findOneById(id) + return ResponseEntity(profileInfo, HttpStatus.OK) } @PutMapping("/{id}") fun updateProfile(@PathVariable id: Long, @RequestBody profileUpdateRequest: ProfileUpdateRequest): ResponseEntity { - val profile = profileService.update(id, profileUpdateRequest) - return ResponseEntity(profile, HttpStatus.OK) + val profileInfo = profileService.update(id, profileUpdateRequest) + return ResponseEntity(profileInfo, HttpStatus.OK) } @DeleteMapping("/{id}") @@ -41,4 +40,16 @@ class ProfileApiController( profileService.delete(id) return ResponseEntity.ok().build() } + + @GetMapping("/follower/{id}") + fun findAllFollowerProfiles(@PathVariable id: Long): ResponseEntity { + val profiles = profileService.findAllFollowerProfileInfo(id) + return ResponseEntity(profiles, HttpStatus.OK) + } + + @GetMapping("/following/{id}") + fun findAllFollowingProfiles(@PathVariable id: Long): ResponseEntity { + val profiles = profileService.findAllFollowingProfileInfo(id) + return ResponseEntity(profiles, HttpStatus.OK) + } } \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/profile/dto/response/AllFollowerProfileResponse.kt b/sns_service/src/main/kotlin/joryu/sns_service/profile/dto/response/AllFollowerProfileResponse.kt new file mode 100644 index 0000000..712d116 --- /dev/null +++ b/sns_service/src/main/kotlin/joryu/sns_service/profile/dto/response/AllFollowerProfileResponse.kt @@ -0,0 +1,13 @@ +package joryu.sns_service.profile.dto.response + +import joryu.sns_service.profile.entity.Profile + +data class AllProfileResponse( + val profileInfo: MutableList = mutableListOf() +) { + + fun addProfileInfoInFollows(profiles: List): AllProfileResponse { + profiles.forEach { profile -> profileInfo.add(ProfileInfoResponse(profile)) } + return this + } +} \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/profile/dto/response/ProfileInfoResponse.kt b/sns_service/src/main/kotlin/joryu/sns_service/profile/dto/response/ProfileInfoResponse.kt index ed3fdc9..bbf751c 100644 --- a/sns_service/src/main/kotlin/joryu/sns_service/profile/dto/response/ProfileInfoResponse.kt +++ b/sns_service/src/main/kotlin/joryu/sns_service/profile/dto/response/ProfileInfoResponse.kt @@ -2,6 +2,10 @@ package joryu.sns_service.profile.dto.response import joryu.sns_service.profile.entity.Profile -data class ProfileInfoResponse(val name: String) { - constructor(profile: Profile): this(profile.name) +data class ProfileInfoResponse( + val name: String?, + val followerNumber: Int?, + val followingNumber: Int? +) { + constructor(profile: Profile?) : this(profile?.name, profile?.followerNumber, profile?.followingNumber) } \ No newline at end of file diff --git a/sns_service/src/main/kotlin/joryu/sns_service/profile/entity/Profile.kt b/sns_service/src/main/kotlin/joryu/sns_service/profile/entity/Profile.kt index d414c2f..97de07c 100644 --- a/sns_service/src/main/kotlin/joryu/sns_service/profile/entity/Profile.kt +++ b/sns_service/src/main/kotlin/joryu/sns_service/profile/entity/Profile.kt @@ -1,30 +1,42 @@ package joryu.sns_service.profile.entity import jakarta.persistence.* -import joryu.sns_service.follower.entity.Follower +import joryu.sns_service.common.entity.BaseEntity +import joryu.sns_service.follow.entity.Follow import joryu.sns_service.profile.dto.request.ProfileUpdateRequest @Table(name = "profile") @Entity -data class Profile( +class Profile( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "profile_id") val id: Long, + @Column(name = "name") var name: String, + @Column(name = "follower_number") + var followerNumber: Int, + @Column(name = "following_number") + var followingNumber: Int, - @OneToMany(mappedBy = "followingProfile") - val followers: MutableList = mutableListOf() -) { - constructor() : this(0, "") - constructor(name: String) : this(0, name) + + @OneToMany(mappedBy = "fromProfile") + val followers: MutableList = mutableListOf(), + @OneToMany(mappedBy = "toProfile") + val followings: MutableList = mutableListOf() +) : BaseEntity() { + constructor() : this(0, "", 0, 0) + constructor(name: String) : this(0, name, 0, 0) fun update(profileUpdateRequest: ProfileUpdateRequest) { this.name = profileUpdateRequest.name } + fun addFollower(follow: Follow) { + this.followerNumber++ + } - fun addFollower(follower: Follower) { - followers.add(follower) + fun addFollowing(following: Follow) { + this.followingNumber++ } } diff --git a/sns_service/src/main/kotlin/joryu/sns_service/profile/service/ProfileService.kt b/sns_service/src/main/kotlin/joryu/sns_service/profile/service/ProfileService.kt index 17f7e3e..f785c09 100644 --- a/sns_service/src/main/kotlin/joryu/sns_service/profile/service/ProfileService.kt +++ b/sns_service/src/main/kotlin/joryu/sns_service/profile/service/ProfileService.kt @@ -1,7 +1,9 @@ package joryu.sns_service.profile.service +import joryu.sns_service.follow.repository.FollowRepository import joryu.sns_service.profile.dto.request.ProfileCreateRequest import joryu.sns_service.profile.dto.request.ProfileUpdateRequest +import joryu.sns_service.profile.dto.response.AllProfileResponse import joryu.sns_service.profile.dto.response.ProfileInfoResponse import joryu.sns_service.profile.entity.Profile import joryu.sns_service.profile.exception.ProfileBaseException @@ -15,13 +17,14 @@ import org.springframework.transaction.annotation.Transactional @RequiredArgsConstructor class ProfileService( private val profileRepository: ProfileRepository, + private val followRepository: FollowRepository ) { @Transactional - fun create(profileCreateRequest: ProfileCreateRequest) : Profile{ + fun create(profileCreateRequest: ProfileCreateRequest): ProfileInfoResponse { val profile = Profile(profileCreateRequest.name) profileRepository.save(profile) - return profile + return ProfileInfoResponse(profile) } @Transactional(readOnly = true) @@ -33,7 +36,7 @@ class ProfileService( @Transactional fun update(id: Long, profileUpdateRequest: ProfileUpdateRequest): ProfileInfoResponse { - var profile = profileRepository.findById(id) + val profile = profileRepository.findById(id) .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } profile.update(profileUpdateRequest) return ProfileInfoResponse(profile) @@ -41,8 +44,28 @@ class ProfileService( @Transactional fun delete(id: Long) { - var profile = profileRepository.findById(id) + val profile = profileRepository.findById(id) .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } profileRepository.delete(profile); } + + @Transactional(readOnly = true) + fun findAllFollowerProfileInfo(id: Long): AllProfileResponse { + val profile = profileRepository.findById(id) + .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } + val followers = followRepository.findAllByToProfile(profile).stream() + .map { follows -> follows.fromProfile } + .toList() + return AllProfileResponse().addProfileInfoInFollows(followers) + } + + @Transactional(readOnly = true) + fun findAllFollowingProfileInfo(id: Long): AllProfileResponse { + val profile = profileRepository.findById(id) + .orElseThrow { ProfileBaseException(ProfileExceptionEnums.PROFILE_NOT_FOUND) } + val followings = followRepository.findAllByFromProfile(profile).stream() + .map { follows -> follows.toProfile } + .toList() + return AllProfileResponse().addProfileInfoInFollows(followings) + } } \ No newline at end of file diff --git a/sns_service/src/test/kotlin/joryu/sns_service/follow/entity/FollowTest.kt b/sns_service/src/test/kotlin/joryu/sns_service/follow/entity/FollowTest.kt new file mode 100644 index 0000000..5a04622 --- /dev/null +++ b/sns_service/src/test/kotlin/joryu/sns_service/follow/entity/FollowTest.kt @@ -0,0 +1,27 @@ +package joryu.sns_service.follow.entity + +import joryu.sns_service.profile.entity.Profile +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.springframework.boot.test.context.SpringBootTest + +@SpringBootTest +class FollowTest { + + @Test + fun `follow 생성`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + + // when + val follow = Follow(fromProfile, toProfile) + + // then + assertEquals(follow.fromProfile, fromProfile) + assertEquals(follow.toProfile, toProfile) + assertEquals(fromProfile.followingNumber, 1) + assertEquals(toProfile.followerNumber, 1) + } +} \ No newline at end of file diff --git a/sns_service/src/test/kotlin/joryu/sns_service/follow/repository/FollowRepositoryTest.kt b/sns_service/src/test/kotlin/joryu/sns_service/follow/repository/FollowRepositoryTest.kt new file mode 100644 index 0000000..85c8dd5 --- /dev/null +++ b/sns_service/src/test/kotlin/joryu/sns_service/follow/repository/FollowRepositoryTest.kt @@ -0,0 +1,84 @@ +package joryu.sns_service.follow.repository + +import joryu.sns_service.follow.entity.Follow +import joryu.sns_service.profile.entity.Profile +import joryu.sns_service.profile.repository.ProfileRepository +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.transaction.annotation.Transactional + +@SpringBootTest +@Transactional +class FollowRepositoryTest( + @Autowired + private val followRepository: FollowRepository, + @Autowired + private val profileRepository: ProfileRepository +) { + + @Test + fun `follow 저장`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + + // when + followRepository.save(follow) + + // then + } + + @Test + fun `fromProfile과 toProfile로 follow 삭제 성공`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + profileRepository.save(fromProfile) + profileRepository.save(toProfile) + followRepository.save(follow) + + // when + followRepository.deleteByFromProfileAndToProfile(fromProfile, toProfile) + + // then + } + + @Test + fun `fromProfile로 follow 조회 성공`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + profileRepository.save(fromProfile) + profileRepository.save(toProfile) + followRepository.save(follow) + + // when + val findFollow = followRepository.findAllByFromProfile(fromProfile)[0] + + // then + Assertions.assertEquals(findFollow, follow) + } + + @Test + fun `toProfile로 follow 조회 성공`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + profileRepository.save(fromProfile) + profileRepository.save(toProfile) + followRepository.save(follow) + + // when + val findFollow = followRepository.findAllByToProfile(toProfile)[0] + + // then + Assertions.assertEquals(findFollow, follow) + } + +} \ No newline at end of file diff --git a/sns_service/src/test/kotlin/joryu/sns_service/follow/service/FollowServiceTest.kt b/sns_service/src/test/kotlin/joryu/sns_service/follow/service/FollowServiceTest.kt new file mode 100644 index 0000000..41592f6 --- /dev/null +++ b/sns_service/src/test/kotlin/joryu/sns_service/follow/service/FollowServiceTest.kt @@ -0,0 +1,84 @@ +package joryu.sns_service.follow.service + +import joryu.sns_service.follow.entity.Follow +import joryu.sns_service.follow.repository.FollowRepository +import joryu.sns_service.profile.entity.Profile +import joryu.sns_service.profile.exception.ProfileBaseException +import joryu.sns_service.profile.repository.ProfileRepository +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.transaction.annotation.Transactional + +@SpringBootTest +@Transactional +class FollowServiceTest ( + @Autowired + private val followService: FollowService, + @Autowired + private val followRepository: FollowRepository, + @Autowired + private val profileRepository: ProfileRepository +){ + + @Test + fun `팔로우 성공`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + profileRepository.save(fromProfile) + profileRepository.save(toProfile) + + // when + followService.follow(fromProfile.id, toProfile.id) + + // then + } + + @Test + fun `팔로우 실패`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + followService.follow(fromProfile.id, toProfile.id) + } + } + + @Test + fun `언팔로우 성공`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + profileRepository.save(fromProfile) + profileRepository.save(toProfile) + followRepository.save(follow) + + // when + followService.unFollow(fromProfile.id, toProfile.id) + + // then + } + + @Test + fun `언팔로우 실패`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + followService.unFollow(fromProfile.id, toProfile.id) + } + } +} \ No newline at end of file diff --git a/sns_service/src/test/kotlin/joryu/sns_service/profile/entity/ProfileTest.kt b/sns_service/src/test/kotlin/joryu/sns_service/profile/entity/ProfileTest.kt new file mode 100644 index 0000000..bc9886f --- /dev/null +++ b/sns_service/src/test/kotlin/joryu/sns_service/profile/entity/ProfileTest.kt @@ -0,0 +1,37 @@ +package joryu.sns_service.profile.entity + +import joryu.sns_service.follow.entity.Follow +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.springframework.boot.test.context.SpringBootTest + +@SpringBootTest +class ProfileTest { + + @Test + fun `profile 생성`() { + // given + val profile = Profile("조정현") + + // when + + // then + assertEquals(profile.name, "조정현") + assertEquals(profile.followerNumber, 0) + assertEquals(profile.followingNumber, 0) + } + + @Test + fun `팔로우 관계 추가`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + + // when + val follow = Follow(fromProfile, toProfile) + + // then + assertEquals(fromProfile.followingNumber, 1) + assertEquals(toProfile.followerNumber, 1) + } +} \ No newline at end of file diff --git a/sns_service/src/test/kotlin/joryu/sns_service/profile/repository/ProfileRepositoryTest.kt b/sns_service/src/test/kotlin/joryu/sns_service/profile/repository/ProfileRepositoryTest.kt new file mode 100644 index 0000000..a84a8c5 --- /dev/null +++ b/sns_service/src/test/kotlin/joryu/sns_service/profile/repository/ProfileRepositoryTest.kt @@ -0,0 +1,59 @@ +package joryu.sns_service.profile.repository + +import joryu.sns_service.profile.entity.Profile +import joryu.sns_service.profile.exception.ProfileBaseException +import joryu.sns_service.profile.exception.ProfileExceptionEnums +import joryu.sns_service.profile.exception.ProfileExceptionEnums.PROFILE_NOT_FOUND +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.transaction.annotation.Transactional + +@SpringBootTest +@Transactional +class ProfileRepositoryTest( + @Autowired + private val profileRepository: ProfileRepository +) { + + @Test + fun `profile 저장`() { + // given + val profile = Profile("조정현") + + // when + profileRepository.save(profile) + + // then + } + + @Test + fun `profile ID로 조회 성공`() { + // given + val profile = Profile("조정현") + profileRepository.save(profile) + + // when + val findProfile = profileRepository.findById(profile.id) + .orElseThrow{ProfileBaseException(PROFILE_NOT_FOUND)} + + // then + Assertions.assertEquals(profile, findProfile) + } + + @Test + fun `profile ID로 조회 실패`() { + // given + val profile = Profile("조정현") + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + profileRepository.findById(profile.id) + .orElseThrow { ProfileBaseException(PROFILE_NOT_FOUND) } + } + } +} \ No newline at end of file diff --git a/sns_service/src/test/kotlin/joryu/sns_service/profile/service/ProfileServiceTest.kt b/sns_service/src/test/kotlin/joryu/sns_service/profile/service/ProfileServiceTest.kt new file mode 100644 index 0000000..e82dd01 --- /dev/null +++ b/sns_service/src/test/kotlin/joryu/sns_service/profile/service/ProfileServiceTest.kt @@ -0,0 +1,193 @@ +package joryu.sns_service.profile.service + +import joryu.sns_service.follow.entity.Follow +import joryu.sns_service.follow.repository.FollowRepository +import joryu.sns_service.profile.dto.request.ProfileCreateRequest +import joryu.sns_service.profile.dto.request.ProfileUpdateRequest +import joryu.sns_service.profile.entity.Profile +import joryu.sns_service.profile.exception.ProfileBaseException +import joryu.sns_service.profile.repository.ProfileRepository +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.transaction.annotation.Transactional + +@SpringBootTest +@Transactional +class ProfileServiceTest ( + @Autowired + private val profileRepository: ProfileRepository, + @Autowired + private val profileService: ProfileService, + @Autowired + private val followRepository: FollowRepository +) { + @Test + fun `profile 생성 후 저장`() { + // given + val profileCreateRequest = ProfileCreateRequest("조정현") + + // when + val response = profileService.create(profileCreateRequest) + + // then + assertEquals(profileCreateRequest.name, response.name) + assertEquals(response.followerNumber, 0) + assertEquals(response.followingNumber, 0) + } + + @Test + fun `profile ID로 조회 성공`() { + // given + val profile = Profile("조정현") + profileRepository.save(profile) + + // when + val response = profileService.findOneById(profile.id) + + // then + assertEquals(profile.name, response.name) + assertEquals(profile.followerNumber, response.followerNumber) + assertEquals(profile.followingNumber, response.followingNumber) + } + + @Test + fun `profile ID로 조회 실패`() { + // given + val profile = Profile("조정현") + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + profileService.findOneById(profile.id) + } + } + + @Test + fun `profile ID로 프로필 정보 업데이트 성공`() { + // given + val profile = Profile("조정현") + val profileUpdateRequest = ProfileUpdateRequest("조현모") + profileRepository.save(profile) + + + // when + val response = profileService.update(profile.id, profileUpdateRequest) + + // then + assertEquals(profileUpdateRequest.name, response.name) + assertEquals(profile.followerNumber, response.followerNumber) + assertEquals(profile.followingNumber, response.followingNumber) + } + + @Test + fun `profile ID로 프로필 정보 업데이트 실패`() { + // given + val profile = Profile("조정현") + val profileUpdateRequest = ProfileUpdateRequest("조현모") + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + profileService.update(profile.id, profileUpdateRequest) + } + } + + @Test + fun `profile ID로 프로필 삭제 성공`() { + // given + val profile = Profile("조정현") + profileRepository.save(profile) + + + // when + profileService.delete(profile.id) + + // then + assertThrows(ProfileBaseException::class.java) { + profileService.findOneById(profile.id) + } + } + + @Test + fun `profile ID로 프로필 삭제 실패`() { + // given + val profile = Profile("조정현") + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + profileService.delete(profile.id) + } + } + + @Test + fun `profile ID로 모든 팔로워 프로필 조회 성공`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + profileRepository.save(toProfile) + profileRepository.save(fromProfile) + followRepository.save(follow) + + // when + val response = profileService.findAllFollowerProfileInfo(toProfile.id) + + // then + assertEquals(response.profileInfo[0].name, fromProfile.name) + assertEquals(response.profileInfo[0].followingNumber, 1) + assertEquals(toProfile.followerNumber, 1) + } + + @Test + fun `profile ID로 모든 팔로워 프로필 조회 실패`() { + // given + val profile = Profile("조정현") + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + profileService.findAllFollowerProfileInfo(profile.id) + } + } + + @Test + fun `profile ID로 모든 팔로잉 프로필 조회 성공`() { + // given + val fromProfile = Profile("팔로워") + val toProfile = Profile("팔로잉") + val follow = Follow(fromProfile, toProfile) + profileRepository.save(toProfile) + profileRepository.save(fromProfile) + followRepository.save(follow) + + // when + val response = profileService.findAllFollowingProfileInfo(fromProfile.id) + + // then + assertEquals(response.profileInfo[0].name, toProfile.name) + assertEquals(response.profileInfo[0].followerNumber, 1) + assertEquals(fromProfile.followingNumber, 1) + } + + @Test + fun `profile ID로 모든 팔로잉 프로필 조회 실패`() { + // given + val profile = Profile("조정현") + + // when + + // then + assertThrows(ProfileBaseException::class.java) { + profileService.findAllFollowingProfileInfo(profile.id) + } + } + +} \ No newline at end of file