From a2ec7439bae65dbf6ffc684be2c03e9c8236961c Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 19:21:09 +0900 Subject: [PATCH 01/10] =?UTF-8?q?[feat]=20=EB=8B=89=EB=84=A4=EC=9E=84=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=8B=9C=EC=A0=90?= =?UTF-8?q?=EC=9D=84=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EC=B6=94=EA=B0=80=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/adapter/out/jpa/UserJpaEntity.java | 16 ++++++++-- .../user/adapter/out/mapper/UserMapper.java | 2 ++ .../java/konkuk/thip/user/domain/User.java | 32 ++++++++++++++++++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java b/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java index d900b46db..c9a911f7a 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java +++ b/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java @@ -5,7 +5,8 @@ import konkuk.thip.common.entity.BaseJpaEntity; import konkuk.thip.user.domain.User; import lombok.*; -import org.springframework.util.Assert; + +import java.time.LocalDate; @Entity @Table(name = "users") @@ -23,6 +24,9 @@ public class UserJpaEntity extends BaseJpaEntity { @Column(length = 60, nullable = false) private String nickname; + @Column(name = "nickname_updated_at", nullable = false) + private LocalDate nicknameUpdatedAt; // 날짜 형식으로 저장 (예: "2023-10-01") + @Column(name = "oauth2_id", length = 50, nullable = false) private String oauth2Id; @@ -37,9 +41,17 @@ public class UserJpaEntity extends BaseJpaEntity { @JoinColumn(name = "user_alias_id", nullable = false) private AliasJpaEntity aliasForUserJpaEntity; + public void updateIncludeAliasFrom(User user, AliasJpaEntity aliasJpaEntity) { + this.nickname = user.getNickname(); + this.nicknameUpdatedAt = user.getNicknameUpdatedAt(); + this.role = UserRole.from(user.getUserRole()); + this.followerCount = user.getFollowerCount(); + this.aliasForUserJpaEntity = aliasJpaEntity; + } + public void updateFrom(User user) { this.nickname = user.getNickname(); - Assert.notNull(user.getAlias(), "Alias must not be null"); + this.nicknameUpdatedAt = user.getNicknameUpdatedAt(); this.role = UserRole.from(user.getUserRole()); this.followerCount = user.getFollowerCount(); } diff --git a/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java b/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java index f29e91fc9..e1df025e5 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java +++ b/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java @@ -13,6 +13,7 @@ public class UserMapper { public UserJpaEntity toJpaEntity(User user, AliasJpaEntity aliasJpaEntity) { return UserJpaEntity.builder() .nickname(user.getNickname()) + .nicknameUpdatedAt(user.getNicknameUpdatedAt()) .role(UserRole.from(user.getUserRole())) .oauth2Id(user.getOauth2Id()) .followerCount(user.getFollowerCount()) @@ -24,6 +25,7 @@ public User toDomainEntity(UserJpaEntity userJpaEntity) { return User.builder() .id(userJpaEntity.getUserId()) .nickname(userJpaEntity.getNickname()) + .nicknameUpdatedAt(userJpaEntity.getNicknameUpdatedAt()) .userRole(userJpaEntity.getRole().getType()) .oauth2Id(userJpaEntity.getOauth2Id()) .followerCount(userJpaEntity.getFollowerCount()) diff --git a/src/main/java/konkuk/thip/user/domain/User.java b/src/main/java/konkuk/thip/user/domain/User.java index 5d0ee1c75..8067f26ba 100644 --- a/src/main/java/konkuk/thip/user/domain/User.java +++ b/src/main/java/konkuk/thip/user/domain/User.java @@ -6,6 +6,8 @@ import lombok.Getter; import lombok.experimental.SuperBuilder; +import java.time.LocalDate; + @Getter @SuperBuilder public class User extends BaseDomainEntity { @@ -14,6 +16,8 @@ public class User extends BaseDomainEntity { private String nickname; + private LocalDate nicknameUpdatedAt; + private String userRole; private String oauth2Id; @@ -22,10 +26,11 @@ public class User extends BaseDomainEntity { private Alias alias; - public static User withoutId(String nickname, String userRole, String oauth2Id, Alias alias) { + public static User withoutId(String nickname, LocalDate nicknameUpdatedAt, String userRole, String oauth2Id, Alias alias) { return User.builder() .id(null) .nickname(nickname) + .nicknameUpdatedAt(nicknameUpdatedAt) .userRole(userRole) .oauth2Id(oauth2Id) .followerCount(0) @@ -44,4 +49,29 @@ public void decreaseFollowerCount() { followerCount--; } + public void updateUserInfo(String nickname, Alias alias, boolean isNicknameUpdateRequest) { + if(isNicknameUpdateRequest) { + validateCanUpdateNickname(nickname); + this.nickname = nickname; + this.nicknameUpdatedAt = LocalDate.now(); + } + this.alias = alias; + } + + private void validateCanUpdateNickname(String nickname) { + if(nickname.isBlank()) { // 빈칸 불가 + throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_BLANK); + } + if(nickname.length() > 10) { // 10자 이상 불가 + throw new InvalidStateException(ErrorCode.USER_NICKNAME_TOO_LONG); + } + if(nickname.equals(this.nickname)) { // 현재 닉네임과 같으면 업데이트 불가 + throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_SAME); + } + // 닉네임을 변경한지 6개월이 지나지 않았으면 닉네임 업데이트 불가 + if(nicknameUpdatedAt != null && nicknameUpdatedAt.isAfter(LocalDate.now().minusMonths(6))) { + throw new InvalidStateException(ErrorCode.USER_NICKNAME_UPDATE_TOO_FREQUENT); + } + } + } From f2a57c6707020036c1d3d47f906208ec01ac6bde Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 19:21:20 +0900 Subject: [PATCH 02/10] =?UTF-8?q?[feat]=20=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=A0=95=EC=9D=98=20(#1?= =?UTF-8?q?22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/konkuk/thip/common/exception/code/ErrorCode.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java b/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java index 31e77003b..020181c71 100644 --- a/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java +++ b/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java @@ -38,6 +38,11 @@ public enum ErrorCode implements ResponseCode { */ USER_NOT_FOUND(HttpStatus.NOT_FOUND, 70000, "존재하지 않는 USER 입니다."), USER_ALREADY_FOLLOWED(HttpStatus.BAD_REQUEST, 70001, "이미 팔로우한 사용자입니다."), + USER_NICKNAME_TOO_LONG(HttpStatus.BAD_REQUEST, 70002, "사용자 닉네임은 10자 이하여야 합니다."), + USER_NICKNAME_CANNOT_BE_BLANK(HttpStatus.BAD_REQUEST, 70003, "사용자 닉네임은 비어있을 수 없습니다."), + USER_NICKNAME_CANNOT_BE_SAME(HttpStatus.BAD_REQUEST, 70004, "사용자 닉네임은 이전과 동일할 수 없습니다."), + USER_NICKNAME_UPDATE_TOO_FREQUENT(HttpStatus.BAD_REQUEST, 70005, "사용자 닉네임은 6개월에 한번 변경할 수 있습니다."), + USER_NICKNAME_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, 70006, "다른 사용자가 이미 사용중인 닉네임입니다."), /** * 75000 : follow error From 472724cbead23a062a1d2b18a675fc603c6f7129 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 19:21:42 +0900 Subject: [PATCH 03/10] =?UTF-8?q?[feat]=20=EB=8B=89=EB=84=A4=EC=9E=84=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=8B=9C=EC=A0=90?= =?UTF-8?q?=EC=9D=84=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EC=B6=94=EA=B0=80=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/user/application/service/UserSignupService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/konkuk/thip/user/application/service/UserSignupService.java b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java index 105e49eb9..65534982a 100644 --- a/src/main/java/konkuk/thip/user/application/service/UserSignupService.java +++ b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java @@ -9,6 +9,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; + import static konkuk.thip.user.adapter.out.jpa.UserRole.USER; @@ -23,7 +25,7 @@ public class UserSignupService implements UserSignupUseCase { public Long signup(UserSignupCommand command) { Alias alias = Alias.from(command.aliasName()); User user = User.withoutId( - command.nickname(), USER.getType(), command.oauth2Id(), alias + command.nickname(), LocalDate.now(), USER.getType(), command.oauth2Id(), alias ); return userCommandPort.save(user); From 4907e7914d3df7c5937225567394a48973c611ca Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 19:21:56 +0900 Subject: [PATCH 04/10] =?UTF-8?q?[feat]=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20api?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/web/UserCommandController.java | 21 +++++++---- .../in/web/request/UserFollowRequest.java | 2 +- .../in/web/request/UserUpdateRequest.java | 20 +++++++++++ .../UserCommandPersistenceAdapter.java | 16 +++++++++ .../UserQueryPersistenceAdapter.java | 5 +++ .../repository/UserJpaRepository.java | 2 ++ .../port/in/UserUpdateUseCase.java | 7 ++++ .../port/in/dto/UserUpdateCommand.java | 8 +++++ .../application/port/out/UserCommandPort.java | 1 + .../application/port/out/UserQueryPort.java | 3 ++ .../service/UserUpdateService.java | 36 +++++++++++++++++++ 11 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 src/main/java/konkuk/thip/user/adapter/in/web/request/UserUpdateRequest.java create mode 100644 src/main/java/konkuk/thip/user/application/port/in/UserUpdateUseCase.java create mode 100644 src/main/java/konkuk/thip/user/application/port/in/dto/UserUpdateCommand.java create mode 100644 src/main/java/konkuk/thip/user/application/service/UserUpdateService.java diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java index cd984e359..87ece35c1 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java @@ -12,15 +12,14 @@ import konkuk.thip.common.swagger.annotation.ExceptionDescription; import konkuk.thip.user.adapter.in.web.request.UserFollowRequest; import konkuk.thip.user.adapter.in.web.request.UserSignupRequest; +import konkuk.thip.user.adapter.in.web.request.UserUpdateRequest; import konkuk.thip.user.adapter.in.web.response.UserFollowResponse; import konkuk.thip.user.adapter.in.web.response.UserSignupResponse; import konkuk.thip.user.application.port.in.UserFollowUsecase; import konkuk.thip.user.application.port.in.UserSignupUseCase; +import konkuk.thip.user.application.port.in.UserUpdateUseCase; import lombok.RequiredArgsConstructor; -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.RestController; +import org.springframework.web.bind.annotation.*; import static konkuk.thip.common.security.constant.AuthParameters.JWT_HEADER_KEY; import static konkuk.thip.common.security.constant.AuthParameters.JWT_PREFIX; @@ -34,6 +33,8 @@ public class UserCommandController { private final UserSignupUseCase userSignupUseCase; private final UserFollowUsecase userFollowUsecase; + private final UserUpdateUseCase userUpdateUseCase; + private final JwtUtil jwtUtil; @Operation( @@ -60,9 +61,17 @@ public BaseResponse signup(@Valid @RequestBody final UserSig public BaseResponse followUser( @Parameter(hidden = true) @UserId final Long userId, @Parameter(description = "팔로우/언팔로우할 사용자 ID") @PathVariable final Long followingUserId, - @RequestBody @Valid final UserFollowRequest request) { + @RequestBody @Valid final UserFollowRequest userFollowRequest) { return BaseResponse.ok(UserFollowResponse.of(userFollowUsecase.changeFollowingState( - UserFollowRequest.toCommand(userId, followingUserId, request.type()) + userFollowRequest.toCommand(userId, followingUserId) ))); } + + @PatchMapping("/users") + public BaseResponse updateUser( + @Parameter(hidden = true) @UserId final Long userId, + @RequestBody @Valid final UserUpdateRequest userUpdateRequest) { + userUpdateUseCase.updateUser(userUpdateRequest.toCommand(userId)); + return BaseResponse.ok(null); + } } diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java index edbe12846..a32aa006f 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java @@ -10,7 +10,7 @@ public record UserFollowRequest( @NotNull(message = "type은 필수 파라미터입니다.") Boolean type ) { - public static UserFollowCommand toCommand(Long userId, Long targetUserId, Boolean type) { + public UserFollowCommand toCommand(Long userId, Long targetUserId) { return new UserFollowCommand(userId, targetUserId, type); } } diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserUpdateRequest.java b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserUpdateRequest.java new file mode 100644 index 000000000..5e0d7ff45 --- /dev/null +++ b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserUpdateRequest.java @@ -0,0 +1,20 @@ +package konkuk.thip.user.adapter.in.web.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import konkuk.thip.user.application.port.in.dto.UserUpdateCommand; + +@Schema(description = "사용자 정보 수정 요청 DTO") +public record UserUpdateRequest( + + @Schema(description = "사용자 수정 칭호", example = "문학가") + @NotBlank(message = "칭호는 필수입니다.") + String aliasName, + + @Schema(description = "사용자 수정 닉네임", example = "thip") + String nickname +) { + public UserUpdateCommand toCommand(Long userId) { + return new UserUpdateCommand(aliasName, nickname, userId); + } +} diff --git a/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java b/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java index 98075a878..dd73bf0dd 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java +++ b/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java @@ -52,4 +52,20 @@ public Map findByIds(List userIds) { .map(userMapper::toDomainEntity) .collect(Collectors.toMap(User::getId, Function.identity())); } + + @Override + public void update(User user) { + UserJpaEntity userJpaEntity = userJpaRepository.findById(user.getId()).orElseThrow( + () -> new EntityNotFoundException(USER_NOT_FOUND) + ); + + aliasJpaRepository.findByValue(user.getAlias().getValue()).ifPresentOrElse( + aliasJpaEntity -> userJpaEntity.updateIncludeAliasFrom(user, aliasJpaEntity), + () -> { + throw new EntityNotFoundException(ALIAS_NOT_FOUND); + } + ); + + userJpaRepository.save(userJpaEntity); + } } diff --git a/src/main/java/konkuk/thip/user/adapter/out/persistence/UserQueryPersistenceAdapter.java b/src/main/java/konkuk/thip/user/adapter/out/persistence/UserQueryPersistenceAdapter.java index 7697a9e06..d162c5094 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/persistence/UserQueryPersistenceAdapter.java +++ b/src/main/java/konkuk/thip/user/adapter/out/persistence/UserQueryPersistenceAdapter.java @@ -23,6 +23,11 @@ public boolean existsByNickname(String nickname) { return userJpaRepository.existsByNickname(nickname); } + @Override + public boolean existsByNicknameAndUserIdNot(String nickname, Long userId) { + return userJpaRepository.existsByNicknameAndUserIdNot(nickname, userId); + } + @Override public Set findUserIdsParticipatedInRoomsByBookId(Long bookId) { return userJpaRepository.findUserIdsByBookId(bookId); diff --git a/src/main/java/konkuk/thip/user/adapter/out/persistence/repository/UserJpaRepository.java b/src/main/java/konkuk/thip/user/adapter/out/persistence/repository/UserJpaRepository.java index 71eda08ef..bbb6d773f 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/persistence/repository/UserJpaRepository.java +++ b/src/main/java/konkuk/thip/user/adapter/out/persistence/repository/UserJpaRepository.java @@ -9,4 +9,6 @@ public interface UserJpaRepository extends JpaRepository, U Optional findByOauth2Id(String oauth2Id); boolean existsByNickname(String nickname); Optional findById(Long userId); + + boolean existsByNicknameAndUserIdNot(String nickname, Long userId); } diff --git a/src/main/java/konkuk/thip/user/application/port/in/UserUpdateUseCase.java b/src/main/java/konkuk/thip/user/application/port/in/UserUpdateUseCase.java new file mode 100644 index 000000000..195a1ee8f --- /dev/null +++ b/src/main/java/konkuk/thip/user/application/port/in/UserUpdateUseCase.java @@ -0,0 +1,7 @@ +package konkuk.thip.user.application.port.in; + +import konkuk.thip.user.application.port.in.dto.UserUpdateCommand; + +public interface UserUpdateUseCase { + void updateUser(UserUpdateCommand command); +} diff --git a/src/main/java/konkuk/thip/user/application/port/in/dto/UserUpdateCommand.java b/src/main/java/konkuk/thip/user/application/port/in/dto/UserUpdateCommand.java new file mode 100644 index 000000000..6523ce742 --- /dev/null +++ b/src/main/java/konkuk/thip/user/application/port/in/dto/UserUpdateCommand.java @@ -0,0 +1,8 @@ +package konkuk.thip.user.application.port.in.dto; + +public record UserUpdateCommand( + String aliasName, + String nickname, + Long userId +) { +} diff --git a/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java b/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java index cac05e1b6..3d8fd2793 100644 --- a/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java +++ b/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java @@ -10,4 +10,5 @@ public interface UserCommandPort { Long save(User user); User findById(Long userId); Map findByIds(List userIds); + void update(User user); } diff --git a/src/main/java/konkuk/thip/user/application/port/out/UserQueryPort.java b/src/main/java/konkuk/thip/user/application/port/out/UserQueryPort.java index 2026b288f..9a12a1494 100644 --- a/src/main/java/konkuk/thip/user/application/port/out/UserQueryPort.java +++ b/src/main/java/konkuk/thip/user/application/port/out/UserQueryPort.java @@ -8,6 +8,9 @@ public interface UserQueryPort { boolean existsByNickname(String nickname); + + boolean existsByNicknameAndUserIdNot(String nickname, Long userId); + Set findUserIdsParticipatedInRoomsByBookId(Long bookId); UserViewAliasChoiceResult getAllAliasesAndCategories(); diff --git a/src/main/java/konkuk/thip/user/application/service/UserUpdateService.java b/src/main/java/konkuk/thip/user/application/service/UserUpdateService.java new file mode 100644 index 000000000..28ec23707 --- /dev/null +++ b/src/main/java/konkuk/thip/user/application/service/UserUpdateService.java @@ -0,0 +1,36 @@ +package konkuk.thip.user.application.service; + +import konkuk.thip.common.exception.BusinessException; +import konkuk.thip.common.exception.code.ErrorCode; +import konkuk.thip.user.application.port.in.UserUpdateUseCase; +import konkuk.thip.user.application.port.in.dto.UserUpdateCommand; +import konkuk.thip.user.application.port.out.UserCommandPort; +import konkuk.thip.user.application.port.out.UserQueryPort; +import konkuk.thip.user.domain.Alias; +import konkuk.thip.user.domain.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserUpdateService implements UserUpdateUseCase { + + private final UserCommandPort userCommandPort; + private final UserQueryPort userQueryPort; + + @Override + @Transactional + public void updateUser(UserUpdateCommand command) { + Alias alias = Alias.from(command.aliasName()); + boolean isNicknameUpdateRequest = command.nickname() != null; // 닉네임이 null이 아니면 닉네임 업데이트 요청 + + User user = userCommandPort.findById(command.userId()); + user.updateUserInfo(command.nickname(), alias, isNicknameUpdateRequest); + + if(isNicknameUpdateRequest && userQueryPort.existsByNicknameAndUserIdNot(command.nickname(), command.userId())) { + throw new BusinessException(ErrorCode.USER_NICKNAME_ALREADY_EXISTS); + } + userCommandPort.update(user); + } +} From 97d464bd018cd3d47ce2eb070c17935821d707ee Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 19:22:19 +0900 Subject: [PATCH 05/10] =?UTF-8?q?[test]=20User=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../konkuk/thip/user/domain/UserTest.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/test/java/konkuk/thip/user/domain/UserTest.java diff --git a/src/test/java/konkuk/thip/user/domain/UserTest.java b/src/test/java/konkuk/thip/user/domain/UserTest.java new file mode 100644 index 000000000..2fb031840 --- /dev/null +++ b/src/test/java/konkuk/thip/user/domain/UserTest.java @@ -0,0 +1,94 @@ +package konkuk.thip.user.domain; + +import konkuk.thip.common.exception.InvalidStateException; +import konkuk.thip.common.exception.code.ErrorCode; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.*; + +@DisplayName("[단위] User 단위 테스트") +class UserTest { + + private User user; + private Alias alias; + + @BeforeEach + void setUp() { + alias = Alias.WRITER; + user = User.builder() + .id(1L) + .nickname("thip") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) // 7개월 전 + .userRole("USER") + .oauth2Id("oauth2-id") + .followerCount(10) + .alias(alias) + .build(); + } + + @Test + @DisplayName("닉네임 빈 값이면 예외 발생") + //영어로 네이밍 + void nicknameCannotBeBlank_throwsException() { + assertThatThrownBy(() -> user.updateUserInfo(" ", alias, true)) + .isInstanceOf(InvalidStateException.class) + .hasMessageContaining(ErrorCode.USER_NICKNAME_CANNOT_BE_BLANK.getMessage()); + } + + @Test + @DisplayName("닉네임 10자 초과이면 예외 발생") + void nicknameTooLong_throwsException() { + String longNickname = "thipthipthip"; // 12자 + assertThatThrownBy(() -> user.updateUserInfo(longNickname, alias, true)) + .isInstanceOf(InvalidStateException.class) + .hasMessageContaining(ErrorCode.USER_NICKNAME_TOO_LONG.getMessage()); + } + + @Test + @DisplayName("닉네임이 기존 닉네임과 같으면 예외 발생") + void nicknameCannotBeSame_throwsException() { + assertThatThrownBy(() -> user.updateUserInfo("thip", alias, true)) + .isInstanceOf(InvalidStateException.class) + .hasMessageContaining(ErrorCode.USER_NICKNAME_CANNOT_BE_SAME.getMessage()); + } + + @Test + @DisplayName("닉네임이 6개월 이내에 변경되면 예외 발생") + void nicknameUpdateTooFrequent_throwsException() { + user = User.builder() + .nicknameUpdatedAt(LocalDate.now().minusMonths(3)) + .build(); + + assertThatThrownBy(() -> user.updateUserInfo("newthip", alias, true)) + .isInstanceOf(InvalidStateException.class) + .hasMessageContaining(ErrorCode.USER_NICKNAME_UPDATE_TOO_FREQUENT.getMessage()); + } + + @Test + @DisplayName("닉네임과 별칭을 정상적으로 업데이트") + void updateUserInfo_success() { + Alias newAlias = Alias.ARTIST; + String newNickname = "newNick"; + + user.updateUserInfo(newNickname, newAlias, true); + + assertThat(user.getNickname()).isEqualTo(newNickname); + assertThat(user.getAlias()).isEqualTo(newAlias); + assertThat(user.getNicknameUpdatedAt()).isEqualTo(LocalDate.now()); + } + + @Test + @DisplayName("닉네임 업데이트 없이 별칭만 변경") + void 닉네임_업데이트_없이_별칭만_변경() { + Alias newAlias = Alias.SCIENTIST; + + user.updateUserInfo(null, newAlias, false); + + assertThat(user.getAlias()).isEqualTo(newAlias); + assertThat(user.getNickname()).isEqualTo("thip"); + } +} \ No newline at end of file From f96b82c6b823289793297860c0dcf707a4922e3f Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 19:26:34 +0900 Subject: [PATCH 06/10] =?UTF-8?q?[test]=20UserUpdateService=20=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/UserFollowServiceTest.java | 1 + .../service/UserUpdateServiceTest.java | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/test/java/konkuk/thip/user/application/service/UserUpdateServiceTest.java diff --git a/src/test/java/konkuk/thip/user/application/service/UserFollowServiceTest.java b/src/test/java/konkuk/thip/user/application/service/UserFollowServiceTest.java index 1d0c41878..f749f1d5d 100644 --- a/src/test/java/konkuk/thip/user/application/service/UserFollowServiceTest.java +++ b/src/test/java/konkuk/thip/user/application/service/UserFollowServiceTest.java @@ -21,6 +21,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.*; +@DisplayName("[단위] UserFollowService 단위 테스트") class UserFollowServiceTest { private FollowingCommandPort followingCommandPort; diff --git a/src/test/java/konkuk/thip/user/application/service/UserUpdateServiceTest.java b/src/test/java/konkuk/thip/user/application/service/UserUpdateServiceTest.java new file mode 100644 index 000000000..16e24090f --- /dev/null +++ b/src/test/java/konkuk/thip/user/application/service/UserUpdateServiceTest.java @@ -0,0 +1,92 @@ +package konkuk.thip.user.application.service; + +import konkuk.thip.common.exception.BusinessException; +import konkuk.thip.user.application.port.in.dto.UserUpdateCommand; +import konkuk.thip.user.application.port.out.UserCommandPort; +import konkuk.thip.user.application.port.out.UserQueryPort; +import konkuk.thip.user.domain.Alias; +import konkuk.thip.user.domain.User; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.*; + +@DisplayName("[단위] UserUpdateService 단위 테스트") +class UserUpdateServiceTest { + + private UserCommandPort userCommandPort; + private UserQueryPort userQueryPort; + private UserUpdateService userUpdateService; + private User existingUser; + + @BeforeEach + void setUp() { + userCommandPort = mock(UserCommandPort.class); + userQueryPort = mock(UserQueryPort.class); + userUpdateService = new UserUpdateService(userCommandPort, userQueryPort); + + existingUser = User.builder() + .id(1L) + .nickname("thip") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) + .userRole("USER") + .oauth2Id("oauth2-id") + .followerCount(0) + .alias(Alias.WRITER) + .build(); + } + + @Test + @DisplayName("닉네임과 별칭을 정상적으로 업데이트") + void updateUser_success() { + // given + UserUpdateCommand command = new UserUpdateCommand(Alias.ARTIST.getValue(), "newthip", existingUser.getId()); + when(userCommandPort.findById(command.userId())).thenReturn(existingUser); + when(userQueryPort.existsByNicknameAndUserIdNot(command.nickname(), command.userId())) + .thenReturn(false); + + // when + userUpdateService.updateUser(command); + + // then + assertThat(existingUser.getNickname()).isEqualTo("newthip"); + assertThat(existingUser.getAlias()).isEqualTo(Alias.ARTIST); + verify(userCommandPort).update(existingUser); + } + + @Test + @DisplayName("닉네임 중복이면 예외 발생") + void updateUser_duplicateNickname_throwsException() { + // given + UserUpdateCommand command = new UserUpdateCommand(Alias.ARTIST.getValue(), "existingnickname", existingUser.getId()); + when(userCommandPort.findById(command.userId())).thenReturn(existingUser); + when(userQueryPort.existsByNicknameAndUserIdNot(command.nickname(), command.userId())) + .thenReturn(true); + + // when & then + assertThatThrownBy(() -> userUpdateService.updateUser(command)) + .isInstanceOf(BusinessException.class); + verify(userCommandPort, never()).update(any()); + } + + @Test + @DisplayName("닉네임 없이 별칭만 업데이트") + void updateUser_onlyAlias_success() { + // given + UserUpdateCommand command = new UserUpdateCommand(Alias.SCIENTIST.getValue(), null, existingUser.getId()); + when(userCommandPort.findById(command.userId())).thenReturn(existingUser); + + // when + userUpdateService.updateUser(command); + + // then + assertThat(existingUser.getAlias()).isEqualTo(Alias.SCIENTIST); + assertThat(existingUser.getNickname()).isEqualTo("thip"); + verify(userCommandPort).update(existingUser); + } +} \ No newline at end of file From df025d3717513ec4182d103cff246f116d0da263 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 22:03:01 +0900 Subject: [PATCH 07/10] =?UTF-8?q?[refactor]=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=88=9C=EC=84=9C=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/konkuk/thip/user/domain/User.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/konkuk/thip/user/domain/User.java b/src/main/java/konkuk/thip/user/domain/User.java index 8067f26ba..a1e4b0a48 100644 --- a/src/main/java/konkuk/thip/user/domain/User.java +++ b/src/main/java/konkuk/thip/user/domain/User.java @@ -65,13 +65,13 @@ private void validateCanUpdateNickname(String nickname) { if(nickname.length() > 10) { // 10자 이상 불가 throw new InvalidStateException(ErrorCode.USER_NICKNAME_TOO_LONG); } - if(nickname.equals(this.nickname)) { // 현재 닉네임과 같으면 업데이트 불가 - throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_SAME); - } // 닉네임을 변경한지 6개월이 지나지 않았으면 닉네임 업데이트 불가 if(nicknameUpdatedAt != null && nicknameUpdatedAt.isAfter(LocalDate.now().minusMonths(6))) { throw new InvalidStateException(ErrorCode.USER_NICKNAME_UPDATE_TOO_FREQUENT); } + if(nickname.equals(this.nickname)) { // 현재 닉네임과 같으면 업데이트 불가 + throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_SAME); + } } } From 750c8b7a91feaa011508afc922b85b4230adba32 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 22:03:22 +0900 Subject: [PATCH 08/10] =?UTF-8?q?[test]=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=ED=8E=B8=EC=A7=91=20api=20=ED=86=B5=ED=95=A9=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/web/UserUpdateApiTest.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java diff --git a/src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java b/src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java new file mode 100644 index 000000000..1c76c0321 --- /dev/null +++ b/src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java @@ -0,0 +1,87 @@ +package konkuk.thip.user.adapter.in.web; + +import com.fasterxml.jackson.databind.ObjectMapper; +import konkuk.thip.common.util.TestEntityFactory; +import konkuk.thip.user.adapter.in.web.request.UserUpdateRequest; +import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; +import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; +import konkuk.thip.user.adapter.out.jpa.UserRole; +import konkuk.thip.user.adapter.out.persistence.repository.UserJpaRepository; +import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository; +import org.junit.jupiter.api.AfterEach; +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.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@ActiveProfiles("test") +@AutoConfigureMockMvc(addFilters = false) +@DisplayName("[통합] 사용자 정보 수정 API 통합 테스트") +class UserUpdateApiTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private UserJpaRepository userJpaRepository; + + @Autowired + private AliasJpaRepository aliasJpaRepository; + + @AfterEach + void tearDown() { + userJpaRepository.deleteAll(); + aliasJpaRepository.deleteAll(); + } + + @Test + @DisplayName("사용자 닉네임과 별칭이 정상적으로 업데이트된다.") + void updateUser_success() throws Exception { + // given: 기존 alias 및 user 생성 + AliasJpaEntity oldAlias = aliasJpaRepository.save(TestEntityFactory.createScienceAlias()); + AliasJpaEntity newAlias = aliasJpaRepository.save(TestEntityFactory.createLiteratureAlias()); + + UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() + .nickname("oldthip") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) + .oauth2Id("oauth2_user100") + .role(UserRole.USER) + .aliasForUserJpaEntity(oldAlias) + .build()); + + Long userId = user.getUserId(); + + UserUpdateRequest userUpdateRequest = new UserUpdateRequest(newAlias.getValue(),"newthip"); + + // when: API 요청 + mockMvc.perform(patch("/users") + .requestAttr("userId", userId) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(userUpdateRequest))) + // then: HTTP 응답 상태 및 기본 응답 검증 + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data").doesNotExist()); + + // DB 검증: 닉네임과 alias가 업데이트되었는지 확인 + UserJpaEntity updatedUser = userJpaRepository.findById(userId).orElseThrow(); + assertThat(updatedUser.getNickname()).isEqualTo("newthip"); + + AliasJpaEntity updatedAlias = aliasJpaRepository.findById(updatedUser.getAliasForUserJpaEntity().getAliasId()).orElseThrow(); + assertThat(updatedAlias.getValue()).isEqualTo(newAlias.getValue()); + } +} \ No newline at end of file From fd4f7c15cefbcba4ed7faa878ca3bcfb157b5a9a Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 22:03:48 +0900 Subject: [PATCH 09/10] =?UTF-8?q?[test]=20=EC=83=81=EC=88=98=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=EC=9D=84=20enum=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=8C=80=EC=B2=B4=20&=20User=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95=20(#1?= =?UTF-8?q?22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/web/BookChangeSavedControllerTest.java | 4 +++- .../web/BookDetailSearchControllerTest.java | 1 + .../BookMostSearchedBooksControllerTest.java | 2 ++ .../in/web/BookQueryControllerTest.java | 12 ++++++---- .../thip/common/util/TestEntityFactory.java | 24 +++++++++++-------- .../adapter/in/web/RecordSearchApiTest.java | 2 ++ .../adapter/in/web/RoomCloseJoinApiTest.java | 3 +++ .../adapter/in/web/RoomCreateAPITest.java | 1 + .../in/web/RoomGetMemberListApiTest.java | 5 ++++ .../room/adapter/in/web/RoomJoinApiTest.java | 2 ++ .../in/web/RoomPlayingDetailViewApiTest.java | 10 ++++---- .../web/RoomRecruitingDetailViewApiTest.java | 1 + .../adapter/in/web/RoomSearchApiTest.java | 4 +++- .../konkuk/thip/room/domain/RoomTest.java | 2 +- .../adapter/in/web/UserFollowApiTest.java | 3 +++ .../web/UserVerifyNicknameControllerTest.java | 3 +++ .../in/web/VoteCreateControllerTest.java | 6 +++-- 17 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java b/src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java index 64e635f16..f18f62028 100644 --- a/src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java +++ b/src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java @@ -12,8 +12,8 @@ import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserRole; -import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository; import konkuk.thip.user.adapter.out.persistence.repository.UserJpaRepository; +import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -26,6 +26,7 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import java.time.LocalDate; import java.util.Optional; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -72,6 +73,7 @@ void setUp() { UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_432708231") .nickname("User1") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); diff --git a/src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java b/src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java index 800966d41..9a64cd89a 100644 --- a/src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java +++ b/src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java @@ -66,6 +66,7 @@ void setup() { UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_432708231") .nickname("User1") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); diff --git a/src/test/java/konkuk/thip/book/adapter/in/web/BookMostSearchedBooksControllerTest.java b/src/test/java/konkuk/thip/book/adapter/in/web/BookMostSearchedBooksControllerTest.java index 201217753..fc29c4ea8 100644 --- a/src/test/java/konkuk/thip/book/adapter/in/web/BookMostSearchedBooksControllerTest.java +++ b/src/test/java/konkuk/thip/book/adapter/in/web/BookMostSearchedBooksControllerTest.java @@ -68,6 +68,8 @@ void setUp() { UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_432708231") .nickname("User1") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) + .nicknameUpdatedAt(LocalDate.now().minusMonths(1)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); diff --git a/src/test/java/konkuk/thip/book/adapter/in/web/BookQueryControllerTest.java b/src/test/java/konkuk/thip/book/adapter/in/web/BookQueryControllerTest.java index 4ad8f670c..0c38d9537 100644 --- a/src/test/java/konkuk/thip/book/adapter/in/web/BookQueryControllerTest.java +++ b/src/test/java/konkuk/thip/book/adapter/in/web/BookQueryControllerTest.java @@ -9,23 +9,26 @@ import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserRole; -import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository; import konkuk.thip.user.adapter.out.persistence.repository.UserJpaRepository; +import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository; import org.junit.jupiter.api.AfterEach; 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.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; + +import java.time.LocalDate; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @AutoConfigureMockMvc @@ -57,6 +60,7 @@ void setUp() { UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_432708231") .nickname("User1") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); diff --git a/src/test/java/konkuk/thip/common/util/TestEntityFactory.java b/src/test/java/konkuk/thip/common/util/TestEntityFactory.java index 6294c8811..1ae37aea4 100644 --- a/src/test/java/konkuk/thip/common/util/TestEntityFactory.java +++ b/src/test/java/konkuk/thip/common/util/TestEntityFactory.java @@ -14,11 +14,13 @@ import konkuk.thip.room.adapter.out.jpa.RoomJpaEntity; import konkuk.thip.room.adapter.out.jpa.RoomParticipantJpaEntity; import konkuk.thip.room.adapter.out.jpa.RoomParticipantRole; +import konkuk.thip.room.domain.Category; import konkuk.thip.saved.adapter.out.jpa.SavedFeedJpaEntity; import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; import konkuk.thip.user.adapter.out.jpa.FollowingJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserRole; +import konkuk.thip.user.domain.Alias; import konkuk.thip.vote.adapter.out.jpa.VoteJpaEntity; import java.time.LocalDate; @@ -34,32 +36,32 @@ public class TestEntityFactory { public static AliasJpaEntity createLiteratureAlias() { return AliasJpaEntity.builder() // 실제 존재하는 값으로 - .value("문학가") - .imageUrl("문학_image") - .color("문학_color") + .value(Alias.WRITER.getValue()) + .imageUrl(Alias.WRITER.getImageUrl()) + .color(Alias.WRITER.getColor()) .build(); } public static CategoryJpaEntity createLiteratureCategory(AliasJpaEntity alias) { return CategoryJpaEntity.builder() // 실제 존재하는 값으로 - .value("문학") - .imageUrl("문학_image") + .value(Category.LITERATURE.getValue()) + .imageUrl(Category.LITERATURE.getImageUrl()) .aliasForCategoryJpaEntity(alias) .build(); } public static AliasJpaEntity createScienceAlias() { return AliasJpaEntity.builder() // 실제 존재하는 값으로 - .value("과학자") - .imageUrl("과학_image") - .color("과학_color") + .value(Alias.SCIENTIST.getValue()) + .imageUrl(Alias.SCIENTIST.getImageUrl()) + .color(Alias.SCIENTIST.getColor()) .build(); } public static CategoryJpaEntity createScienceCategory(AliasJpaEntity alias) { return CategoryJpaEntity.builder() // 실제 존재하는 값으로 - .value("과학/IT") - .imageUrl("과학/IT_image") + .value(Category.SCIENCE_IT.getValue()) + .imageUrl(Category.SCIENCE_IT.getImageUrl()) .aliasForCategoryJpaEntity(alias) .build(); } @@ -67,6 +69,7 @@ public static CategoryJpaEntity createScienceCategory(AliasJpaEntity alias) { public static UserJpaEntity createUser(AliasJpaEntity alias) { return UserJpaEntity.builder() .nickname("테스터") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_12345678") .aliasForUserJpaEntity(alias) .role(UserRole.USER) @@ -76,6 +79,7 @@ public static UserJpaEntity createUser(AliasJpaEntity alias) { public static UserJpaEntity createUser(AliasJpaEntity alias, String nickname) { return UserJpaEntity.builder() .nickname(nickname) + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_12345678") .aliasForUserJpaEntity(alias) .role(UserRole.USER) diff --git a/src/test/java/konkuk/thip/record/adapter/in/web/RecordSearchApiTest.java b/src/test/java/konkuk/thip/record/adapter/in/web/RecordSearchApiTest.java index 5a78190e7..b64659c63 100644 --- a/src/test/java/konkuk/thip/record/adapter/in/web/RecordSearchApiTest.java +++ b/src/test/java/konkuk/thip/record/adapter/in/web/RecordSearchApiTest.java @@ -408,6 +408,7 @@ private TestData createTestData() { UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_123") .nickname("테스트사용자") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); @@ -525,6 +526,7 @@ private TestData createTestDataWithLockedContent() { UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_123") .nickname("테스트사용자") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); diff --git a/src/test/java/konkuk/thip/room/adapter/in/web/RoomCloseJoinApiTest.java b/src/test/java/konkuk/thip/room/adapter/in/web/RoomCloseJoinApiTest.java index d875fae49..aeaab3100 100644 --- a/src/test/java/konkuk/thip/room/adapter/in/web/RoomCloseJoinApiTest.java +++ b/src/test/java/konkuk/thip/room/adapter/in/web/RoomCloseJoinApiTest.java @@ -61,18 +61,21 @@ void setup() { host = userJpaRepository.save(UserJpaEntity.builder() .nickname("호스트") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_12345678") .aliasForUserJpaEntity(alias) .role(UserRole.USER) .build()); member = userJpaRepository.save(UserJpaEntity.builder() .nickname("방 참여자") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_12345678") .aliasForUserJpaEntity(alias) .role(UserRole.USER) .build()); outsider = userJpaRepository.save(UserJpaEntity.builder() .nickname("방 미참여자") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_12345678") .aliasForUserJpaEntity(alias) .role(UserRole.USER) diff --git a/src/test/java/konkuk/thip/room/adapter/in/web/RoomCreateAPITest.java b/src/test/java/konkuk/thip/room/adapter/in/web/RoomCreateAPITest.java index cde68b034..906dca091 100644 --- a/src/test/java/konkuk/thip/room/adapter/in/web/RoomCreateAPITest.java +++ b/src/test/java/konkuk/thip/room/adapter/in/web/RoomCreateAPITest.java @@ -78,6 +78,7 @@ private void saveUserAndCategory() { userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_432708231") .nickname("User1") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); diff --git a/src/test/java/konkuk/thip/room/adapter/in/web/RoomGetMemberListApiTest.java b/src/test/java/konkuk/thip/room/adapter/in/web/RoomGetMemberListApiTest.java index 4defca8f6..ea08d89eb 100644 --- a/src/test/java/konkuk/thip/room/adapter/in/web/RoomGetMemberListApiTest.java +++ b/src/test/java/konkuk/thip/room/adapter/in/web/RoomGetMemberListApiTest.java @@ -26,6 +26,8 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import java.time.LocalDate; + import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasSize; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -76,6 +78,7 @@ void setUp() { user1 = userJpaRepository.save(UserJpaEntity.builder() .nickname("테스터1") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_1") .aliasForUserJpaEntity(alias) .role(UserRole.USER) @@ -84,6 +87,7 @@ void setUp() { user2 = userJpaRepository.save(UserJpaEntity.builder() .nickname("테스터2") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_2") .aliasForUserJpaEntity(alias) .role(UserRole.USER) @@ -92,6 +96,7 @@ void setUp() { user3 = userJpaRepository.save(UserJpaEntity.builder() .nickname("테스터3") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("kakao_3") .aliasForUserJpaEntity(alias) .role(UserRole.USER) diff --git a/src/test/java/konkuk/thip/room/adapter/in/web/RoomJoinApiTest.java b/src/test/java/konkuk/thip/room/adapter/in/web/RoomJoinApiTest.java index b56add344..1ceb22fc2 100644 --- a/src/test/java/konkuk/thip/room/adapter/in/web/RoomJoinApiTest.java +++ b/src/test/java/konkuk/thip/room/adapter/in/web/RoomJoinApiTest.java @@ -95,6 +95,7 @@ private void createUsers(AliasJpaEntity alias) { host = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_432708231") .nickname("user") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); @@ -102,6 +103,7 @@ private void createUsers(AliasJpaEntity alias) { participant = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_12345678") .nickname("user123") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); diff --git a/src/test/java/konkuk/thip/room/adapter/in/web/RoomPlayingDetailViewApiTest.java b/src/test/java/konkuk/thip/room/adapter/in/web/RoomPlayingDetailViewApiTest.java index 6796c7f53..382b041d6 100644 --- a/src/test/java/konkuk/thip/room/adapter/in/web/RoomPlayingDetailViewApiTest.java +++ b/src/test/java/konkuk/thip/room/adapter/in/web/RoomPlayingDetailViewApiTest.java @@ -11,6 +11,7 @@ import konkuk.thip.room.adapter.out.persistence.repository.RoomJpaRepository; import konkuk.thip.room.adapter.out.persistence.repository.category.CategoryJpaRepository; import konkuk.thip.room.adapter.out.persistence.repository.roomparticipant.RoomParticipantJpaRepository; +import konkuk.thip.room.domain.Category; import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserRole; @@ -121,6 +122,7 @@ private void saveUsersToRoom(RoomJpaEntity roomJpaEntity, int count) { List users = IntStream.rangeClosed(1, count) .mapToObj(i -> UserJpaEntity.builder() .nickname("user" + i) + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("oauth2Id") .role(UserRole.USER) .aliasForUserJpaEntity(alias) @@ -193,7 +195,7 @@ void get_playing_room_detail() throws Exception { result.andExpect(status().isOk()) .andExpect(jsonPath("$.data.isHost", is(false))) .andExpect(jsonPath("$.data.roomName", is("과학-방-1일뒤-활동시작"))) - .andExpect(jsonPath("$.data.roomImageUrl", is("과학/IT_image"))) // 방 대표 이미지 추가 + .andExpect(jsonPath("$.data.roomImageUrl", is(Category.SCIENCE_IT.getImageUrl()))) // 방 대표 이미지 추가 .andExpect(jsonPath("$.data.progressStartDate", is(DateUtil.formatDate(LocalDate.now().plusDays(1))))) .andExpect(jsonPath("$.data.memberCount", is(4))) .andExpect(jsonPath("$.data.recruitCount", is(10))) @@ -241,7 +243,7 @@ void get_playing_room_detail_host() throws Exception { result.andExpect(status().isOk()) .andExpect(jsonPath("$.data.isHost", is(true))) // 방 HOST 이면 true .andExpect(jsonPath("$.data.roomName", is("과학-방-1일뒤-활동시작"))) - .andExpect(jsonPath("$.data.roomImageUrl", is("과학/IT_image"))) // 방 대표 이미지 추가 + .andExpect(jsonPath("$.data.roomImageUrl", is(Category.SCIENCE_IT.getImageUrl()))) // 방 대표 이미지 추가 .andExpect(jsonPath("$.data.progressStartDate", is(DateUtil.formatDate(LocalDate.now().plusDays(1))))) .andExpect(jsonPath("$.data.memberCount", is(4))) .andExpect(jsonPath("$.data.recruitCount", is(10))) @@ -315,7 +317,7 @@ void get_playing_room_detail_too_many_votes() throws Exception { result.andExpect(status().isOk()) .andExpect(jsonPath("$.data.isHost", is(false))) .andExpect(jsonPath("$.data.roomName", is("과학-방-1일뒤-활동시작"))) - .andExpect(jsonPath("$.data.roomImageUrl", is("과학/IT_image"))) // 방 대표 이미지 추가 + .andExpect(jsonPath("$.data.roomImageUrl", is(Category.SCIENCE_IT.getImageUrl()))) // 방 대표 이미지 추가 .andExpect(jsonPath("$.data.progressStartDate", is(DateUtil.formatDate(LocalDate.now().plusDays(1))))) .andExpect(jsonPath("$.data.memberCount", is(4))) .andExpect(jsonPath("$.data.recruitCount", is(10))) @@ -367,7 +369,7 @@ void get_playing_room_detail_no_votes() throws Exception { result.andExpect(status().isOk()) .andExpect(jsonPath("$.data.isHost", is(false))) .andExpect(jsonPath("$.data.roomName", is("과학-방-1일뒤-활동시작"))) - .andExpect(jsonPath("$.data.roomImageUrl", is("과학/IT_image"))) // 방 대표 이미지 추가 + .andExpect(jsonPath("$.data.roomImageUrl", is(Category.SCIENCE_IT.getImageUrl()))) // 방 대표 이미지 추가 .andExpect(jsonPath("$.data.progressStartDate", is(DateUtil.formatDate(LocalDate.now().plusDays(1))))) .andExpect(jsonPath("$.data.memberCount", is(4))) .andExpect(jsonPath("$.data.recruitCount", is(10))) diff --git a/src/test/java/konkuk/thip/room/adapter/in/web/RoomRecruitingDetailViewApiTest.java b/src/test/java/konkuk/thip/room/adapter/in/web/RoomRecruitingDetailViewApiTest.java index 2f576bf08..64f75b3ee 100644 --- a/src/test/java/konkuk/thip/room/adapter/in/web/RoomRecruitingDetailViewApiTest.java +++ b/src/test/java/konkuk/thip/room/adapter/in/web/RoomRecruitingDetailViewApiTest.java @@ -136,6 +136,7 @@ private void saveUsersToRoom(RoomJpaEntity roomJpaEntity, int count) { List users = IntStream.rangeClosed(1, count) .mapToObj(i -> UserJpaEntity.builder() .nickname("user" + i) + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("oauth2Id") .role(UserRole.USER) .aliasForUserJpaEntity(alias) diff --git a/src/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.java b/src/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.java index 2457e94fb..8045ea119 100644 --- a/src/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.java +++ b/src/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.java @@ -9,6 +9,7 @@ import konkuk.thip.room.adapter.out.jpa.RoomParticipantRole; import konkuk.thip.room.adapter.out.persistence.repository.category.CategoryJpaRepository; import konkuk.thip.room.adapter.out.persistence.repository.RoomJpaRepository; +import konkuk.thip.room.domain.Category; import konkuk.thip.user.adapter.out.jpa.*; import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository; import konkuk.thip.user.adapter.out.persistence.repository.UserJpaRepository; @@ -135,6 +136,7 @@ private void saveUsersToRoom(RoomJpaEntity roomJpaEntity, int count) { List users = IntStream.rangeClosed(1, count) .mapToObj(i -> UserJpaEntity.builder() .nickname("user" + i) + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("oauth2Id") .role(UserRole.USER) .aliasForUserJpaEntity(alias) @@ -362,7 +364,7 @@ void search_keyword_and_category() throws Exception { ResultActions result = mockMvc.perform(get("/rooms/search") .requestAttr("userId", 1L) .param("keyword", "과학") - .param("category", "과학/IT") + .param("category", Category.SCIENCE_IT.getValue()) .param("sort", "deadline") .param("page", "1")); diff --git a/src/test/java/konkuk/thip/room/domain/RoomTest.java b/src/test/java/konkuk/thip/room/domain/RoomTest.java index 680f20500..faa62fb7f 100644 --- a/src/test/java/konkuk/thip/room/domain/RoomTest.java +++ b/src/test/java/konkuk/thip/room/domain/RoomTest.java @@ -21,7 +21,7 @@ class RoomTest { private final LocalDate today = LocalDate.now(); private final LocalDate START = today.plusDays(1); private final LocalDate END = today.plusDays(32); - private final Category validCategory = Category.from("과학/IT"); + private final Category validCategory = Category.SCIENCE_IT; @Test @DisplayName("withoutId: 공개 방이면서 password가 not null 이면, InvalidStateException 발생한다.") diff --git a/src/test/java/konkuk/thip/user/adapter/in/web/UserFollowApiTest.java b/src/test/java/konkuk/thip/user/adapter/in/web/UserFollowApiTest.java index ff555ce42..e542d5ca0 100644 --- a/src/test/java/konkuk/thip/user/adapter/in/web/UserFollowApiTest.java +++ b/src/test/java/konkuk/thip/user/adapter/in/web/UserFollowApiTest.java @@ -18,6 +18,7 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; +import java.time.LocalDate; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @@ -58,6 +59,7 @@ void changeFollowingState_follow_then_unfollow() throws Exception { UserJpaEntity followingUser = userJpaRepository.save(UserJpaEntity.builder() .nickname("user100") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("oauth2_user100") .role(UserRole.USER) .aliasForUserJpaEntity(alias) @@ -65,6 +67,7 @@ void changeFollowingState_follow_then_unfollow() throws Exception { UserJpaEntity target = userJpaRepository.save(UserJpaEntity.builder() .nickname("user200") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .oauth2Id("oauth2_user200") .role(UserRole.USER) .aliasForUserJpaEntity(alias) diff --git a/src/test/java/konkuk/thip/user/adapter/in/web/UserVerifyNicknameControllerTest.java b/src/test/java/konkuk/thip/user/adapter/in/web/UserVerifyNicknameControllerTest.java index 151922234..c26e0d41b 100644 --- a/src/test/java/konkuk/thip/user/adapter/in/web/UserVerifyNicknameControllerTest.java +++ b/src/test/java/konkuk/thip/user/adapter/in/web/UserVerifyNicknameControllerTest.java @@ -19,6 +19,8 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import java.time.LocalDate; + import static konkuk.thip.common.exception.code.ErrorCode.API_INVALID_PARAM; import static konkuk.thip.user.adapter.out.jpa.UserRole.USER; import static org.assertj.core.api.Assertions.assertThat; @@ -81,6 +83,7 @@ void verify_nickname_false() throws Exception { UserJpaEntity userJpaEntity = UserJpaEntity.builder() .nickname("테스트유저") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(USER) .oauth2Id("kakao_12345678") .aliasForUserJpaEntity(aliasJpaEntity) diff --git a/src/test/java/konkuk/thip/vote/adapter/in/web/VoteCreateControllerTest.java b/src/test/java/konkuk/thip/vote/adapter/in/web/VoteCreateControllerTest.java index e911248c1..389c4285b 100644 --- a/src/test/java/konkuk/thip/vote/adapter/in/web/VoteCreateControllerTest.java +++ b/src/test/java/konkuk/thip/vote/adapter/in/web/VoteCreateControllerTest.java @@ -8,6 +8,7 @@ import konkuk.thip.room.adapter.out.jpa.RoomJpaEntity; import konkuk.thip.room.adapter.out.persistence.repository.category.CategoryJpaRepository; import konkuk.thip.room.adapter.out.persistence.repository.RoomJpaRepository; +import konkuk.thip.room.domain.Category; import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserRole; @@ -95,6 +96,7 @@ private void saveUserAndRoom() { UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() .oauth2Id("kakao_432708231") .nickname("User1") + .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) .role(UserRole.USER) .aliasForUserJpaEntity(alias) .build()); @@ -112,8 +114,8 @@ private void saveUserAndRoom() { CategoryJpaEntity category = categoryJpaRepository.save(CategoryJpaEntity.builder() - .value("과학/IT") - .imageUrl("과학/IT_image") + .value(Category.SCIENCE_IT.getValue()) + .imageUrl(Category.SCIENCE_IT.getImageUrl()) .aliasForCategoryJpaEntity(alias) .build()); From 71800219407f47b31d037be736482b3a429570b3 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 1 Aug 2025 22:07:11 +0900 Subject: [PATCH 10/10] =?UTF-8?q?[docs]=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=ED=8E=B8=EC=A7=91=20api=20=EB=AA=85=EC=84=B8=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/swagger/SwaggerResponseDescription.java | 10 ++++++++++ .../user/adapter/in/web/UserCommandController.java | 8 ++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java b/src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java index b59ad4f46..14db85f1d 100644 --- a/src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java +++ b/src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java @@ -26,6 +26,16 @@ public enum SwaggerResponseDescription { USER_SEARCH(new LinkedHashSet<>(Set.of( USER_NOT_FOUND ))), + USER_UPDATE(new LinkedHashSet<>(Set.of( + USER_NOT_FOUND, + ALIAS_NAME_NOT_MATCH, + USER_NICKNAME_TOO_LONG, + USER_NICKNAME_CANNOT_BE_BLANK, + USER_NICKNAME_CANNOT_BE_SAME, + USER_NICKNAME_UPDATE_TOO_FREQUENT, + USER_NICKNAME_ALREADY_EXISTS + ))), + // Follow CHANGE_FOLLOW_STATE(new LinkedHashSet<>(Set.of( diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java index 87ece35c1..09db4e44a 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java @@ -23,8 +23,7 @@ import static konkuk.thip.common.security.constant.AuthParameters.JWT_HEADER_KEY; import static konkuk.thip.common.security.constant.AuthParameters.JWT_PREFIX; -import static konkuk.thip.common.swagger.SwaggerResponseDescription.CHANGE_FOLLOW_STATE; -import static konkuk.thip.common.swagger.SwaggerResponseDescription.USER_SIGNUP; +import static konkuk.thip.common.swagger.SwaggerResponseDescription.*; @Tag(name = "User Command API", description = "사용자가 주체가 되는 정보 수정") @RestController @@ -67,6 +66,11 @@ public BaseResponse followUser( ))); } + @Operation( + summary = "사용자 정보 수정", + description = "사용자가 자신의 정보를 수정합니다. 닉네임과 칭호(Alias)를 수정할 수 있습니다." + ) + @ExceptionDescription(USER_UPDATE) @PatchMapping("/users") public BaseResponse updateUser( @Parameter(hidden = true) @UserId final Long userId,