diff --git a/backend/kirikiri/build.gradle b/backend/kirikiri/build.gradle index dd29aa9f9..7bd653e1d 100644 --- a/backend/kirikiri/build.gradle +++ b/backend/kirikiri/build.gradle @@ -170,6 +170,9 @@ dependencies { // flyway implementation 'org.flywaydb:flyway-mysql' + // redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + // test testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/config/AWSConfig.java b/backend/kirikiri/src/main/java/co/kirikiri/common/config/AWSConfig.java index b084ee0eb..21500a245 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/config/AWSConfig.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/config/AWSConfig.java @@ -1,5 +1,7 @@ package co.kirikiri.common.config; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; @@ -11,15 +13,23 @@ public class AWSConfig { private final Regions region; + private final String accessKey; + private final String secretKey; - public AWSConfig(@Value("${cloud.aws.region.static}") final String region) { + public AWSConfig(@Value("${cloud.aws.region.static}") final String region, + @Value("${cloud.aws.credentials.access-key}") final String accessKey, + @Value("${cloud.aws.credentials.secret-key}") final String secretKey) { this.region = Regions.fromName(region); + this.accessKey = accessKey; + this.secretKey = secretKey; } @Bean public AmazonS3 amazonS3() { + final BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); return AmazonS3ClientBuilder.standard() .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) .build(); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/config/JpaConfig.java b/backend/kirikiri/src/main/java/co/kirikiri/common/config/JpaConfig.java deleted file mode 100644 index 18158e4fb..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/config/JpaConfig.java +++ /dev/null @@ -1,10 +0,0 @@ -package co.kirikiri.common.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; - -@Configuration -@EnableJpaAuditing -public class JpaConfig { - -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/config/RedisConfig.java b/backend/kirikiri/src/main/java/co/kirikiri/common/config/RedisConfig.java new file mode 100644 index 000000000..e49a413d9 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/config/RedisConfig.java @@ -0,0 +1,52 @@ +package co.kirikiri.common.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import java.time.Duration; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +@EnableCaching +@Profile(value = {"prod", "dev", "local"}) +public class RedisConfig { + + @Bean + public RedisTemplate redisTemplate(final RedisConnectionFactory redisConnectionFactory) { + final RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + return redisTemplate; + } + + @Bean + public CacheManager redisCacheManager(final RedisConnectionFactory redisConnectionFactory) { + final ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.EVERYTHING); + + final RedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper); + + final RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() + .entryTtl(Duration.ofMinutes(30L)) + .disableCachingNullValues() + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer)); + + return RedisCacheManager.RedisCacheManagerBuilder + .fromConnectionFactory(redisConnectionFactory) + .cacheDefaults(redisCacheConfiguration) + .build(); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java b/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java index b296550ff..d2298df5c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java @@ -1,7 +1,7 @@ package co.kirikiri.common.interceptor; -import co.kirikiri.exception.AuthenticationException; import co.kirikiri.service.auth.AuthService; +import co.kirikiri.service.exception.AuthenticationException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java index f076d15dd..caf9b0e30 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java @@ -1,7 +1,9 @@ package co.kirikiri.common.resolver; -import co.kirikiri.exception.AuthenticationException; +import co.kirikiri.common.interceptor.Authenticated; import co.kirikiri.service.auth.AuthService; +import co.kirikiri.service.exception.AuthenticationException; +import co.kirikiri.service.exception.ServerException; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; @@ -21,6 +23,9 @@ public class MemberIdentifierArgumentResolver implements HandlerMethodArgumentRe @Override public boolean supportsParameter(final MethodParameter parameter) { + if (!parameter.hasMethodAnnotation(Authenticated.class)) { + throw new ServerException("MemberIdentifier는 인증된 사용자만 사용 가능합니다. (@Authenticated)"); + } return parameter.getParameterType().equals(String.class) && parameter.hasParameterAnnotation(MemberIdentifier.class); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java index 5a25323a0..fb080e831 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java @@ -1,11 +1,12 @@ package co.kirikiri.common.resolver; -import co.kirikiri.exception.BadRequestException; import co.kirikiri.service.dto.roadmap.request.RoadmapNodeSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; +import co.kirikiri.service.exception.BadRequestException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; @@ -20,7 +21,6 @@ import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; -import java.util.List; @Component @RequiredArgsConstructor diff --git a/backend/kirikiri/src/main/java/co/kirikiri/controller/GlobalExceptionHandler.java b/backend/kirikiri/src/main/java/co/kirikiri/controller/GlobalExceptionHandler.java index 9a2c47607..181ac9cb0 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/controller/GlobalExceptionHandler.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/controller/GlobalExceptionHandler.java @@ -1,13 +1,14 @@ package co.kirikiri.controller; -import co.kirikiri.exception.AuthenticationException; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ConflictException; -import co.kirikiri.exception.ForbiddenException; -import co.kirikiri.exception.NotFoundException; -import co.kirikiri.exception.ServerException; import co.kirikiri.service.dto.ErrorResponse; +import co.kirikiri.service.exception.AuthenticationException; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ConflictException; +import co.kirikiri.service.exception.ForbiddenException; +import co.kirikiri.service.exception.NotFoundException; +import co.kirikiri.service.exception.ServerException; import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -15,7 +16,6 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; -import java.util.List; @RestControllerAdvice public class GlobalExceptionHandler { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/controller/GoalRoomController.java b/backend/kirikiri/src/main/java/co/kirikiri/controller/GoalRoomController.java index f39625033..671c65dd8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/controller/GoalRoomController.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/controller/GoalRoomController.java @@ -2,8 +2,6 @@ import co.kirikiri.common.interceptor.Authenticated; import co.kirikiri.common.resolver.MemberIdentifier; -import co.kirikiri.service.goalroom.GoalRoomCreateService; -import co.kirikiri.service.goalroom.GoalRoomReadService; import co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto; import co.kirikiri.service.dto.goalroom.request.CheckFeedRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; @@ -18,6 +16,8 @@ import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; +import co.kirikiri.service.goalroom.GoalRoomCreateService; +import co.kirikiri.service.goalroom.GoalRoomReadService; import jakarta.validation.Valid; import java.net.URI; import java.util.List; @@ -50,16 +50,16 @@ public ResponseEntity create(@RequestBody @Valid final GoalRoomCreateReque return ResponseEntity.created(URI.create("/api/goal-rooms/" + id)).build(); } - @Authenticated @PostMapping("/{goalRoomId}/join") + @Authenticated public ResponseEntity joinGoalRoom(@MemberIdentifier final String identifier, @PathVariable final Long goalRoomId) { goalRoomCreateService.join(identifier, goalRoomId); return ResponseEntity.status(HttpStatus.OK).build(); } - @Authenticated @PostMapping("/{goalRoomId}/todos") + @Authenticated public ResponseEntity addTodo(@RequestBody @Valid final GoalRoomTodoRequest goalRoomTodoRequest, @PathVariable final Long goalRoomId, @MemberIdentifier final String identifier) { @@ -67,8 +67,8 @@ public ResponseEntity addTodo(@RequestBody @Valid final GoalRoomTodoReques return ResponseEntity.created(URI.create("/api/goal-rooms/" + goalRoomId + "/todos/" + id)).build(); } - @Authenticated @PostMapping("/{goalRoomId}/todos/{todoId}") + @Authenticated public ResponseEntity checkTodo(@PathVariable final Long goalRoomId, @PathVariable final Long todoId, @MemberIdentifier final String identifier) { @@ -77,8 +77,8 @@ public ResponseEntity checkTodo(@PathVariable final L return ResponseEntity.ok(checkResponse); } - @Authenticated @PostMapping(value = "/{goalRoomId}/checkFeeds", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) + @Authenticated public ResponseEntity createCheckFeed(@MemberIdentifier final String identifier, @PathVariable("goalRoomId") final Long goalRoomId, @ModelAttribute final CheckFeedRequest checkFeedRequest) { @@ -116,8 +116,8 @@ public ResponseEntity findGoalRoom(@PathVariable("goalRoomId") return ResponseEntity.ok(goalRoomResponse); } - @Authenticated @GetMapping("/{goalRoomId}/members") + @Authenticated public ResponseEntity> findGoalRoomMembers( @PathVariable final Long goalRoomId, @RequestParam(value = "sortCond", required = false) final GoalRoomMemberSortTypeDto sortType) { @@ -126,8 +126,8 @@ public ResponseEntity> findGoalRoomMembers( return ResponseEntity.ok(goalRoomMembers); } - @Authenticated @GetMapping("/{goalRoomId}/me") + @Authenticated public ResponseEntity findMemberGoalRoom( @MemberIdentifier final String identifier, @PathVariable final Long goalRoomId) { final MemberGoalRoomResponse memberGoalRoomResponse = goalRoomReadService.findMemberGoalRoom(identifier, @@ -135,8 +135,8 @@ public ResponseEntity findMemberGoalRoom( return ResponseEntity.ok(memberGoalRoomResponse); } - @Authenticated @GetMapping("/me") + @Authenticated public ResponseEntity> findMemberGoalRoomsByStatus( @MemberIdentifier final String identifier, @RequestParam(value = "statusCond", required = false) final GoalRoomStatusTypeRequest goalRoomStatusTypeRequest) { @@ -150,8 +150,8 @@ public ResponseEntity> findMemberGoalRoomsBy return ResponseEntity.ok(memberGoalRoomForListResponses); } - @Authenticated @GetMapping("/{goalRoomId}/todos") + @Authenticated public ResponseEntity> findAllTodos( @PathVariable final Long goalRoomId, @MemberIdentifier final String identifier) { @@ -160,8 +160,8 @@ public ResponseEntity> findAllTodos( return ResponseEntity.ok(todoResponses); } - @Authenticated @GetMapping("/{goalRoomId}/nodes") + @Authenticated public ResponseEntity> findAllNodes( @PathVariable final Long goalRoomId, @MemberIdentifier final String identifier @@ -171,8 +171,8 @@ public ResponseEntity> findAllNodes( return ResponseEntity.ok(nodeResponses); } - @Authenticated @GetMapping("/{goalRoomId}/checkFeeds") + @Authenticated public ResponseEntity> findGoalRoomCheckFeeds( @MemberIdentifier final String identifier, @PathVariable("goalRoomId") final Long goalRoomId) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/controller/RoadmapController.java b/backend/kirikiri/src/main/java/co/kirikiri/controller/RoadmapController.java index 98a894a86..21abca873 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/controller/RoadmapController.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/controller/RoadmapController.java @@ -2,8 +2,6 @@ import co.kirikiri.common.interceptor.Authenticated; import co.kirikiri.common.resolver.MemberIdentifier; -import co.kirikiri.service.roadmap.RoadmapCreateService; -import co.kirikiri.service.roadmap.RoadmapReadService; import co.kirikiri.service.dto.CustomScrollRequest; import co.kirikiri.service.dto.roadmap.RoadmapGoalRoomsOrderTypeDto; import co.kirikiri.service.dto.roadmap.request.RoadmapCategorySaveRequest; @@ -17,7 +15,11 @@ import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; +import co.kirikiri.service.roadmap.RoadmapCreateService; +import co.kirikiri.service.roadmap.RoadmapReadService; import jakarta.validation.Valid; +import java.net.URI; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -31,8 +33,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.net.URI; -import java.util.List; @RestController @RequestMapping("/roadmaps") @@ -42,14 +42,15 @@ public class RoadmapController { private final RoadmapCreateService roadmapCreateService; private final RoadmapReadService roadmapReadService; - @Authenticated @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @Authenticated public ResponseEntity create(final RoadmapSaveRequest request, @MemberIdentifier final String identifier) { final Long roadmapId = roadmapCreateService.create(request, identifier); return ResponseEntity.created(URI.create("/api/roadmaps/" + roadmapId)).build(); } @PostMapping("/{roadmapId}/reviews") + @Authenticated public ResponseEntity createReview( @PathVariable("roadmapId") final Long roadmapId, @MemberIdentifier final String identifier, @@ -93,7 +94,8 @@ public ResponseEntity> findAllRoadmapCategories() } @PostMapping("/categories") - public ResponseEntity createRoadmapCategory(@RequestBody @Valid final RoadmapCategorySaveRequest roadmapCategorySaveRequest) { + public ResponseEntity createRoadmapCategory( + @RequestBody @Valid final RoadmapCategorySaveRequest roadmapCategorySaveRequest) { roadmapCreateService.createRoadmapCategory(roadmapCategorySaveRequest); return ResponseEntity.status(HttpStatus.CREATED).build(); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseCreatedTimeEntity.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseCreatedTimeEntity.java index 82d3cb77e..383bd9634 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseCreatedTimeEntity.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseCreatedTimeEntity.java @@ -1,28 +1,23 @@ package co.kirikiri.domain; import jakarta.persistence.Column; -import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; import jakarta.persistence.PrePersist; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @MappedSuperclass -@EntityListeners(AuditingEntityListener.class) public class BaseCreatedTimeEntity extends BaseEntity { - private static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSSSS"; + protected static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSSSS"; - @CreatedDate @Column(nullable = false, updatable = false) protected LocalDateTime createdAt; @PrePersist - public void prePersist() { + protected void prePersist() { final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMAT); - final String formattedTime = createdAt.format(formatter); + final String formattedTime = LocalDateTime.now().format(formatter); createdAt = LocalDateTime.parse(formattedTime, formatter); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseEntity.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseEntity.java index 2f257106b..a66368c62 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseEntity.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseEntity.java @@ -1,15 +1,12 @@ package co.kirikiri.domain; -import jakarta.persistence.EntityListeners; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; import java.util.Objects; @MappedSuperclass -@EntityListeners(AuditingEntityListener.class) public class BaseEntity { @Id diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseUpdatedTimeEntity.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseUpdatedTimeEntity.java index ea6b22ff1..7434bf778 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseUpdatedTimeEntity.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseUpdatedTimeEntity.java @@ -1,17 +1,29 @@ package co.kirikiri.domain; import jakarta.persistence.Column; -import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import jakarta.persistence.PreUpdate; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; @MappedSuperclass -@EntityListeners(AuditingEntityListener.class) public class BaseUpdatedTimeEntity extends BaseCreatedTimeEntity { - @LastModifiedDate @Column(nullable = false) private LocalDateTime updatedAt; + + @Override + protected void prePersist() { + final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMAT); + final String formattedTime = LocalDateTime.now().format(formatter); + createdAt = LocalDateTime.parse(formattedTime, formatter); + updatedAt = LocalDateTime.parse(formattedTime, formatter); + } + + @PreUpdate + private void preUpdate() { + final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMAT); + final String formattedTime = LocalDateTime.now().format(formatter); + updatedAt = LocalDateTime.parse(formattedTime, formatter); + } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/ImageContentType.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/ImageContentType.java index 681e49136..9d8a4df07 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/ImageContentType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/ImageContentType.java @@ -1,6 +1,6 @@ package co.kirikiri.domain; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.exception.ImageExtensionException; import java.util.Arrays; public enum ImageContentType { @@ -21,6 +21,6 @@ public static ImageContentType findImageContentType(final String imageContentTyp return Arrays.stream(values()) .filter(it -> it.extension.equals(imageContentType)) .findAny() - .orElseThrow(() -> new BadRequestException("허용되지 않는 확장자입니다.")); + .orElseThrow(() -> new ImageExtensionException("허용되지 않는 확장자입니다.")); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/auth/EncryptedToken.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/auth/EncryptedToken.java deleted file mode 100644 index 192998399..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/auth/EncryptedToken.java +++ /dev/null @@ -1,57 +0,0 @@ -package co.kirikiri.domain.auth; - -import co.kirikiri.exception.ServerException; -import jakarta.persistence.Column; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Base64; -import java.util.Objects; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter -public class EncryptedToken { - - private static final String ALGORITHM = "SHA-256"; - - @Column(name = "token", nullable = false) - private String value; - - public EncryptedToken(final String rawToken) { - this.value = encrypt(rawToken); - } - - private String encrypt(final String rawToken) { - final MessageDigest messageDigest = findMessageDigest(); - messageDigest.update(rawToken.getBytes()); - final byte[] hashedToken = messageDigest.digest(); - return Base64.getEncoder().encodeToString(hashedToken); - } - - private MessageDigest findMessageDigest() { - try { - return MessageDigest.getInstance(ALGORITHM); - } catch (final NoSuchAlgorithmException exception) { - throw new ServerException(exception.getMessage()); - } - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final EncryptedToken that = (EncryptedToken) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/auth/RefreshToken.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/auth/RefreshToken.java deleted file mode 100644 index 571e528d5..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/auth/RefreshToken.java +++ /dev/null @@ -1,55 +0,0 @@ -package co.kirikiri.domain.auth; - -import co.kirikiri.domain.member.Member; -import jakarta.persistence.Column; -import jakarta.persistence.Embedded; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import java.time.LocalDateTime; - -@Entity -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class RefreshToken { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Embedded - private EncryptedToken token; - - @Column(nullable = false) - private LocalDateTime expiredAt; - - @Column(nullable = false) - private final boolean isRevoked = false; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id", nullable = false) - private Member member; - - public RefreshToken(final EncryptedToken token, final LocalDateTime expiredAt, final Member member) { - this.token = token; - this.expiredAt = expiredAt; - this.member = member; - } - - public boolean isExpired() { - return expiredAt.isBefore(LocalDateTime.now()); - } - - public EncryptedToken getToken() { - return token; - } - - public Member getMember() { - return member; - } -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/DomainException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/DomainException.java new file mode 100644 index 000000000..bf1161db4 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/DomainException.java @@ -0,0 +1,8 @@ +package co.kirikiri.domain.exception; + +public class DomainException extends RuntimeException { + + public DomainException(final String message) { + super(message); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/ImageExtensionException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/ImageExtensionException.java new file mode 100644 index 000000000..3a8e84f67 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/ImageExtensionException.java @@ -0,0 +1,8 @@ +package co.kirikiri.domain.exception; + +public class ImageExtensionException extends DomainException { + + public ImageExtensionException(final String message) { + super(message); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/UnexpectedDomainException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/UnexpectedDomainException.java new file mode 100644 index 000000000..50735c79e --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/UnexpectedDomainException.java @@ -0,0 +1,8 @@ +package co.kirikiri.domain.exception; + +public class UnexpectedDomainException extends DomainException { + + public UnexpectedDomainException(final String message) { + super(message); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/BaseGoalRoomMember.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/BaseGoalRoomMember.java index 14eb20161..e034bc6d6 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/BaseGoalRoomMember.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/BaseGoalRoomMember.java @@ -3,25 +3,26 @@ import co.kirikiri.domain.BaseEntity; import co.kirikiri.domain.member.Member; import com.querydsl.core.annotations.QueryInit; -import jakarta.persistence.EntityListeners; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.PrePersist; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Objects; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import java.time.LocalDateTime; -import java.util.Objects; @MappedSuperclass -@EntityListeners(AuditingEntityListener.class) @NoArgsConstructor(access = AccessLevel.PROTECTED) public abstract class BaseGoalRoomMember extends BaseEntity { + protected static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSSSS"; + @Enumerated(value = EnumType.STRING) protected GoalRoomRole role; @@ -52,6 +53,13 @@ public BaseGoalRoomMember(final Long id, final GoalRoomRole role, final LocalDat this.member = member; } + @PrePersist + private void prePersist() { + final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMAT); + final String formattedTime = LocalDateTime.now().format(formatter); + joinedAt = LocalDateTime.parse(formattedTime, formatter); + } + public boolean isLeader() { return role == GoalRoomRole.LEADER; } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoom.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoom.java index 57fbcc7e6..e10f05f82 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoom.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoom.java @@ -1,11 +1,11 @@ package co.kirikiri.domain.goalroom; import co.kirikiri.domain.BaseUpdatedTimeEntity; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import co.kirikiri.domain.goalroom.vo.GoalRoomName; import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.roadmap.RoadmapContent; -import co.kirikiri.exception.BadRequestException; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; @@ -14,13 +14,13 @@ import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -75,13 +75,13 @@ public GoalRoom(final Long id, final GoalRoomName name, final LimitedMemberCount private void updateLeader(final Member member) { final GoalRoomPendingMember leader = new GoalRoomPendingMember(GoalRoomRole.LEADER, member); - leader.updateGoalRoom(this); + leader.initGoalRoom(this); goalRoomPendingMembers.add(leader); } public void join(final Member member) { final GoalRoomPendingMember newMember = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, member); - newMember.updateGoalRoom(this); + newMember.initGoalRoom(this); validateJoinGoalRoom(newMember); goalRoomPendingMembers.add(newMember); } @@ -94,19 +94,19 @@ private void validateJoinGoalRoom(final GoalRoomPendingMember member) { private void validateMemberCount() { if (getCurrentMemberCount() >= limitedMemberCount.getValue()) { - throw new BadRequestException("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다."); + throw new GoalRoomException("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다."); } } private void validateStatus() { if (status != GoalRoomStatus.RECRUITING) { - throw new BadRequestException("모집 중이지 않은 골룸에는 참여할 수 없습니다."); + throw new GoalRoomException("모집 중이지 않은 골룸에는 참여할 수 없습니다."); } } private void validateAlreadyParticipated(final GoalRoomPendingMember member) { if (goalRoomPendingMembers.containGoalRoomPendingMember(member)) { - throw new BadRequestException("이미 참여한 골룸에는 참여할 수 없습니다."); + throw new GoalRoomException("이미 참여한 골룸에는 참여할 수 없습니다."); } } @@ -143,7 +143,7 @@ public void addAllGoalRoomRoadmapNodes(final GoalRoomRoadmapNodes goalRoomRoadma private void checkTotalSize(final int totalSize) { if (totalSize > roadmapContent.nodesSize()) { - throw new BadRequestException("로드맵의 노드 수보다 골룸의 노드 수가 큽니다."); + throw new GoalRoomException("로드맵의 노드 수보다 골룸의 노드 수가 큽니다."); } } @@ -214,7 +214,7 @@ public boolean cannotStart() { private GoalRoomPendingMember findGoalRoomPendingMemberByMember(final Member member) { return goalRoomPendingMembers.findByMember(member) - .orElseThrow(() -> new BadRequestException("골룸에 참여한 사용자가 아닙니다. memberId = " + member.getId())); + .orElseThrow(() -> new GoalRoomException("골룸에 참여한 사용자가 아닙니다. memberId = " + member.getId())); } private void changeRoleIfLeaderLeave(final GoalRoomPendingMembers goalRoomPendingMembers, @@ -227,7 +227,7 @@ private void changeRoleIfLeaderLeave(final GoalRoomPendingMembers goalRoomPendin private GoalRoomMember findGoalRoomMemberByMember(final Member member) { return goalRoomMembers.findByMember(member) - .orElseThrow(() -> new BadRequestException("골룸에 참여한 사용자가 아닙니다. memberId = " + member.getId())); + .orElseThrow(() -> new GoalRoomException("골룸에 참여한 사용자가 아닙니다. memberId = " + member.getId())); } private void changeRoleIfLeaderLeave(final GoalRoomMembers goalRoomMembers, diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMembers.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMembers.java index 3a7638b5c..f05d9d369 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMembers.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMembers.java @@ -1,19 +1,18 @@ package co.kirikiri.domain.goalroom; +import co.kirikiri.domain.exception.UnexpectedDomainException; import co.kirikiri.domain.member.Member; -import co.kirikiri.exception.NotFoundException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; import jakarta.persistence.OneToMany; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.BatchSize; - import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Optional; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.BatchSize; @Embeddable @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -68,7 +67,7 @@ public Member findGoalRoomLeader() { .filter(GoalRoomMember::isLeader) .findFirst() .map(GoalRoomMember::getMember) - .orElseThrow(() -> new NotFoundException("골룸의 리더가 없습니다.")); + .orElseThrow(() -> new UnexpectedDomainException("골룸의 리더가 없습니다.")); } public int size() { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMember.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMember.java index 9693080be..ab671fb74 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMember.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMember.java @@ -1,11 +1,10 @@ package co.kirikiri.domain.goalroom; import co.kirikiri.domain.member.Member; -import co.kirikiri.exception.ServerException; import jakarta.persistence.Entity; +import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -29,14 +28,9 @@ public GoalRoomPendingMember(final Long id, final GoalRoomRole role, final Local super(id, role, joinedAt, goalRoom, member); } - public void updateGoalRoom(final GoalRoom goalRoom) { + public void initGoalRoom(final GoalRoom goalRoom) { if (this.goalRoom == null) { this.goalRoom = goalRoom; - return; - } - if (this.goalRoom.equals(goalRoom)) { - return; } - throw new ServerException("골룸을 변경할 수 없습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembers.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembers.java index ec26f1258..6cd84a26c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembers.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembers.java @@ -1,19 +1,18 @@ package co.kirikiri.domain.goalroom; +import co.kirikiri.domain.exception.UnexpectedDomainException; import co.kirikiri.domain.member.Member; -import co.kirikiri.exception.NotFoundException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; import jakarta.persistence.OneToMany; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.BatchSize; - import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Optional; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.BatchSize; @Embeddable @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -54,7 +53,7 @@ public Member findGoalRoomLeader() { .filter(GoalRoomPendingMember::isLeader) .findFirst() .map(GoalRoomPendingMember::getMember) - .orElseThrow(() -> new NotFoundException("골룸의 리더가 없습니다.")); + .orElseThrow(() -> new UnexpectedDomainException("골룸의 리더가 없습니다.")); } public boolean isNotLeader(final Member member) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNode.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNode.java index 262c7ae14..a8ec84112 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNode.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNode.java @@ -1,17 +1,17 @@ package co.kirikiri.domain.goalroom; import co.kirikiri.domain.BaseEntity; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import co.kirikiri.domain.goalroom.vo.Period; import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.exception.BadRequestException; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.time.LocalDate; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.time.LocalDate; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -48,13 +48,13 @@ private void validate(final Period period, final Integer checkCount) { private void validateCheckCountPositive(final Integer checkCount) { if (checkCount < MIN_CHECK_COUNT) { - throw new BadRequestException("골룸 노드의 인증 횟수는 0보다 커야합니다."); + throw new GoalRoomException("골룸 노드의 인증 횟수는 0보다 커야합니다."); } } private void validateCheckCountWithDaysBetween(final Period period, final int checkCount) { if (checkCount > period.getDayCount()) { - throw new BadRequestException("골룸 노드의 인증 횟수가 설정 기간보다 클 수 없습니다."); + throw new GoalRoomException("골룸 노드의 인증 횟수가 설정 기간보다 클 수 없습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodes.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodes.java index 1db980ab4..83401f80d 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodes.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodes.java @@ -1,14 +1,11 @@ package co.kirikiri.domain.goalroom; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.NotFoundException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.ArrayList; @@ -16,6 +13,8 @@ import java.util.List; import java.util.Optional; import java.util.stream.IntStream; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; @Embeddable @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -42,7 +41,7 @@ public void validatePeriodNoOverlap(final List nodes) { .filter(index -> nodes.get(index).isEndDateEqualOrAfterOtherStartDate(nodes.get(index + 1))) .findAny() .ifPresent(it -> { - throw new BadRequestException("골룸 노드의 기간이 겹칠 수 없습니다."); + throw new GoalRoomException("골룸 노드의 기간이 겹칠 수 없습니다."); }); } @@ -57,14 +56,14 @@ public void addAll(final GoalRoomRoadmapNodes goalRoomRoadmapNodes) { public LocalDate getGoalRoomStartDate() { return values.stream() .min(Comparator.comparing(GoalRoomRoadmapNode::getStartDate)) - .orElseThrow(() -> new NotFoundException("골룸에 노드가 존재하지 않습니다.")) + .orElseThrow(() -> new GoalRoomException("골룸에 노드가 존재하지 않습니다.")) .getStartDate(); } public LocalDate getGoalRoomEndDate() { return values.stream() .max(Comparator.comparing(GoalRoomRoadmapNode::getEndDate)) - .orElseThrow(() -> new NotFoundException("골룸에 노드가 존재하지 않습니다.")) + .orElseThrow(() -> new GoalRoomException("골룸에 노드가 존재하지 않습니다.")) .getEndDate(); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/exception/GoalRoomException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/exception/GoalRoomException.java new file mode 100644 index 000000000..514495361 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/exception/GoalRoomException.java @@ -0,0 +1,10 @@ +package co.kirikiri.domain.goalroom.exception; + +import co.kirikiri.domain.exception.DomainException; + +public class GoalRoomException extends DomainException { + + public GoalRoomException(final String message) { + super(message); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomName.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomName.java index 1e6922195..8893b12de 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomName.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomName.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.goalroom.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -23,7 +23,7 @@ public GoalRoomName(final String value) { private void validate(final String value) { if (value.length() < MIN_LENGTH || value.length() > MAX_LENGTH) { - throw new BadRequestException("골룸 이름의 길이가 적절하지 않습니다."); + throw new GoalRoomException("골룸 이름의 길이가 적절하지 않습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContent.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContent.java index 485e07e70..4b5096307 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContent.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContent.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.goalroom.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -23,7 +23,7 @@ public GoalRoomTodoContent(final String value) { private void validate(final String value) { if (value.length() < MIN_LENGTH || value.length() > MAX_LENGTH) { - throw new BadRequestException("투두 컨텐츠의 길이가 적절하지 않습니다."); + throw new GoalRoomException("투두 컨텐츠의 길이가 적절하지 않습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCount.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCount.java index 2c9e74844..9160fb278 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCount.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCount.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.goalroom.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -23,7 +23,7 @@ public LimitedMemberCount(final int value) { private void validate(final int value) { if (value < MIN || value > MAX) { - throw new BadRequestException("제한 인원 수가 적절하지 않습니다."); + throw new GoalRoomException("제한 인원 수가 적절하지 않습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/Period.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/Period.java index 1016d9ac9..881202f46 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/Period.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/Period.java @@ -1,12 +1,12 @@ package co.kirikiri.domain.goalroom.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import java.time.LocalDate; import java.time.temporal.ChronoUnit; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; @Embeddable @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -31,13 +31,13 @@ private void validate(final LocalDate startDate, final LocalDate endDate) { private void validateStartDateAfterNow(final LocalDate startDate) { if (startDate.isBefore(LocalDate.now())) { - throw new BadRequestException("시작일은 오늘보다 전일 수 없습니다."); + throw new GoalRoomException("시작일은 오늘보다 전일 수 없습니다."); } } private void validateStartDateBeforeOrEqualEndDate(final LocalDate startDate, final LocalDate endDate) { if (startDate.isAfter(endDate)) { - throw new BadRequestException("시작일은 종료일보다 후일 수 없습니다."); + throw new GoalRoomException("시작일은 종료일보다 후일 수 없습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java index 7aa459735..3dfb27793 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java @@ -1,14 +1,14 @@ package co.kirikiri.domain.member; +import co.kirikiri.domain.exception.UnexpectedDomainException; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.exception.ServerException; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Base64; import java.util.Objects; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; @NoArgsConstructor(access = AccessLevel.PROTECTED) public class EncryptedPassword { @@ -42,7 +42,7 @@ private MessageDigest findMessageDigest() { try { return MessageDigest.getInstance(ALGORITHM); } catch (final NoSuchAlgorithmException exception) { - throw new ServerException(exception.getMessage()); + throw new UnexpectedDomainException(exception.getMessage()); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/exception/MemberException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/exception/MemberException.java new file mode 100644 index 000000000..44f6fa57b --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/exception/MemberException.java @@ -0,0 +1,10 @@ +package co.kirikiri.domain.member.exception; + +import co.kirikiri.domain.exception.DomainException; + +public class MemberException extends DomainException { + + public MemberException(final String message) { + super(message); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Identifier.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Identifier.java index 05227ed42..f3ee6e3c1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Identifier.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Identifier.java @@ -1,10 +1,10 @@ package co.kirikiri.domain.member.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.member.exception.MemberException; import jakarta.persistence.Column; +import java.util.Objects; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.util.Objects; @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Identifier { @@ -22,7 +22,7 @@ public Identifier(final String value) { private void validate(final String value) { if (isNotValidLength(value)) { - throw new BadRequestException("제약 조건에 맞지 않는 아이디입니다."); + throw new MemberException("제약 조건에 맞지 않는 아이디입니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Nickname.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Nickname.java index 19b1abed3..3032a52a4 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Nickname.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Nickname.java @@ -1,9 +1,9 @@ package co.kirikiri.domain.member.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.member.exception.MemberException; import jakarta.persistence.Column; -import lombok.NoArgsConstructor; import java.util.Objects; +import lombok.NoArgsConstructor; @NoArgsConstructor public class Nickname { @@ -21,7 +21,7 @@ public Nickname(final String value) { private void validate(final String value) { if (isNotValidLength(value)) { - throw new BadRequestException("제약 조건에 맞지 않는 닉네임입니다."); + throw new MemberException("제약 조건에 맞지 않는 닉네임입니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Password.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Password.java index 54c63c621..10db63859 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Password.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/vo/Password.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.member.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.member.exception.MemberException; import lombok.Getter; @Getter @@ -19,7 +19,7 @@ public Password(final String value) { private void validate(final String value) { if (isNotValidLength(value) || isNotValidPattern(value)) { - throw new BadRequestException("제약 조건에 맞지 않는 비밀번호입니다."); + throw new MemberException("제약 조건에 맞지 않는 비밀번호입니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java index 92d852ac3..6c509d470 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java @@ -2,7 +2,7 @@ import co.kirikiri.domain.BaseCreatedTimeEntity; import co.kirikiri.domain.member.Member; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; @@ -11,11 +11,11 @@ import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.util.Objects; +import java.util.Optional; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; -import java.util.Objects; -import java.util.Optional; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -101,7 +101,7 @@ private void validate(final String title, final String introduction, final int r private void validateTitleLength(final String title) { if (title.length() < TITLE_MIN_LENGTH || title.length() > TITLE_MAX_LENGTH) { - throw new BadRequestException( + throw new RoadmapException( String.format("로드맵 제목의 길이는 최소 %d글자, 최대 %d글자입니다.", TITLE_MIN_LENGTH, TITLE_MAX_LENGTH) ); } @@ -109,7 +109,7 @@ private void validateTitleLength(final String title) { private void validateIntroductionLength(final String introduction) { if (introduction.length() < INTRODUCTION_MIN_LENGTH || introduction.length() > INTRODUCTION_MAX_LENGTH) { - throw new BadRequestException( + throw new RoadmapException( String.format("로드맵 소개글의 길이는 최소 %d글자, 최대 %d글자입니다.", INTRODUCTION_MIN_LENGTH, INTRODUCTION_MAX_LENGTH ) @@ -119,7 +119,7 @@ private void validateIntroductionLength(final String introduction) { private void validateRequiredPeriod(final int requiredPeriod) { if (requiredPeriod < REQUIRED_MIN_PERIOD || requiredPeriod > REQUIRED_MAX_PERIOD) { - throw new BadRequestException( + throw new RoadmapException( String.format("로드맵 추천 소요 기간은 최소 %d일, 최대 %d일입니다.", REQUIRED_MIN_PERIOD, REQUIRED_MAX_PERIOD) ); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java index b872e298e..521839855 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java @@ -1,7 +1,7 @@ package co.kirikiri.domain.roadmap; import co.kirikiri.domain.BaseEntity; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import lombok.AccessLevel; @@ -32,7 +32,7 @@ public RoadmapCategory(final Long id, final String name) { private void validateNameLength(final String name) { if (name.length() < MIN_NAME_LENGTH || name.length() > MAX_NAME_LENGTH) { - throw new BadRequestException("카테고리 이름은 1자 이상 10자 이하입니다."); + throw new RoadmapException("카테고리 이름은 1자 이상 10자 이하입니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java index 808b24af6..e4d918267 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java @@ -1,17 +1,17 @@ package co.kirikiri.domain.roadmap; import co.kirikiri.domain.BaseUpdatedTimeEntity; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.util.Optional; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.Optional; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -49,7 +49,7 @@ private void validate(final String content) { private void validateContentLength(final String content) { if (content.length() > CONTENT_MAX_LENGTH) { - throw new BadRequestException(String.format("로드맵 본문의 길이는 최대 %d글자입니다.", CONTENT_MAX_LENGTH)); + throw new RoadmapException(String.format("로드맵 본문의 길이는 최대 %d글자입니다.", CONTENT_MAX_LENGTH)); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java index 67f00b154..dcf5bfbdf 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java @@ -1,7 +1,7 @@ package co.kirikiri.domain.roadmap; import co.kirikiri.domain.BaseEntity; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; @@ -51,14 +51,14 @@ private void validate(final String title, final String content) { private void validateTitleLength(final String title) { if (title.length() < TITLE_MIN_LENGTH || title.length() > TITLE_MAX_LENGTH) { - throw new BadRequestException( + throw new RoadmapException( String.format("로드맵 노드의 제목의 길이는 최소 %d글자, 최대 %d글자입니다.", TITLE_MIN_LENGTH, TITLE_MAX_LENGTH)); } } private void validateContentLength(final String content) { if (content.length() < CONTENT_MIN_LENGTH || content.length() > CONTENT_MAX_LENGTH) { - throw new BadRequestException( + throw new RoadmapException( String.format("로드맵 노드의 설명의 길이는 최소 %d글자, 최대 %d글자입니다.", CONTENT_MIN_LENGTH, CONTENT_MAX_LENGTH)); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImages.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImages.java index 209f62dac..8d33922dc 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImages.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImages.java @@ -1,14 +1,14 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; -import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; +import lombok.NoArgsConstructor; @Embeddable @NoArgsConstructor @@ -27,7 +27,7 @@ public RoadmapNodeImages(final List images) { private void validateSize(final List images) { if (images.size() > MAX_SIZE) { - throw new BadRequestException("한 로드맵 노드에 사진은 최대 2개까지 가능합니다."); + throw new RoadmapException("한 로드맵 노드에 사진은 최대 2개까지 가능합니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodes.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodes.java index c87e9ace6..728d15b6f 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodes.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodes.java @@ -1,16 +1,16 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; import jakarta.persistence.OneToMany; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; @Embeddable @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -32,7 +32,7 @@ private void validateTitleDistinct(final List roadmapNodes) { .collect(Collectors.toSet()) .size(); if (roadmapNodes.size() != distinctNameCount) { - throw new BadRequestException("한 로드맵에 같은 이름의 노드가 존재할 수 없습니다."); + throw new RoadmapException("한 로드맵에 같은 이름의 노드가 존재할 수 없습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java index 318aaa792..1b36d1f92 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java @@ -2,15 +2,15 @@ import co.kirikiri.domain.BaseUpdatedTimeEntity; import co.kirikiri.domain.member.Member; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.util.regex.Pattern; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -53,13 +53,13 @@ private void validate(final String content, final Double rate) { private void validateContentLength(final String content) { if (content.length() > CONTENT_MAX_LENGTH) { - throw new BadRequestException(String.format("리뷰는 최대 %d글자까지 입력할 수 있습니다.", CONTENT_MAX_LENGTH)); + throw new RoadmapException(String.format("리뷰는 최대 %d글자까지 입력할 수 있습니다.", CONTENT_MAX_LENGTH)); } } private void validateRate(final Double rate) { if (!Pattern.matches(RATE_FORMAT, String.valueOf(rate))) { - throw new BadRequestException(String.format("별점은 %d부터 %d까지 0.%d 단위로 설정할 수 있습니다.", + throw new RoadmapException(String.format("별점은 %d부터 %d까지 0.%d 단위로 설정할 수 있습니다.", MIN_RATE, MAX_RATE, RATE_UNIT)); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTags.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTags.java index 4efaa3cc7..763c920cb 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTags.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTags.java @@ -1,7 +1,7 @@ package co.kirikiri.domain.roadmap; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; -import co.kirikiri.exception.BadRequestException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; @@ -40,7 +40,7 @@ private void validate(final List roadmapTags) { private void validateCount(final List roadmapTags) { if (roadmapTags.size() > MAX_COUNT) { - throw new BadRequestException( + throw new RoadmapException( String.format("태그의 개수는 최대 %d개까지 가능합니다.", MAX_COUNT)); } } @@ -50,7 +50,7 @@ private void validateDuplicatedName(final List roadmapTags) { .map(RoadmapTag::getName) .collect(Collectors.toSet()); if (roadmapTags.size() != nonDuplicatedNames.size()) { - throw new BadRequestException("태그 이름은 중복될 수 없습니다."); + throw new RoadmapException("태그 이름은 중복될 수 없습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/exception/RoadmapException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/exception/RoadmapException.java new file mode 100644 index 000000000..86610f60b --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/exception/RoadmapException.java @@ -0,0 +1,10 @@ +package co.kirikiri.domain.roadmap.exception; + +import co.kirikiri.domain.exception.DomainException; + +public class RoadmapException extends DomainException { + + public RoadmapException(final String message) { + super(message); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/vo/RoadmapTagName.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/vo/RoadmapTagName.java index 3a7e60796..711208319 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/vo/RoadmapTagName.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/vo/RoadmapTagName.java @@ -1,10 +1,10 @@ package co.kirikiri.domain.roadmap.vo; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; +import java.util.Objects; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.util.Objects; @NoArgsConstructor(access = AccessLevel.PROTECTED) public class RoadmapTagName { @@ -23,7 +23,7 @@ public RoadmapTagName(final String value) { private void validate(final String name) { if (name.length() < MIN_LENGTH || name.length() > MAX_LENGTH) { - throw new BadRequestException( + throw new RoadmapException( String.format("태그 이름은 최소 %d자부터 최대 %d자까지 가능합니다.", MIN_LENGTH, MAX_LENGTH)); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java b/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java index 2c26ee9bd..429359a26 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java @@ -1,19 +1,19 @@ package co.kirikiri.infra; -import co.kirikiri.exception.ServerException; import co.kirikiri.service.FileService; import co.kirikiri.service.dto.FileInformation; +import co.kirikiri.service.exception.ServerException; import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; import com.amazonaws.services.s3.model.ObjectMetadata; +import java.io.InputStream; +import java.net.URL; +import java.util.Date; import lombok.RequiredArgsConstructor; import org.springframework.core.env.Environment; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; -import java.io.InputStream; -import java.net.URL; -import java.util.Date; @Service @RequiredArgsConstructor diff --git a/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java b/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java index 990b50f7f..2c95c30ff 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java @@ -1,11 +1,11 @@ package co.kirikiri.infra; -import co.kirikiri.exception.ServerException; +import co.kirikiri.service.exception.ServerException; +import java.net.MalformedURLException; +import java.net.URL; import lombok.RequiredArgsConstructor; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; -import java.net.MalformedURLException; -import java.net.URL; @Service @RequiredArgsConstructor diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/QuerydslRepositorySupporter.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/QuerydslRepositorySupporter.java index 56671899d..685533ef7 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/QuerydslRepositorySupporter.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/QuerydslRepositorySupporter.java @@ -1,6 +1,6 @@ package co.kirikiri.persistence; -import co.kirikiri.exception.ServerException; +import co.kirikiri.service.exception.ServerException; import com.querydsl.core.types.EntityPath; import com.querydsl.core.types.Expression; import com.querydsl.core.types.dsl.PathBuilder; @@ -9,6 +9,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.annotation.PostConstruct; import jakarta.persistence.EntityManager; +import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cglib.core.internal.Function; import org.springframework.data.domain.Page; @@ -16,7 +17,6 @@ import org.springframework.data.jpa.repository.support.Querydsl; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.stereotype.Repository; -import java.util.List; @Repository public abstract class QuerydslRepositorySupporter { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenQueryRepository.java deleted file mode 100644 index 771f49681..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenQueryRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package co.kirikiri.persistence.auth; - -import co.kirikiri.domain.auth.EncryptedToken; -import co.kirikiri.domain.auth.RefreshToken; -import java.util.Optional; - -public interface RefreshTokenQueryRepository { - - Optional findByTokenAndIsRevokedFalse(final EncryptedToken token); -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenQueryRepositoryImpl.java deleted file mode 100644 index 31672da4b..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenQueryRepositoryImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package co.kirikiri.persistence.auth; - -import static co.kirikiri.domain.auth.QRefreshToken.refreshToken; -import static co.kirikiri.domain.member.QMember.member; - -import co.kirikiri.domain.auth.EncryptedToken; -import co.kirikiri.domain.auth.RefreshToken; -import co.kirikiri.persistence.QuerydslRepositorySupporter; -import java.util.Optional; - -public class RefreshTokenQueryRepositoryImpl extends QuerydslRepositorySupporter implements - RefreshTokenQueryRepository { - - public RefreshTokenQueryRepositoryImpl() { - super(RefreshToken.class); - } - - @Override - public Optional findByTokenAndIsRevokedFalse(final EncryptedToken token) { - - return Optional.ofNullable(selectFrom(refreshToken) - .join(refreshToken.member, member) - .fetchJoin() - .where(refreshToken.token.eq(token)) - .where(refreshToken.isRevoked.isFalse()) - .fetchOne()); - } -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenRepository.java index bf457b877..18e789945 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenRepository.java @@ -1,8 +1,10 @@ package co.kirikiri.persistence.auth; -import co.kirikiri.domain.auth.RefreshToken; -import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; -public interface RefreshTokenRepository extends JpaRepository, RefreshTokenQueryRepository { +public interface RefreshTokenRepository { + void save(final String refreshToken, final String memberIdentifier); + + Optional findMemberIdentifierByRefreshToken(final String refreshToken); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenRepositoryImpl.java new file mode 100644 index 000000000..7ca0a5de2 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/auth/RefreshTokenRepositoryImpl.java @@ -0,0 +1,37 @@ +package co.kirikiri.persistence.auth; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Repository; + +@Repository +public class RefreshTokenRepositoryImpl implements RefreshTokenRepository { + + private final RedisTemplate redisTemplate; + private final Long refreshTokenValidityInSeconds; + + public RefreshTokenRepositoryImpl(final RedisTemplate redisTemplate, + @Value("${jwt.refresh-token-validity-in-seconds}") final Long refreshTokenValidityInSeconds) { + this.redisTemplate = redisTemplate; + this.refreshTokenValidityInSeconds = refreshTokenValidityInSeconds; + } + + @Override + public void save(final String refreshToken, final String memberIdentifier) { + final long timeToLiveSeconds = refreshTokenValidityInSeconds / 1000; + + redisTemplate.opsForValue() + .set(refreshToken, memberIdentifier, timeToLiveSeconds, TimeUnit.SECONDS); + } + + @Override + public Optional findMemberIdentifierByRefreshToken(final String refreshToken) { + final String memberIdentifier = redisTemplate.opsForValue().get(refreshToken); + if (memberIdentifier == null) { + return Optional.empty(); + } + return Optional.of(memberIdentifier); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java index d059b45f5..c090385c1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java @@ -1,6 +1,6 @@ package co.kirikiri.persistence.dto; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.service.exception.BadRequestException; public record RoadmapSearchTagName( String value diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java index 35291df93..8469ce5d7 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java @@ -1,6 +1,6 @@ package co.kirikiri.persistence.dto; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.service.exception.BadRequestException; public record RoadmapSearchTitle( String value diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepository.java new file mode 100644 index 000000000..9a7b2e8b5 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepository.java @@ -0,0 +1,9 @@ +package co.kirikiri.persistence.goalroom; + +import co.kirikiri.domain.goalroom.GoalRoomMember; +import java.util.List; + +public interface GoalRoomMemberJdbcRepository { + + void saveAllInBatch(final List goalRoomMembers); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepositoryImpl.java new file mode 100644 index 000000000..28758b191 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepositoryImpl.java @@ -0,0 +1,30 @@ +package co.kirikiri.persistence.goalroom; + +import co.kirikiri.domain.goalroom.GoalRoomMember; +import java.util.List; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +@Repository +public class GoalRoomMemberJdbcRepositoryImpl implements GoalRoomMemberJdbcRepository { + + private final JdbcTemplate jdbcTemplate; + + public GoalRoomMemberJdbcRepositoryImpl(final JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public void saveAllInBatch(final List goalRoomMembers) { + final String sql = "INSERT INTO goal_room_member " + + "(goal_room_id, member_id, role, joined_at, accomplishment_rate) " + + "VALUES (?, ?, ?, ?, ?)"; + jdbcTemplate.batchUpdate(sql, goalRoomMembers, goalRoomMembers.size(), ((ps, goalRoomMember) -> { + ps.setLong(1, goalRoomMember.getGoalRoom().getId()); + ps.setLong(2, goalRoomMember.getMember().getId()); + ps.setString(3, goalRoomMember.getRole().name()); + ps.setObject(4, goalRoomMember.getJoinedAt()); + ps.setDouble(5, goalRoomMember.getAccomplishmentRate()); + })); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepository.java index 88246c784..aa1f912c8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepository.java @@ -3,13 +3,14 @@ import co.kirikiri.domain.goalroom.GoalRoom; import co.kirikiri.domain.goalroom.GoalRoomMember; import co.kirikiri.domain.member.vo.Identifier; +import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import java.util.List; -import java.util.Optional; -public interface GoalRoomMemberRepository extends JpaRepository, GoalRoomMemberQueryRepository { +public interface GoalRoomMemberRepository extends JpaRepository, + GoalRoomMemberQueryRepository, GoalRoomMemberJdbcRepository { @Query("select gm from GoalRoomMember gm " + "inner join fetch gm.goalRoom g " diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepository.java index 1c8913d9f..cdd2d45db 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepository.java @@ -3,11 +3,12 @@ import co.kirikiri.domain.goalroom.GoalRoom; import co.kirikiri.domain.goalroom.GoalRoomPendingMember; import co.kirikiri.domain.member.vo.Identifier; +import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import java.util.List; -import java.util.Optional; public interface GoalRoomPendingMemberRepository extends JpaRepository, GoalRoomPendingMemberQueryRepository { @@ -28,4 +29,8 @@ Optional findByGoalRoomAndMemberIdentifier( + "where g=:goalRoom " + "and gp.member = m") List findAllByGoalRoom(@Param("goalRoom") final GoalRoom goalRoom); + + @Modifying + @Query("DELETE FROM GoalRoomPendingMember gp WHERE gp.id IN :ids") + void deleteAllByIdIn(@Param("ids") final List ids); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepository.java index 61f1b4625..5a18b19d9 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepository.java @@ -11,6 +11,8 @@ public interface GoalRoomQueryRepository { + Optional findGoalRoomByIdWithPessimisticLock(Long goalRoomId); + Optional findByIdWithRoadmapContent(final Long goalRoomId); Optional findByIdWithContentAndTodos(final Long goalRoomId); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepositoryImpl.java index e11544dc8..dad601666 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepositoryImpl.java @@ -15,6 +15,7 @@ import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; +import jakarta.persistence.LockModeType; import java.time.LocalDate; import java.util.List; import java.util.Optional; @@ -27,6 +28,16 @@ public GoalRoomQueryRepositoryImpl() { super(GoalRoom.class); } + @Override + public Optional findGoalRoomByIdWithPessimisticLock(final Long goalRoomId) { + return Optional.ofNullable(selectFrom(goalRoom) + .innerJoin(goalRoom.goalRoomPendingMembers.values, goalRoomPendingMember) + .fetchJoin() + .where(goalRoom.id.eq(goalRoomId)) + .setLockMode(LockModeType.PESSIMISTIC_WRITE) + .fetchOne()); + } + @Override public Optional findByIdWithRoadmapContent(final Long goalRoomId) { return Optional.ofNullable(selectFrom(goalRoom) @@ -116,6 +127,8 @@ public List findByRoadmap(final Roadmap roadmap) { @Override public List findAllRecruitingGoalRoomsByStartDateEarlierThan(final LocalDate date) { return selectFrom(goalRoom) + .innerJoin(goalRoom.goalRoomPendingMembers.values, goalRoomPendingMember) + .fetchJoin() .where(statusCond(GoalRoomStatus.RECRUITING)) .where(equalOrEarlierStartDateThan(date)) .fetch(); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomRepository.java index 79b481ad0..7f517ae99 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomRepository.java @@ -1,14 +1,13 @@ package co.kirikiri.persistence.goalroom; import co.kirikiri.domain.goalroom.GoalRoom; -import org.springframework.data.jpa.repository.JpaRepository; import java.time.LocalDate; import java.util.List; import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; public interface GoalRoomRepository extends JpaRepository, GoalRoomQueryRepository { - - @Override + Optional findById(final Long goalRoomId); List findAllByEndDate(final LocalDate endDate); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/CacheKeyGenerator.java b/backend/kirikiri/src/main/java/co/kirikiri/service/CacheKeyGenerator.java new file mode 100644 index 000000000..2a11fcd5d --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/CacheKeyGenerator.java @@ -0,0 +1,27 @@ +package co.kirikiri.service; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.stream.Collectors; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.stereotype.Component; + +@Component +public class CacheKeyGenerator implements KeyGenerator { + + private static final String DELIMITER = "_"; + + @Override + public Object generate(final Object target, final Method method, final Object... params) { + return String.format("%s-%s-%s", + target.getClass().getSimpleName(), + method.getName(), + arrayToDelimitedString(params)); + } + + private Object arrayToDelimitedString(final Object... params) { + return Arrays.stream(params) + .map(o -> o == null ? "" : String.valueOf(o.hashCode())) + .collect(Collectors.joining(DELIMITER)); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java b/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java index 673804030..6d6450e2c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java @@ -1,10 +1,10 @@ package co.kirikiri.service; -import co.kirikiri.exception.BadRequestException; -import org.springframework.stereotype.Component; +import co.kirikiri.service.exception.BadRequestException; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.UUID; +import org.springframework.stereotype.Component; @Component public class UUIDFilePathGenerator implements FilePathGenerator { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvert.java b/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvert.java new file mode 100644 index 000000000..1a2b42941 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvert.java @@ -0,0 +1,12 @@ +package co.kirikiri.service.aop; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExceptionConvert { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvertAop.java b/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvertAop.java new file mode 100644 index 000000000..4a9fb96ad --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvertAop.java @@ -0,0 +1,24 @@ +package co.kirikiri.service.aop; + +import co.kirikiri.domain.exception.DomainException; +import co.kirikiri.domain.exception.UnexpectedDomainException; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ServerException; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class ExceptionConvertAop { + + @AfterThrowing(pointcut = "within(@co.kirikiri.service.aop.ExceptionConvert *)", throwing = "exception") + public void convertException(final Throwable exception) { + if (exception instanceof UnexpectedDomainException) { + throw new ServerException(exception.getMessage()); + } + if (exception instanceof DomainException) { + throw new BadRequestException(exception.getMessage()); + } + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java index 1ba9a1af7..f8cc195f0 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java @@ -1,26 +1,26 @@ package co.kirikiri.service.auth; -import co.kirikiri.domain.auth.EncryptedToken; -import co.kirikiri.domain.auth.RefreshToken; import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.exception.AuthenticationException; import co.kirikiri.persistence.auth.RefreshTokenRepository; import co.kirikiri.persistence.member.MemberRepository; +import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.auth.LoginDto; import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; +import co.kirikiri.service.exception.AuthenticationException; import co.kirikiri.service.mapper.AuthMapper; +import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.Map; @Service @Transactional(readOnly = true) @RequiredArgsConstructor +@ExceptionConvert public class AuthService { private final RefreshTokenRepository refreshTokenRepository; @@ -48,16 +48,13 @@ private void checkPassword(final Password password, final Member member) { private AuthenticationResponse makeAuthenticationResponse(final Member member) { final String refreshToken = tokenProvider.createRefreshToken(member.getIdentifier().getValue(), Map.of()); - saveRefreshToken(member, refreshToken); + saveRefreshToken(refreshToken, member); final String accessToken = tokenProvider.createAccessToken(member.getIdentifier().getValue(), Map.of()); return AuthMapper.convertToAuthenticationResponse(refreshToken, accessToken); } - private void saveRefreshToken(final Member member, final String rawRefreshToken) { - final EncryptedToken encryptedToken = new EncryptedToken(rawRefreshToken); - final LocalDateTime expiredAt = tokenProvider.findTokenExpiredAt(rawRefreshToken); - final RefreshToken refreshToken = new RefreshToken(encryptedToken, expiredAt, member); - refreshTokenRepository.save(refreshToken); + private void saveRefreshToken(final String refreshToken, final Member member) { + refreshTokenRepository.save(refreshToken, member.getIdentifier().getValue()); } public AuthenticationResponse oauthLogin(final Member member) { @@ -71,11 +68,8 @@ public boolean isCertified(final String token) { @Transactional public AuthenticationResponse reissueToken(final ReissueTokenRequest reissueTokenRequest) { checkTokenValid(reissueTokenRequest.refreshToken()); - final EncryptedToken clientRefreshToken = AuthMapper.convertToEncryptedToken(reissueTokenRequest); - final RefreshToken refreshToken = findSavedRefreshToken(clientRefreshToken); - checkTokenExpired(refreshToken); - refreshTokenRepository.delete(refreshToken); - final Member member = refreshToken.getMember(); + final String memberIdentifier = findMemberIdentifierByRefreshToken(reissueTokenRequest.refreshToken()); + final Member member = findMemberByRefreshToken(memberIdentifier); return makeAuthenticationResponse(member); } @@ -85,15 +79,14 @@ private void checkTokenValid(final String token) { } } - private RefreshToken findSavedRefreshToken(final EncryptedToken clientRefreshToken) { - return refreshTokenRepository.findByTokenAndIsRevokedFalse(clientRefreshToken) - .orElseThrow(() -> new AuthenticationException("토큰이 유효하지 않습니다.")); + private String findMemberIdentifierByRefreshToken(final String clientRefreshToken) { + return refreshTokenRepository.findMemberIdentifierByRefreshToken(clientRefreshToken) + .orElseThrow(() -> new AuthenticationException("토큰이 만료 되었습니다.")); } - private void checkTokenExpired(final RefreshToken refreshToken) { - if (refreshToken.isExpired()) { - throw new AuthenticationException("토큰이 만료 되었습니다."); - } + private Member findMemberByRefreshToken(final String memberIdentifier) { + return memberRepository.findByIdentifier(new Identifier(memberIdentifier)) + .orElseThrow(() -> new AuthenticationException("존재하지 않는 회원입니다.")); } public String findIdentifierByToken(final String token) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java index 298c0abc7..2b91cf904 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java @@ -1,15 +1,12 @@ package co.kirikiri.service.auth; -import co.kirikiri.exception.AuthenticationException; +import co.kirikiri.service.exception.AuthenticationException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jws; import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.ZoneId; @@ -17,6 +14,9 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; +import javax.crypto.SecretKey; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; @Component public class JwtTokenProvider implements TokenProvider { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/NaverOauthService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/NaverOauthService.java index 9a18c5c56..d0630697e 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/NaverOauthService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/NaverOauthService.java @@ -1,8 +1,8 @@ package co.kirikiri.service.auth; import co.kirikiri.domain.member.Member; -import co.kirikiri.service.OauthNetworkService; import co.kirikiri.persistence.member.MemberRepository; +import co.kirikiri.service.OauthNetworkService; import co.kirikiri.service.dto.auth.NaverMemberProfileDto; import co.kirikiri.service.dto.auth.NaverMemberProfileResponseDto; import co.kirikiri.service.dto.auth.NaverOauthTokenDto; @@ -12,15 +12,15 @@ import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.mapper.OauthMapper; import co.kirikiri.service.member.MemberService; +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.Map; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Map; -import java.util.Optional; @Service @Transactional(readOnly = true) @@ -58,7 +58,8 @@ private String getProperty(final String property) { @Transactional public AuthenticationResponse login(final Map queryParams) { - final NaverOauthTokenDto naverOauthTokenDto = oauthNetworkService.requestToken(NaverOauthTokenDto.class, queryParams).getBody(); + final NaverOauthTokenDto naverOauthTokenDto = oauthNetworkService.requestToken(NaverOauthTokenDto.class, + queryParams).getBody(); final NaverMemberProfileDto naverMemberProfileDto = getNaverMemberProfileDto(naverOauthTokenDto.accessToken()); final NaverMemberProfileResponseDto naverMemberProfileResponseDto = naverMemberProfileDto.response(); final Optional optionalMember = memberRepository.findByOauthId(naverMemberProfileResponseDto.id()); @@ -66,8 +67,10 @@ public AuthenticationResponse login(final Map queryParams) { final Member member = optionalMember.get(); return authService.oauthLogin(member); } - return memberService.oauthJoin(new OauthMemberJoinDto(naverMemberProfileResponseDto.id(), naverMemberProfileResponseDto.email(), - naverMemberProfileResponseDto.nickname(), GenderType.findByOauthType(naverMemberProfileResponseDto.gender()))); + return memberService.oauthJoin( + new OauthMemberJoinDto(naverMemberProfileResponseDto.id(), naverMemberProfileResponseDto.email(), + naverMemberProfileResponseDto.nickname(), + GenderType.findByOauthType(naverMemberProfileResponseDto.gender()))); } private NaverMemberProfileDto getNaverMemberProfileDto(final String accessToken) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java index f199f19f8..164ebc537 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java @@ -1,6 +1,6 @@ package co.kirikiri.service.dto.member.request; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.service.exception.BadRequestException; import java.util.Arrays; public enum GenderType { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/exception/AuthenticationException.java b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/AuthenticationException.java similarity index 80% rename from backend/kirikiri/src/main/java/co/kirikiri/exception/AuthenticationException.java rename to backend/kirikiri/src/main/java/co/kirikiri/service/exception/AuthenticationException.java index 303cb5908..6e08c9c38 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/exception/AuthenticationException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/AuthenticationException.java @@ -1,4 +1,4 @@ -package co.kirikiri.exception; +package co.kirikiri.service.exception; public class AuthenticationException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/exception/BadRequestException.java b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BadRequestException.java similarity index 79% rename from backend/kirikiri/src/main/java/co/kirikiri/exception/BadRequestException.java rename to backend/kirikiri/src/main/java/co/kirikiri/service/exception/BadRequestException.java index e88a97266..a6000ad1a 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/exception/BadRequestException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BadRequestException.java @@ -1,4 +1,4 @@ -package co.kirikiri.exception; +package co.kirikiri.service.exception; public class BadRequestException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/exception/BusinessException.java b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BusinessException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/exception/BusinessException.java rename to backend/kirikiri/src/main/java/co/kirikiri/service/exception/BusinessException.java index 32c3e413d..404a22614 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/exception/BusinessException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BusinessException.java @@ -1,4 +1,4 @@ -package co.kirikiri.exception; +package co.kirikiri.service.exception; public class BusinessException extends RuntimeException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/exception/ConflictException.java b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ConflictException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/exception/ConflictException.java rename to backend/kirikiri/src/main/java/co/kirikiri/service/exception/ConflictException.java index e40e602dc..dc0103c4a 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/exception/ConflictException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ConflictException.java @@ -1,4 +1,4 @@ -package co.kirikiri.exception; +package co.kirikiri.service.exception; public class ConflictException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/exception/ForbiddenException.java b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ForbiddenException.java similarity index 79% rename from backend/kirikiri/src/main/java/co/kirikiri/exception/ForbiddenException.java rename to backend/kirikiri/src/main/java/co/kirikiri/service/exception/ForbiddenException.java index 11c23e4ac..e945efb65 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/exception/ForbiddenException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ForbiddenException.java @@ -1,4 +1,4 @@ -package co.kirikiri.exception; +package co.kirikiri.service.exception; public class ForbiddenException extends RuntimeException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/exception/NotFoundException.java b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/NotFoundException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/exception/NotFoundException.java rename to backend/kirikiri/src/main/java/co/kirikiri/service/exception/NotFoundException.java index ae007e40e..135762e67 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/exception/NotFoundException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/NotFoundException.java @@ -1,4 +1,4 @@ -package co.kirikiri.exception; +package co.kirikiri.service.exception; public class NotFoundException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/exception/ServerException.java b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ServerException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/exception/ServerException.java rename to backend/kirikiri/src/main/java/co/kirikiri/service/exception/ServerException.java index aa1a6efad..105a85b63 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/exception/ServerException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ServerException.java @@ -1,4 +1,4 @@ -package co.kirikiri.exception; +package co.kirikiri.service.exception; public class ServerException extends RuntimeException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomCreateService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomCreateService.java index e52ef5691..7e34b03ea 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomCreateService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomCreateService.java @@ -15,8 +15,6 @@ import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapContent; import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.goalroom.CheckFeedRepository; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomRepository; @@ -26,6 +24,7 @@ import co.kirikiri.service.FilePathGenerator; import co.kirikiri.service.FileService; import co.kirikiri.service.ImageDirType; +import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.FileInformation; import co.kirikiri.service.dto.goalroom.GoalRoomCreateDto; import co.kirikiri.service.dto.goalroom.GoalRoomRoadmapNodeDto; @@ -33,6 +32,8 @@ import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.mapper.GoalRoomMapper; import java.time.LocalDate; import java.time.LocalDateTime; @@ -46,6 +47,7 @@ @Service @Transactional @RequiredArgsConstructor +@ExceptionConvert public class GoalRoomCreateService { private final FileService fileService; @@ -116,12 +118,12 @@ private Member findMemberByIdentifier(final String memberIdentifier) { public void join(final String identifier, final Long goalRoomId) { final Member member = findMemberByIdentifier(identifier); - final GoalRoom goalRoom = findGoalRoomById(goalRoomId); + final GoalRoom goalRoom = findGoalRoomByIdWithPessimisticLock(goalRoomId); goalRoom.join(member); } - private GoalRoom findGoalRoomById(final Long goalRoomId) { - return goalRoomRepository.findById(goalRoomId) + private GoalRoom findGoalRoomByIdWithPessimisticLock(final Long goalRoomId) { + return goalRoomRepository.findGoalRoomByIdWithPessimisticLock(goalRoomId) .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); } @@ -137,6 +139,11 @@ public Long addGoalRoomTodo(final Long goalRoomId, final String identifier, return goalRoom.findLastGoalRoomTodo().getId(); } + private GoalRoom findGoalRoomById(final Long goalRoomId) { + return goalRoomRepository.findById(goalRoomId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); + } + private void checkGoalRoomCompleted(final GoalRoom goalRoom) { if (goalRoom.isCompleted()) { throw new BadRequestException("이미 종료된 골룸입니다."); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomReadService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomReadService.java index 4680909a1..09480bbef 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomReadService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomReadService.java @@ -12,8 +12,6 @@ import co.kirikiri.domain.member.Member; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.exception.ForbiddenException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.goalroom.CheckFeedRepository; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; @@ -22,6 +20,7 @@ import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.service.FileService; +import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.goalroom.CheckFeedDto; import co.kirikiri.service.dto.goalroom.GoalRoomCheckFeedDto; import co.kirikiri.service.dto.goalroom.GoalRoomMemberDto; @@ -38,6 +37,8 @@ import co.kirikiri.service.dto.member.MemberDto; import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; +import co.kirikiri.service.exception.ForbiddenException; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.mapper.GoalRoomMapper; import java.net.URL; import java.time.LocalDate; @@ -53,6 +54,7 @@ @Service @Transactional(readOnly = true) @RequiredArgsConstructor +@ExceptionConvert public class GoalRoomReadService { private final MemberRepository memberRepository; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/AuthMapper.java b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/AuthMapper.java index ec3df85d4..4809ca258 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/AuthMapper.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/AuthMapper.java @@ -1,11 +1,9 @@ package co.kirikiri.service.mapper; -import co.kirikiri.domain.auth.EncryptedToken; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Password; import co.kirikiri.service.dto.auth.LoginDto; import co.kirikiri.service.dto.auth.request.LoginRequest; -import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -21,8 +19,4 @@ public static AuthenticationResponse convertToAuthenticationResponse(final Strin final String accessToken) { return new AuthenticationResponse(refreshToken, accessToken); } - - public static EncryptedToken convertToEncryptedToken(final ReissueTokenRequest reissueTokenRequest) { - return new EncryptedToken(reissueTokenRequest.refreshToken()); - } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/GoalRoomMapper.java b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/GoalRoomMapper.java index a1ef9ce41..a7a7fdef6 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/GoalRoomMapper.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/GoalRoomMapper.java @@ -1,20 +1,43 @@ package co.kirikiri.service.mapper; -import co.kirikiri.domain.goalroom.*; +import co.kirikiri.domain.goalroom.GoalRoom; +import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; +import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; +import co.kirikiri.domain.goalroom.GoalRoomStatus; +import co.kirikiri.domain.goalroom.GoalRoomToDo; +import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; +import co.kirikiri.domain.goalroom.GoalRoomToDos; import co.kirikiri.domain.goalroom.vo.GoalRoomName; import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.exception.ServerException; import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; import co.kirikiri.service.dto.FileInformation; -import co.kirikiri.service.dto.goalroom.*; +import co.kirikiri.service.dto.goalroom.CheckFeedDto; +import co.kirikiri.service.dto.goalroom.GoalRoomCheckFeedDto; +import co.kirikiri.service.dto.goalroom.GoalRoomCreateDto; +import co.kirikiri.service.dto.goalroom.GoalRoomMemberDto; +import co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto; +import co.kirikiri.service.dto.goalroom.GoalRoomRoadmapNodeDetailDto; +import co.kirikiri.service.dto.goalroom.GoalRoomRoadmapNodeDto; +import co.kirikiri.service.dto.goalroom.MemberGoalRoomForListDto; +import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomDto; +import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomScrollDto; import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomStatusTypeRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.*; +import co.kirikiri.service.dto.goalroom.response.CheckFeedResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomCertifiedResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomCheckFeedResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeDetailResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodesResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; +import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; import co.kirikiri.service.dto.member.MemberDto; import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; @@ -23,16 +46,16 @@ import co.kirikiri.service.dto.roadmap.RoadmapGoalRoomsOrderTypeDto; import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; - +import co.kirikiri.service.exception.ServerException; import java.io.IOException; import java.time.LocalDate; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class GoalRoomMapper { @@ -129,7 +152,8 @@ public static RoadmapGoalRoomResponses convertToRoadmapGoalRoomResponses( private static RoadmapGoalRoomResponse convertToRoadmapGoalRoomResponse( final RoadmapGoalRoomDto roadmapGoalRoomDto) { return new RoadmapGoalRoomResponse(roadmapGoalRoomDto.goalRoomId(), roadmapGoalRoomDto.name(), - roadmapGoalRoomDto.status(), roadmapGoalRoomDto.currentMemberCount(), roadmapGoalRoomDto.limitedMemberCount(), + roadmapGoalRoomDto.status(), roadmapGoalRoomDto.currentMemberCount(), + roadmapGoalRoomDto.limitedMemberCount(), roadmapGoalRoomDto.createdAt(), roadmapGoalRoomDto.startDate(), roadmapGoalRoomDto.endDate(), convertToMemberResponse(roadmapGoalRoomDto.goalRoomLeader())); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java index c2c6409b5..a5efc4376 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java @@ -3,7 +3,6 @@ import co.kirikiri.domain.member.Member; import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapCategory; -import co.kirikiri.exception.ServerException; import co.kirikiri.persistence.dto.RoadmapOrderType; import co.kirikiri.service.dto.FileInformation; import co.kirikiri.service.dto.member.MemberDto; @@ -37,12 +36,13 @@ import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapTagResponse; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; +import co.kirikiri.service.exception.ServerException; import java.io.IOException; import java.util.Collections; import java.util.List; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class RoadmapMapper { @@ -78,7 +78,8 @@ private static RoadmapNodeSaveDto convertToRoadmapNodesSaveDto(final RoadmapNode private static FileInformation converToRoadmapNodeImageDto(final MultipartFile it) { try { - return new FileInformation(it.getOriginalFilename(), it.getSize(), it.getContentType(), it.getInputStream()); + return new FileInformation(it.getOriginalFilename(), it.getSize(), it.getContentType(), + it.getInputStream()); } catch (final IOException exception) { throw new ServerException(exception.getMessage()); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java index 2a6aebd1f..2fec1552c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java @@ -1,8 +1,6 @@ package co.kirikiri.service.member; import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.auth.EncryptedToken; -import co.kirikiri.domain.auth.RefreshToken; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -10,12 +8,11 @@ import co.kirikiri.domain.member.MemberProfile; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; -import co.kirikiri.exception.ConflictException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.auth.RefreshTokenRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.service.FileService; import co.kirikiri.service.NumberGenerator; +import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.auth.TokenProvider; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; import co.kirikiri.service.dto.member.MemberInformationDto; @@ -25,21 +22,23 @@ import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.member.response.MemberInformationForPublicResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; +import co.kirikiri.service.exception.ConflictException; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.mapper.AuthMapper; import co.kirikiri.service.mapper.MemberMapper; +import java.net.URL; +import java.util.Map; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.core.env.Environment; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.net.URL; -import java.time.LocalDateTime; -import java.util.Map; -import java.util.UUID; @Service @Transactional(readOnly = true) @RequiredArgsConstructor +@ExceptionConvert public class MemberService { private static final String DEFAULT_ORIGINAL_FILE_NAME_PROPERTY = "image.default.originalFileName"; @@ -48,11 +47,11 @@ public class MemberService { private static final String DEFAULT_EXTENSION = "image.default.extension"; private static final int MAX_IDENTIFIER_LENGTH = 40; - private final MemberRepository memberRepository; private final Environment environment; private final NumberGenerator numberGenerator; private final FileService fileService; private final TokenProvider tokenProvider; + private final MemberRepository memberRepository; private final RefreshTokenRepository refreshTokenRepository; @Transactional @@ -75,10 +74,12 @@ private void checkIdentifierDuplicate(final Identifier identifier) { @Transactional public AuthenticationResponse oauthJoin(final OauthMemberJoinDto oauthMemberJoinDto) { - final MemberProfile memberProfile = new MemberProfile(Gender.valueOf(oauthMemberJoinDto.gender().name()), oauthMemberJoinDto.email()); + final MemberProfile memberProfile = new MemberProfile(Gender.valueOf(oauthMemberJoinDto.gender().name()), + oauthMemberJoinDto.email()); final Identifier identifier = makeIdentifier(oauthMemberJoinDto); final Nickname nickname = new Nickname(oauthMemberJoinDto.nickname()); - final Member member = new Member(identifier, oauthMemberJoinDto.oauthId(), nickname, findDefaultMemberImage(), memberProfile); + final Member member = new Member(identifier, oauthMemberJoinDto.oauthId(), nickname, findDefaultMemberImage(), + memberProfile); memberRepository.save(member); return makeAuthenticationResponse(member); } @@ -96,16 +97,13 @@ private Identifier makeIdentifier(final OauthMemberJoinDto oauthMemberJoinDto) { private AuthenticationResponse makeAuthenticationResponse(final Member member) { final String refreshToken = tokenProvider.createRefreshToken(member.getIdentifier().getValue(), Map.of()); - saveRefreshToken(member, refreshToken); + saveRefreshToken(refreshToken, member); final String accessToken = tokenProvider.createAccessToken(member.getIdentifier().getValue(), Map.of()); return AuthMapper.convertToAuthenticationResponse(refreshToken, accessToken); } - private void saveRefreshToken(final Member member, final String rawRefreshToken) { - final EncryptedToken encryptedToken = new EncryptedToken(rawRefreshToken); - final LocalDateTime expiredAt = tokenProvider.findTokenExpiredAt(rawRefreshToken); - final RefreshToken refreshToken = new RefreshToken(encryptedToken, expiredAt, member); - refreshTokenRepository.save(refreshToken); + private void saveRefreshToken(final String refreshToken, final Member member) { + refreshTokenRepository.save(refreshToken, member.getIdentifier().getValue()); } private MemberImage findDefaultMemberImage() { @@ -130,7 +128,8 @@ public MemberInformationDto makeMemberInformationDto(final Member member) { final MemberProfile memberProfile = member.getMemberProfile(); final URL imageUrl = fileService.generateUrl(memberImage.getServerFilePath(), HttpMethod.GET); return new MemberInformationDto(member.getId(), member.getNickname().getValue(), - imageUrl.toExternalForm(), memberProfile.getGender().name(), member.getIdentifier().getValue(), memberProfile.getEmail()); + imageUrl.toExternalForm(), memberProfile.getGender().name(), member.getIdentifier().getValue(), + memberProfile.getEmail()); } private Member findMemberInformationByIdentifier(final String identifier) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java index bd31b7120..833c59de6 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java @@ -6,24 +6,26 @@ import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ServerException; import co.kirikiri.persistence.roadmap.RoadmapContentRepository; import co.kirikiri.service.FilePathGenerator; import co.kirikiri.service.FileService; import co.kirikiri.service.ImageDirType; +import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.FileInformation; import co.kirikiri.service.dto.roadmap.RoadmapNodeSaveDto; import co.kirikiri.service.event.RoadmapCreateEvent; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ServerException; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; -import java.util.List; @Service @RequiredArgsConstructor +@ExceptionConvert public class RoadmapCreateEventListener { private final RoadmapContentRepository roadmapContentRepository; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java index 7ae17b927..77bce647b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java @@ -15,17 +15,13 @@ import co.kirikiri.domain.roadmap.RoadmapTag; import co.kirikiri.domain.roadmap.RoadmapTags; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; -import co.kirikiri.exception.AuthenticationException; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ConflictException; -import co.kirikiri.exception.ForbiddenException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; import co.kirikiri.persistence.roadmap.RoadmapReviewRepository; +import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.roadmap.RoadmapNodeSaveDto; import co.kirikiri.service.dto.roadmap.RoadmapReviewDto; import co.kirikiri.service.dto.roadmap.RoadmapSaveDto; @@ -34,16 +30,23 @@ import co.kirikiri.service.dto.roadmap.request.RoadmapReviewSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; import co.kirikiri.service.event.RoadmapCreateEvent; +import co.kirikiri.service.exception.AuthenticationException; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ConflictException; +import co.kirikiri.service.exception.ForbiddenException; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.mapper.RoadmapMapper; +import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; @Service @Transactional @RequiredArgsConstructor +@ExceptionConvert public class RoadmapCreateService { private final MemberRepository memberRepository; @@ -54,6 +57,7 @@ public class RoadmapCreateService { private final RoadmapCategoryRepository roadmapCategoryRepository; private final ApplicationEventPublisher applicationEventPublisher; + @CacheEvict(value = "roadmapList", allEntries = true) public Long create(final RoadmapSaveRequest request, final String identifier) { final Member member = findMemberByIdentifier(identifier); final RoadmapCategory roadmapCategory = findRoadmapCategoryById(request.categoryId()); @@ -154,6 +158,7 @@ private void validateReviewCount(final Roadmap roadmap, final Member member) { } } + @CacheEvict(value = {"roadmapList", "roadmap"}, allEntries = true) public void deleteRoadmap(final String identifier, final Long roadmapId) { final Roadmap roadmap = findRoadmapById(roadmapId); validateRoadmapCreator(roadmapId, identifier); @@ -170,6 +175,7 @@ private void validateRoadmapCreator(final Long roadmapId, final String identifie .orElseThrow(() -> new ForbiddenException("해당 로드맵을 생성한 사용자가 아닙니다.")); } + @CacheEvict(value = "categoryList", allEntries = true) public void createRoadmapCategory(final RoadmapCategorySaveRequest roadmapCategorySaveRequest) { final RoadmapCategory roadmapCategory = RoadmapMapper.convertToRoadmapCategory(roadmapCategorySaveRequest); roadmapCategoryRepository.findByName(roadmapCategory.getName()) diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java index ae1391c68..7afa4fce1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java @@ -10,7 +10,6 @@ import co.kirikiri.domain.roadmap.RoadmapNodes; import co.kirikiri.domain.roadmap.RoadmapReview; import co.kirikiri.domain.roadmap.RoadmapTags; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.dto.RoadmapOrderType; import co.kirikiri.persistence.dto.RoadmapSearchDto; import co.kirikiri.persistence.goalroom.GoalRoomRepository; @@ -21,6 +20,7 @@ import co.kirikiri.persistence.roadmap.RoadmapRepository; import co.kirikiri.persistence.roadmap.RoadmapReviewRepository; import co.kirikiri.service.FileService; +import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.CustomScrollRequest; import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomDto; import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomScrollDto; @@ -43,19 +43,22 @@ import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.mapper.GoalRoomMapper; import co.kirikiri.service.mapper.RoadmapMapper; import co.kirikiri.service.mapper.ScrollResponseMapper; +import java.net.URL; +import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.net.URL; -import java.util.List; @Service @Transactional(readOnly = true) @RequiredArgsConstructor +@ExceptionConvert public class RoadmapReadService { private final RoadmapRepository roadmapRepository; @@ -66,6 +69,7 @@ public class RoadmapReadService { private final MemberRepository memberRepository; private final FileService fileService; + @Cacheable(value = "roadmap", keyGenerator = "cacheKeyGenerator", cacheManager = "redisCacheManager") public RoadmapResponse findRoadmap(final Long id) { final Roadmap roadmap = findRoadmapById(id); final RoadmapContent recentRoadmapContent = findRecentContent(roadmap); @@ -126,6 +130,7 @@ private RoadmapContent findRecentContent(final Roadmap roadmap) { .orElseThrow(() -> new NotFoundException("로드맵에 컨텐츠가 존재하지 않습니다.")); } + @Cacheable(value = "roadmapList", keyGenerator = "cacheKeyGenerator", cacheManager = "redisCacheManager") public RoadmapForListResponses findRoadmapsByOrderType(final Long categoryId, final RoadmapOrderTypeRequest orderTypeRequest, final CustomScrollRequest scrollRequest) { @@ -146,7 +151,7 @@ private RoadmapCategory findCategoryById(final Long categoryId) { .orElseThrow(() -> new NotFoundException("존재하지 않는 카테고리입니다. categoryId = " + categoryId)); } - public RoadmapForListScrollDto makeRoadmapForListScrollDto(final List roadmaps, final int requestSize) { + private RoadmapForListScrollDto makeRoadmapForListScrollDto(final List roadmaps, final int requestSize) { final List roadmapForListDtos = roadmaps.stream() .map(this::makeRoadmapForListDto) .toList(); @@ -198,6 +203,7 @@ public RoadmapForListResponses search(final RoadmapOrderTypeRequest orderTypeReq return RoadmapMapper.convertRoadmapResponses(roadmapForListScrollDto); } + @Cacheable(value = "categoryList", keyGenerator = "cacheKeyGenerator", cacheManager = "redisCacheManager") public List findAllRoadmapCategories() { final List roadmapCategories = roadmapCategoryRepository.findAll(); return RoadmapMapper.convertRoadmapCategoryResponses(roadmapCategories); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/GoalRoomScheduler.java b/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/GoalRoomScheduler.java index 3a2114b48..71792ac6b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/GoalRoomScheduler.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/GoalRoomScheduler.java @@ -1,9 +1,13 @@ package co.kirikiri.service.scheduler; +import co.kirikiri.domain.BaseEntity; import co.kirikiri.domain.goalroom.GoalRoom; import co.kirikiri.domain.goalroom.GoalRoomMember; import co.kirikiri.domain.goalroom.GoalRoomPendingMember; +import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; +import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomRepository; +import co.kirikiri.service.aop.ExceptionConvert; import java.time.LocalDate; import java.util.List; import lombok.RequiredArgsConstructor; @@ -14,9 +18,12 @@ @Component @Transactional @RequiredArgsConstructor +@ExceptionConvert public class GoalRoomScheduler { private final GoalRoomRepository goalRoomRepository; + private final GoalRoomPendingMemberRepository goalRoomPendingMemberRepository; + private final GoalRoomMemberRepository goalRoomMemberRepository; @Scheduled(cron = "0 0 0 * * *") public void startGoalRooms() { @@ -24,16 +31,16 @@ public void startGoalRooms() { LocalDate.now()); for (final GoalRoom goalRoom : goalRoomsToStart) { final List goalRoomPendingMembers = goalRoom.getGoalRoomPendingMembers().getValues(); - saveGoalRoomMemberFromPendingMembers(goalRoomPendingMembers, goalRoom); + saveGoalRoomMemberFromPendingMembers(goalRoomPendingMembers); goalRoom.start(); } } - private void saveGoalRoomMemberFromPendingMembers(final List goalRoomPendingMembers, - final GoalRoom goalRoom) { + private void saveGoalRoomMemberFromPendingMembers(final List goalRoomPendingMembers) { final List goalRoomMembers = makeGoalRoomMembers(goalRoomPendingMembers); - goalRoom.addAllGoalRoomMembers(goalRoomMembers); - goalRoom.deleteAllPendingMembers(); + goalRoomMemberRepository.saveAllInBatch(goalRoomMembers); + final List ids = makeGoalRoomPendingMemberIds(goalRoomPendingMembers); + goalRoomPendingMemberRepository.deleteAllByIdIn(ids); } private List makeGoalRoomMembers(final List goalRoomPendingMembers) { @@ -43,9 +50,14 @@ private List makeGoalRoomMembers(final List makeGoalRoomPendingMemberIds(final List goalRoomPendingMembers) { + return goalRoomPendingMembers.stream() + .map(BaseEntity::getId) + .toList(); } @Scheduled(cron = "0 0 4 * * *") diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java b/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java index 12af9979b..92af456a9 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java @@ -5,15 +5,17 @@ import co.kirikiri.domain.roadmap.RoadmapStatus; import co.kirikiri.persistence.goalroom.GoalRoomRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; +import co.kirikiri.service.aop.ExceptionConvert; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -import java.util.List; @Component @Transactional @RequiredArgsConstructor +@ExceptionConvert public class RoadmapScheduler { private static final int DELETE_AFTER_MONTH = 3; diff --git a/backend/kirikiri/src/main/resources/db/migration/V4__drop_refresh_token_table.sql b/backend/kirikiri/src/main/resources/db/migration/V4__drop_refresh_token_table.sql new file mode 100644 index 000000000..994308065 --- /dev/null +++ b/backend/kirikiri/src/main/resources/db/migration/V4__drop_refresh_token_table.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS refresh_token; diff --git a/backend/kirikiri/src/main/resources/properties b/backend/kirikiri/src/main/resources/properties deleted file mode 160000 index 3421e8b52..000000000 --- a/backend/kirikiri/src/main/resources/properties +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3421e8b5292c632c7d6ae4189e9e291a7d41022c diff --git a/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java b/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java index 149355e1d..606505846 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java @@ -6,8 +6,8 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; -import co.kirikiri.exception.AuthenticationException; import co.kirikiri.service.auth.AuthService; +import co.kirikiri.service.exception.AuthenticationException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java index db536f21e..c9843407f 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java @@ -5,8 +5,11 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; -import co.kirikiri.exception.AuthenticationException; +import co.kirikiri.common.interceptor.Authenticated; import co.kirikiri.service.auth.AuthService; +import co.kirikiri.service.exception.AuthenticationException; +import co.kirikiri.service.exception.ServerException; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -18,7 +21,6 @@ import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.ModelAndViewContainer; -import java.util.List; @ExtendWith(MockitoExtension.class) class MemberIdentifierArgumentResolverTest { @@ -50,6 +52,8 @@ class MemberIdentifierArgumentResolverTest { .thenReturn(String.class); when(parameter.hasParameterAnnotation(MemberIdentifier.class)) .thenReturn(true); + when(parameter.hasMethodAnnotation(Authenticated.class)) + .thenReturn(true); //when final boolean result = memberIdentifierArgumentResolver.supportsParameter(parameter); @@ -63,6 +67,8 @@ class MemberIdentifierArgumentResolverTest { //given Mockito.>when(parameter.getParameterType()) .thenReturn(List.class); + when(parameter.hasMethodAnnotation(Authenticated.class)) + .thenReturn(true); //when final boolean result = memberIdentifierArgumentResolver.supportsParameter(parameter); @@ -78,6 +84,8 @@ class MemberIdentifierArgumentResolverTest { .thenReturn(String.class); when(parameter.hasParameterAnnotation(MemberIdentifier.class)) .thenReturn(false); + when(parameter.hasMethodAnnotation(Authenticated.class)) + .thenReturn(true); //when final boolean result = memberIdentifierArgumentResolver.supportsParameter(parameter); @@ -86,6 +94,19 @@ class MemberIdentifierArgumentResolverTest { assertThat(result).isFalse(); } + @Test + void String_타입이고_Authenticated가_붙지_않은_인자인_경우_예외가_발생한다() { + //given + when(parameter.hasMethodAnnotation(Authenticated.class)) + .thenReturn(false); + + //when + //then + assertThatThrownBy(() -> memberIdentifierArgumentResolver.supportsParameter(parameter)) + .isInstanceOf(ServerException.class) + .hasMessageContaining("MemberIdentifier는 인증된 사용자만 사용 가능합니다. (@Authenticated)"); + } + @Test void 정상적으로_토큰이_들어온_경우_토큰을_인증한다() { // given diff --git a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java index 494da040d..80973fc0f 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java @@ -4,11 +4,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; -import co.kirikiri.exception.BadRequestException; import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; +import co.kirikiri.service.exception.BadRequestException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import javax.xml.validation.Validator; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -21,7 +22,6 @@ import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.ModelAndViewContainer; -import javax.xml.validation.Validator; @ExtendWith(MockitoExtension.class) class RoadmapSaveArgumentResolverTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java index 0fc3ba309..8b1741f4c 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java @@ -14,7 +14,6 @@ import co.kirikiri.controller.helper.ControllerTestHelper; import co.kirikiri.controller.helper.FieldDescriptionHelper.FieldDescription; -import co.kirikiri.exception.AuthenticationException; import co.kirikiri.service.auth.AuthService; import co.kirikiri.service.auth.NaverOauthService; import co.kirikiri.service.dto.ErrorResponse; @@ -22,7 +21,9 @@ import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; +import co.kirikiri.service.exception.AuthenticationException; import com.fasterxml.jackson.core.type.TypeReference; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -30,7 +31,6 @@ import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; -import java.util.List; @WebMvcTest(AuthController.class) class AuthCreateApiTest extends ControllerTestHelper { @@ -268,7 +268,8 @@ class AuthCreateApiTest extends ControllerTestHelper { @Test void 네이버_로그인_페이지를_정상적으로_반환한다() throws Exception { // given - final OauthRedirectResponse expectedResponse = new OauthRedirectResponse("Naver_Login_Redirect_Page_URL", "state"); + final OauthRedirectResponse expectedResponse = new OauthRedirectResponse("Naver_Login_Redirect_Page_URL", + "state"); given(naverOauthService.makeOauthUrl()).willReturn(expectedResponse); 네이버_로그인_페이지(status().isOk()); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomCreateApiTest.java index 2df851342..01b22f4ee 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomCreateApiTest.java @@ -26,16 +26,19 @@ import co.kirikiri.controller.helper.ControllerTestHelper; import co.kirikiri.controller.helper.FieldDescriptionHelper.FieldDescription; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.NotFoundException; -import co.kirikiri.service.goalroom.GoalRoomCreateService; -import co.kirikiri.service.goalroom.GoalRoomReadService; import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.NotFoundException; +import co.kirikiri.service.goalroom.GoalRoomCreateService; +import co.kirikiri.service.goalroom.GoalRoomReadService; import com.fasterxml.jackson.core.type.TypeReference; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -46,9 +49,6 @@ import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; @WebMvcTest(GoalRoomController.class) class GoalRoomCreateApiTest extends ControllerTestHelper { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomReadApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomReadApiTest.java index 5334608cf..1ad346fbb 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomReadApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomReadApiTest.java @@ -20,11 +20,6 @@ import co.kirikiri.controller.helper.ControllerTestHelper; import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ForbiddenException; -import co.kirikiri.exception.NotFoundException; -import co.kirikiri.service.goalroom.GoalRoomCreateService; -import co.kirikiri.service.goalroom.GoalRoomReadService; import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.goalroom.request.GoalRoomStatusTypeRequest; import co.kirikiri.service.dto.goalroom.response.CheckFeedResponse; @@ -40,6 +35,11 @@ import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; import co.kirikiri.service.dto.member.response.MemberResponse; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ForbiddenException; +import co.kirikiri.service.exception.NotFoundException; +import co.kirikiri.service.goalroom.GoalRoomCreateService; +import co.kirikiri.service.goalroom.GoalRoomReadService; import com.fasterxml.jackson.core.type.TypeReference; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java index 0c00bab6d..0764ac644 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java @@ -13,13 +13,14 @@ import co.kirikiri.controller.helper.ControllerTestHelper; import co.kirikiri.controller.helper.FieldDescriptionHelper.FieldDescription; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ConflictException; -import co.kirikiri.service.member.MemberService; import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ConflictException; +import co.kirikiri.service.member.MemberService; import com.fasterxml.jackson.core.type.TypeReference; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -28,7 +29,6 @@ import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; -import java.util.List; @WebMvcTest(MemberController.class) class MemberCreateApiTest extends ControllerTestHelper { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java index f49ecce26..cfb492596 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java @@ -14,11 +14,11 @@ import co.kirikiri.controller.helper.ControllerTestHelper; import co.kirikiri.domain.member.Gender; -import co.kirikiri.exception.NotFoundException; -import co.kirikiri.service.member.MemberService; import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.member.response.MemberInformationForPublicResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; +import co.kirikiri.service.exception.NotFoundException; +import co.kirikiri.service.member.MemberService; import com.fasterxml.jackson.core.type.TypeReference; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java index 7c4140673..04f4a8d19 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java @@ -25,13 +25,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import co.kirikiri.controller.helper.ControllerTestHelper; -import co.kirikiri.exception.AuthenticationException; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ConflictException; -import co.kirikiri.exception.ForbiddenException; -import co.kirikiri.exception.NotFoundException; -import co.kirikiri.service.roadmap.RoadmapCreateService; -import co.kirikiri.service.roadmap.RoadmapReadService; import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.roadmap.request.RoadmapCategorySaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapDifficultyType; @@ -39,7 +32,16 @@ import co.kirikiri.service.dto.roadmap.request.RoadmapReviewSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapTagSaveRequest; +import co.kirikiri.service.exception.AuthenticationException; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ConflictException; +import co.kirikiri.service.exception.ForbiddenException; +import co.kirikiri.service.exception.NotFoundException; +import co.kirikiri.service.roadmap.RoadmapCreateService; +import co.kirikiri.service.roadmap.RoadmapReadService; import com.fasterxml.jackson.core.type.TypeReference; +import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -53,8 +55,6 @@ import org.springframework.restdocs.snippet.Attributes.Attribute; import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; -import java.util.ArrayList; -import java.util.List; @WebMvcTest(RoadmapController.class) class RoadmapCreateApiTest extends ControllerTestHelper { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java index 02aa97c55..ceda742a1 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java @@ -1,17 +1,48 @@ package co.kirikiri.controller; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import co.kirikiri.controller.helper.ControllerTestHelper; import co.kirikiri.domain.goalroom.GoalRoomStatus; import co.kirikiri.domain.roadmap.RoadmapDifficulty; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.service.dto.CustomScrollRequest; import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.member.response.MemberResponse; import co.kirikiri.service.dto.roadmap.request.RoadmapOrderTypeRequest; -import co.kirikiri.service.dto.roadmap.response.*; +import co.kirikiri.service.dto.roadmap.response.MemberRoadmapResponse; +import co.kirikiri.service.dto.roadmap.response.MemberRoadmapResponses; +import co.kirikiri.service.dto.roadmap.response.RoadmapCategoryResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapContentResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponses; +import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; +import co.kirikiri.service.dto.roadmap.response.RoadmapNodeResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapTagResponse; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.roadmap.RoadmapCreateService; import co.kirikiri.service.roadmap.RoadmapReadService; import com.fasterxml.jackson.core.type.TypeReference; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -20,25 +51,6 @@ import org.springframework.restdocs.snippet.Attributes; import org.springframework.test.web.servlet.MvcResult; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.when; -import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; -import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; -import static org.springframework.restdocs.request.RequestDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @WebMvcTest(RoadmapController.class) class RoadmapReadApiTest extends ControllerTestHelper { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/auth/vo/EncryptedTokenTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/auth/vo/EncryptedTokenTest.java deleted file mode 100644 index aaef1b68e..000000000 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/auth/vo/EncryptedTokenTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package co.kirikiri.domain.auth.vo; - -import static org.assertj.core.api.Assertions.assertThat; - -import co.kirikiri.domain.auth.EncryptedToken; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class EncryptedTokenTest { - - @ParameterizedTest - @ValueSource(strings = {"a", "abc", "", "token", "abcdefghijklmnopqrstuvwxyz"}) - void 정상적으로_토큰을_암호화한다(final String value) { - //given - //when - final EncryptedToken encryptedToken = new EncryptedToken(value); - - //then - assertThat(encryptedToken.getValue()).isNotEqualTo(value); - } -} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembersTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembersTest.java index 918e01d8b..bcb18de45 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembersTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembersTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import co.kirikiri.domain.exception.UnexpectedDomainException; import co.kirikiri.domain.goalroom.vo.GoalRoomName; import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; import co.kirikiri.domain.member.EncryptedPassword; @@ -11,10 +12,9 @@ import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; import co.kirikiri.domain.roadmap.RoadmapContent; -import co.kirikiri.exception.NotFoundException; -import org.junit.jupiter.api.Test; import java.time.LocalDateTime; import java.util.List; +import org.junit.jupiter.api.Test; class GoalRoomPendingMembersTest { @@ -55,18 +55,16 @@ null, new EncryptedPassword(new Password("password2!")), // then assertThatThrownBy(() -> assertThat(goalRoomPendingMembers.findGoalRoomLeader())) - .isInstanceOf(NotFoundException.class); + .isInstanceOf(UnexpectedDomainException.class); } @Test void 입력받은_사용자를_골룸_사용자_중에서_찾는다() { // given final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), null, - MEMBER1); + LocalDateTime.now(), null, MEMBER1); final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), null, - MEMBER2); + LocalDateTime.now(), null, MEMBER2); final GoalRoomPendingMembers goalRoomPendingMembers = new GoalRoomPendingMembers( List.of(goalRoomPendingMember1, goalRoomPendingMember2)); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodeTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodeTest.java index e8c19c311..51a8d6208 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodeTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodeTest.java @@ -4,12 +4,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import co.kirikiri.domain.goalroom.vo.Period; import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.exception.BadRequestException; +import java.time.LocalDate; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.time.LocalDate; class GoalRoomRoadmapNodeTest { @@ -37,7 +37,7 @@ class GoalRoomRoadmapNodeTest { //then assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, new RoadmapNode("title", "content"))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @ParameterizedTest @@ -51,7 +51,7 @@ class GoalRoomRoadmapNodeTest { //then assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, new RoadmapNode("title", "content"))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @ParameterizedTest @@ -66,7 +66,7 @@ class GoalRoomRoadmapNodeTest { //then assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, new RoadmapNode("title", "content"))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @ParameterizedTest @@ -81,7 +81,7 @@ class GoalRoomRoadmapNodeTest { //then assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, new RoadmapNode("title", "content"))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @ParameterizedTest diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodesTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodesTest.java index 2633a6870..3743814ba 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodesTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodesTest.java @@ -5,16 +5,16 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import co.kirikiri.domain.goalroom.vo.Period; import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.exception.BadRequestException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class GoalRoomRoadmapNodesTest { @@ -60,7 +60,7 @@ class GoalRoomRoadmapNodesTest { //when //then assertThatThrownBy(() -> new GoalRoomRoadmapNodes(List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @Test diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomTest.java index 65eed4db1..8459bd4d1 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import co.kirikiri.domain.goalroom.vo.GoalRoomName; import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; import co.kirikiri.domain.goalroom.vo.Period; @@ -22,12 +23,11 @@ import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.exception.BadRequestException; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.util.Collections; import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; class GoalRoomTest { @@ -114,7 +114,7 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 //when, then assertThatThrownBy(() -> goalRoom.join(member)) - .isInstanceOf(BadRequestException.class) + .isInstanceOf(GoalRoomException.class) .hasMessage("모집 중이지 않은 골룸에는 참여할 수 없습니다."); } @@ -126,7 +126,7 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 //when,then assertThatThrownBy(() -> goalRoom.join(member)) - .isInstanceOf(BadRequestException.class) + .isInstanceOf(GoalRoomException.class) .hasMessage("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다."); } @@ -138,7 +138,7 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 //when,then assertThatThrownBy(() -> goalRoom.join(member)) - .isInstanceOf(BadRequestException.class) + .isInstanceOf(GoalRoomException.class) .hasMessage("이미 참여한 골룸에는 참여할 수 없습니다."); } @@ -223,7 +223,7 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 // when // then assertThatThrownBy(() -> goalRoom.leave(notJoinMember)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @Test diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDoTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDoTest.java index e784db669..16b3a5dce 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDoTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDoTest.java @@ -3,12 +3,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.exception.BadRequestException; +import java.time.LocalDate; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.time.LocalDate; class GoalRoomToDoTest { @@ -34,7 +34,7 @@ class GoalRoomToDoTest { //when //then assertThatThrownBy(() -> new GoalRoomToDo(new GoalRoomTodoContent("content"), new Period(startDate, endDate))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @ParameterizedTest @@ -47,6 +47,6 @@ class GoalRoomToDoTest { //when //then assertThatThrownBy(() -> new GoalRoomToDo(new GoalRoomTodoContent("content"), new Period(startDate, endDate))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomNameTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomNameTest.java index ce8928f3f..b1eafe64e 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomNameTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomNameTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -29,6 +29,6 @@ class GoalRoomNameTest { //when //then assertThatThrownBy(() -> new GoalRoomName(value)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContentTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContentTest.java index 31c2e5e77..ef200e17c 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContentTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContentTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -29,6 +29,6 @@ class GoalRoomTodoContentTest { //when //then assertThatThrownBy(() -> new GoalRoomTodoContent(value)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCountTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCountTest.java index 310413d9c..66445598a 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCountTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCountTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -25,6 +25,6 @@ class LimitedMemberCountTest { //when //then assertThatThrownBy(() -> new LimitedMemberCount(value)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/IdentifierTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/IdentifierTest.java index df615a23a..2555e7155 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/IdentifierTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/IdentifierTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.member.exception.MemberException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -25,6 +25,6 @@ class IdentifierTest { //when //then assertThatThrownBy(() -> new Identifier(identifier)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/NicknameTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/NicknameTest.java index 36b4192a7..80876918e 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/NicknameTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/NicknameTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.member.exception.MemberException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -25,6 +25,6 @@ class NicknameTest { //when //then assertThatThrownBy(() -> new Nickname(nickname)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/PasswordTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/PasswordTest.java index 83c8ffee4..a0fe0d3cb 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/PasswordTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/member/vo/PasswordTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.member.exception.MemberException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -25,7 +25,7 @@ class PasswordTest { //when //then assertThatThrownBy(() -> new Password(password)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } @ParameterizedTest @@ -35,7 +35,7 @@ class PasswordTest { //when //then assertThatThrownBy(() -> new Password(password)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } @ParameterizedTest @@ -45,7 +45,7 @@ class PasswordTest { //when //then assertThatThrownBy(() -> new Password(password)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } @ParameterizedTest @@ -55,7 +55,7 @@ class PasswordTest { //when //then assertThatThrownBy(() -> new Password(password)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } @ParameterizedTest @@ -65,7 +65,7 @@ class PasswordTest { //when //then assertThatThrownBy(() -> new Password(password)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } @ParameterizedTest @@ -75,6 +75,6 @@ class PasswordTest { //when //then assertThatThrownBy(() -> new Password(password)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(MemberException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapCategoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapCategoryTest.java index 7cc3ec57e..726de9855 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapCategoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapCategoryTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -27,7 +27,7 @@ class RoadmapCategoryTest { //when //then assertThatThrownBy(() -> new RoadmapCategory(space)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @Test @@ -38,6 +38,6 @@ class RoadmapCategoryTest { //when //then assertThatThrownBy(() -> new RoadmapCategory(space)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapContentTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapContentTest.java index 13fb847f3..4a663ac40 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapContentTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapContentTest.java @@ -13,9 +13,9 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.exception.BadRequestException; -import org.junit.jupiter.api.Test; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import java.util.List; +import org.junit.jupiter.api.Test; class RoadmapContentTest { @@ -26,7 +26,7 @@ class RoadmapContentTest { // expect assertThatThrownBy(() -> new RoadmapContent(content)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @Test diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java index 7282f7808..d5aab01ae 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java @@ -4,9 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import co.kirikiri.domain.ImageContentType; -import co.kirikiri.exception.BadRequestException; -import org.junit.jupiter.api.Test; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import java.util.List; +import org.junit.jupiter.api.Test; class RoadmapNodeImagesTest { @@ -37,7 +37,7 @@ class RoadmapNodeImagesTest { //then assertThatThrownBy( () -> new RoadmapNodeImages(List.of(roadmapNodeImage1, roadmapNodeImage2, roadmapNodeImage3))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @Test @@ -55,7 +55,7 @@ class RoadmapNodeImagesTest { //when //then assertThatThrownBy(() -> roadmapNodeImages.add(roadmapNodeImage3)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @@ -77,7 +77,7 @@ class RoadmapNodeImagesTest { //then assertThatThrownBy( () -> roadmapNodeImages.addAll(new RoadmapNodeImages(List.of(roadmapNodeImage3, roadmapNodeImage4)))) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeTest.java index 9b5f86d70..97ae660fc 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeTest.java @@ -2,7 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -16,7 +16,7 @@ class RoadmapNodeTest { // expect assertThatThrownBy(() -> new RoadmapNode(title, "로드맵 설명")) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @ParameterizedTest @@ -27,6 +27,6 @@ class RoadmapNodeTest { // expect assertThatThrownBy(() -> new RoadmapNode("로드맵 제목", content)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapReviewTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapReviewTest.java index 14964360c..0e7dcd492 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapReviewTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapReviewTest.java @@ -11,7 +11,7 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -44,7 +44,7 @@ class RoadmapReviewTest { // expected assertThatThrownBy(() -> new RoadmapReview(content, null, member)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @ParameterizedTest @@ -57,6 +57,6 @@ class RoadmapReviewTest { // expected assertThatThrownBy(() -> new RoadmapReview("리뷰", rate, member)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTagsTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTagsTest.java index 7d730fa06..76ba65ba5 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTagsTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTagsTest.java @@ -4,10 +4,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; -import co.kirikiri.exception.BadRequestException; -import org.junit.jupiter.api.Test; import java.util.List; +import org.junit.jupiter.api.Test; class RoadmapTagsTest { @@ -42,7 +42,7 @@ class RoadmapTagsTest { // expected assertThatThrownBy(() -> new RoadmapTags(values)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @Test @@ -54,6 +54,6 @@ class RoadmapTagsTest { // expected assertThatThrownBy(() -> new RoadmapTags(values)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTest.java index acb5d82ce..cea624848 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapTest.java @@ -12,11 +12,11 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.util.List; class RoadmapTest { @@ -53,7 +53,7 @@ class RoadmapTest { // expect assertThatThrownBy(() -> new Roadmap(title, "로드맵 소개글", 30, DIFFICULT, creator, category)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @ParameterizedTest @@ -64,7 +64,7 @@ class RoadmapTest { // expect assertThatThrownBy(() -> new Roadmap("로드맵 제목", introduction, 30, DIFFICULT, creator, category)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @ParameterizedTest @@ -72,7 +72,7 @@ class RoadmapTest { void 로드맵_추천_소요_기간이_0보다_작고_1000보다_크면_예외가_발생한다(final int requiredPeriod) { // expect assertThatThrownBy(() -> new Roadmap("로드맵 제목", "로드맵 소개글", requiredPeriod, DIFFICULT, creator, category)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } private Member 크리에이터를_생성한다() { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/vo/RoadmapTagNameTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/vo/RoadmapTagNameTest.java index dec613138..d563697df 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/vo/RoadmapTagNameTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/vo/RoadmapTagNameTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.domain.roadmap.exception.RoadmapException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; @@ -30,7 +30,7 @@ class RoadmapTagNameTest { // expected assertThatThrownBy(() -> new RoadmapTagName(name)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(RoadmapException.class); } @ParameterizedTest diff --git a/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java index 133c86f17..602e83e4d 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java @@ -7,12 +7,15 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; -import co.kirikiri.exception.ServerException; import co.kirikiri.service.dto.FileInformation; +import co.kirikiri.service.exception.ServerException; import com.amazonaws.AmazonServiceException; import com.amazonaws.Protocol; import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; +import java.io.FileInputStream; +import java.net.MalformedURLException; +import java.net.URL; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -20,9 +23,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.env.Environment; import org.springframework.http.HttpMethod; -import java.io.FileInputStream; -import java.net.MalformedURLException; -import java.net.URL; @ExtendWith(MockitoExtension.class) class AmazonS3FileServiceTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java index 8a80955ca..1b56ff0d4 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java @@ -4,15 +4,15 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; -import co.kirikiri.exception.ServerException; +import co.kirikiri.service.exception.ServerException; +import java.net.MalformedURLException; +import java.net.URL; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.env.Environment; -import java.net.MalformedURLException; -import java.net.URL; @ExtendWith(MockitoExtension.class) class CloudFrontServiceTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java index 986140b94..efc6e01a2 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java @@ -15,9 +15,9 @@ import com.fasterxml.jackson.core.type.TypeReference; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; -import java.util.List; class AuthenticationIntegrationTest extends InitIntegrationTest { @@ -90,7 +90,7 @@ class AuthenticationIntegrationTest extends InitIntegrationTest { } @Test - void 정상적으로_토큰_재발행을_힌다() { + void 정상적으로_토큰_재발행을_한다() { //given final ReissueTokenRequest 토큰_재발행_요청 = new ReissueTokenRequest(기본_재발행_토큰); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java index 7c9b5efda..b1f922460 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java @@ -50,14 +50,14 @@ import io.restassured.common.mapper.TypeRef; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockMultipartFile; import java.io.IOException; import java.time.temporal.ChronoUnit; import java.util.Collections; import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockMultipartFile; class GoalRoomCreateIntegrationTest extends InitIntegrationTest { @@ -290,37 +290,6 @@ class GoalRoomCreateIntegrationTest extends InitIntegrationTest { ); } - @Test - void 모집_중이지_않은_골룸에_참가_요청을_보내면_예외가_발생한다() throws IOException { - //given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final List 골룸_노드_별_기간_요청 = List.of( - new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); - final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, - 골룸_노드_별_기간_요청); - final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - - final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", - "follower", GenderType.FEMALE, DEFAULT_EMAIL); - final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); - 회원가입(팔로워_회원_가입_요청); - final String 팔로워_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(팔로워_로그인_요청).accessToken()); - - //when - final ExtractableResponse 참가_요청에_대한_응답 = 골룸_참가_요청(골룸_아이디, 팔로워_액세스_토큰); - - //then - final String 예외_메시지 = 참가_요청에_대한_응답.asString(); - - assertAll( - () -> assertThat(참가_요청에_대한_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()), - () -> assertThat(예외_메시지).contains("모집 중이지 않은 골룸에는 참여할 수 없습니다.") - ); - } - @Test void 인증_피드_등록을_요청한다() throws IOException { //given diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java index 962b53b67..f4f5e9399 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java @@ -26,7 +26,6 @@ import co.kirikiri.integration.helper.InitIntegrationTest; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; -import co.kirikiri.service.scheduler.GoalRoomScheduler; import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; @@ -34,9 +33,10 @@ import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; -import org.junit.jupiter.api.Test; +import co.kirikiri.service.scheduler.GoalRoomScheduler; import java.io.IOException; import java.util.List; +import org.junit.jupiter.api.Test; class GoalRoomSchedulerIntegrationTest extends InitIntegrationTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java index 9a47c4872..8f62a2887 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java @@ -1,5 +1,6 @@ package co.kirikiri.integration.helper; +import co.kirikiri.persistence.auth.RefreshTokenRepository; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomRepository; import co.kirikiri.service.FileService; @@ -27,4 +28,9 @@ public FileService fileService() { public TestTransactionService testTransactionService() { return new TestTransactionService(goalRoomRepository, goalRoomMemberRepository); } + + @Bean + public RefreshTokenRepository refreshTokenRepository() { + return new TestRefreshTokenRepository(); + } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestRefreshTokenRepository.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestRefreshTokenRepository.java new file mode 100644 index 000000000..94f9344a0 --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestRefreshTokenRepository.java @@ -0,0 +1,18 @@ +package co.kirikiri.integration.helper; + +import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_IDENTIFIER; + +import co.kirikiri.persistence.auth.RefreshTokenRepository; +import java.util.Optional; + +public class TestRefreshTokenRepository implements RefreshTokenRepository { + + @Override + public void save(final String refreshToken, final String memberIdentifier) { + } + + @Override + public Optional findMemberIdentifierByRefreshToken(final String refreshToken) { + return Optional.of(DEFAULT_IDENTIFIER); + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java index 5d4b7ec6f..accf118e2 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java @@ -88,7 +88,7 @@ public TestTransactionService(final GoalRoomRepository goalRoomRepository, } public void 골룸_멤버를_저장한다(final List 골룸_멤버_리스트) { - goalRoomMemberRepository.saveAll(골룸_멤버_리스트); + goalRoomMemberRepository.saveAllInBatch(골룸_멤버_리스트); } public void 골룸의_상태와_종료날짜를_변경한다(final Long 골룸_아이디, final GoalRoomStatus 골룸_상태, final LocalDate 변경할_종료날짜) { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/auth/RefreshTokenRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/auth/RefreshTokenRepositoryTest.java index b3ac7c571..d31e6d075 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/auth/RefreshTokenRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/auth/RefreshTokenRepositoryTest.java @@ -1,9 +1,9 @@ package co.kirikiri.persistence.auth; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.Mockito.when; -import co.kirikiri.domain.auth.EncryptedToken; -import co.kirikiri.domain.auth.RefreshToken; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -11,27 +11,39 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.persistence.helper.RepositoryTest; -import co.kirikiri.persistence.member.MemberRepository; +import java.util.Optional; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.time.LocalDateTime; -import java.util.Optional; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; -@RepositoryTest +@ExtendWith(MockitoExtension.class) class RefreshTokenRepositoryTest { + private static final Long refreshTokenValidityInSeconds = 3600000L; + private static Member member; - private final RefreshTokenRepository refreshTokenRepository; - private final MemberRepository memberRepository; + @Mock + private RedisTemplate redisTemplate; - public RefreshTokenRepositoryTest(final RefreshTokenRepository refreshTokenRepository, - final MemberRepository memberRepository) { - this.refreshTokenRepository = refreshTokenRepository; - this.memberRepository = memberRepository; + @Mock + private ValueOperations valueOperations; + + private RefreshTokenRepositoryImpl refreshTokenRepository; + + @BeforeEach + void init() { + when(redisTemplate.opsForValue()) + .thenReturn(valueOperations); + refreshTokenRepository = new RefreshTokenRepositoryImpl(redisTemplate, refreshTokenValidityInSeconds); } + @BeforeAll static void setUp() { final Identifier identifier = new Identifier("identifier1"); @@ -44,22 +56,42 @@ static void setUp() { } @Test - void 정상적으로_취소되지_않은_리프레시_토큰을_찾아온다() { + void 정상적으로_리프레시_토큰을_저장한다() { //given - final EncryptedToken encryptedToken = new EncryptedToken("refreshToken"); - final LocalDateTime now = LocalDateTime.now(); - final RefreshToken refreshToken = new RefreshToken(encryptedToken, now, member); - memberRepository.save(member); - refreshTokenRepository.save(refreshToken); + final String refreshToken = "refreshToken"; + final String memberIdentifier = member.getIdentifier().getValue(); //when - final Optional optionalRefreshToken = refreshTokenRepository.findByTokenAndIsRevokedFalse( - encryptedToken); + //then + assertDoesNotThrow(() -> refreshTokenRepository.save(refreshToken, memberIdentifier)); + } + + @Test + void 정상적으로_리프레시_토큰을_찾아온다() { + //given + final String refreshToken = "refreshToken"; + final String memberIdentifier = member.getIdentifier().getValue(); + when(valueOperations.get(refreshToken)) + .thenReturn(memberIdentifier); + + //when + final String findMemberIdentifier = refreshTokenRepository.findMemberIdentifierByRefreshToken(refreshToken) + .get(); + + //then + assertThat(findMemberIdentifier).isEqualTo(memberIdentifier); + } + + @Test + void 리프레시_토큰을_찾을때_없는경우_빈값을_보낸다() { + //given + final String refreshToken = "refreshToken"; + + //when + final Optional memberIdentifier = refreshTokenRepository.findMemberIdentifierByRefreshToken( + refreshToken); //then - assertThat(optionalRefreshToken).isNotEmpty(); - final RefreshToken result = optionalRefreshToken.get(); - assertThat(result.getToken()).usingRecursiveComparison() - .isEqualTo(encryptedToken); + assertThat(memberIdentifier).isEmpty(); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java index fb9553bf2..23459fce2 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.service.exception.BadRequestException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java index 3b1fc8512..add4ecca9 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.service.exception.BadRequestException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/CheckFeedRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/CheckFeedRepositoryTest.java index 54f04deca..f4eb535ee 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/CheckFeedRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/CheckFeedRepositoryTest.java @@ -34,10 +34,10 @@ import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; -import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; +import org.junit.jupiter.api.Test; @RepositoryTest class CheckFeedRepositoryTest { @@ -86,7 +86,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); 인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember); @@ -120,7 +120,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); 인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember); @@ -151,7 +151,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); @@ -188,7 +188,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, member); final GoalRoomMember otherLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom2, creator); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom1.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom1.getGoalRoomRoadmapNodes().getValues().get(1); @@ -226,7 +226,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); @@ -269,7 +269,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); @@ -303,7 +303,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); @@ -348,7 +348,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); @@ -407,7 +407,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, member); - goalRoomMemberRepository.saveAll(List.of(leader, joinedMember)); + goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepositoryTest.java index 7100454e9..5fed7fa95 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepositoryTest.java @@ -33,12 +33,12 @@ import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; @RepositoryTest class GoalRoomMemberRepositoryTest { @@ -296,11 +296,13 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, private Member 크리에이터를_저장한다() { final MemberImage memberImage = new MemberImage("originalFileName", "serverFilePath", ImageContentType.JPG); final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com"); - final Member creator = new Member(1L, new Identifier("cokirikiri"), null, new EncryptedPassword(new Password("password1!")), new Nickname("코끼리"), memberImage, memberProfile); + final Member creator = new Member(1L, new Identifier("cokirikiri"), null, + new EncryptedPassword(new Password("password1!")), new Nickname("코끼리"), memberImage, memberProfile); return memberRepository.save(creator); } - private Member 사용자를_생성한다(final String identifier, final String password, final String nickname, final String email) { + private Member 사용자를_생성한다(final String identifier, final String password, final String nickname, + final String email) { final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); final Member member = new Member(new Identifier(identifier), new EncryptedPassword(new Password(password)), new Nickname(nickname), diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepositoryTest.java index d62e38a7a..2d7ebd328 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepositoryTest.java @@ -30,10 +30,10 @@ import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; -import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; +import org.junit.jupiter.api.Test; @RepositoryTest class GoalRoomToDoCheckRepositoryTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/helper/RepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/helper/RepositoryTest.java index a26bd5a43..5bfa474ac 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/helper/RepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/helper/RepositoryTest.java @@ -1,19 +1,16 @@ package co.kirikiri.persistence.helper; -import co.kirikiri.common.config.JpaConfig; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; -import org.springframework.test.context.TestConstructor.AutowireMode; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestConstructor; +import org.springframework.test.context.TestConstructor.AutowireMode; @DataJpaTest @ActiveProfiles("test") -@Import({JpaConfig.class}) @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @TestConstructor(autowireMode = AutowireMode.ALL) diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java index 3021665bd..83ab3ff56 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java @@ -37,11 +37,11 @@ import co.kirikiri.persistence.goalroom.GoalRoomRepository; import co.kirikiri.persistence.helper.RepositoryTest; import co.kirikiri.persistence.member.MemberRepository; -import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; +import org.junit.jupiter.api.Test; @RepositoryTest class RoadmapRepositoryTest { @@ -249,13 +249,13 @@ public RoadmapRepositoryTest(final MemberRepository memberRepository, // gameRoadmap2 : 참가인원 1명 final List gameRoadmap2GoalRoomMembers = List.of( new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), gameRoadmap2GoalRoom, creator)); - goalRoomMemberRepository.saveAll(gameRoadmap2GoalRoomMembers); + goalRoomMemberRepository.saveAllInBatch(gameRoadmap2GoalRoomMembers); // travelRoadmap : 참가인원 2명 final List travelRoadmapGoalRoomMembers = List.of( new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), travelRoadmapGoalRoom, creator), new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), travelRoadmapGoalRoom, follower)); - goalRoomMemberRepository.saveAll(travelRoadmapGoalRoomMembers); + goalRoomMemberRepository.saveAllInBatch(travelRoadmapGoalRoomMembers); final RoadmapCategory category = null; final RoadmapOrderType orderType = RoadmapOrderType.PARTICIPANT_COUNT; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java index de56fb58d..ddf3ec88a 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java @@ -3,11 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import co.kirikiri.domain.auth.EncryptedToken; -import co.kirikiri.domain.auth.RefreshToken; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -15,7 +12,6 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.exception.AuthenticationException; import co.kirikiri.persistence.auth.RefreshTokenRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.service.auth.AuthService; @@ -23,14 +19,14 @@ import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; +import co.kirikiri.service.exception.AuthenticationException; +import java.util.Optional; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.time.LocalDateTime; -import java.util.Optional; @ExtendWith(MockitoExtension.class) class AuthServiceTest { @@ -66,20 +62,20 @@ static void setUp() { final LoginRequest loginRequest = new LoginRequest("identifier1", "password1!"); final String accessToken = "accessToken"; final String refreshToken = "refreshToken"; + given(memberRepository.findByIdentifier(any())) .willReturn(Optional.of(member)); given(tokenProvider.createAccessToken(any(), any())) .willReturn(accessToken); given(tokenProvider.createRefreshToken(any(), any())) .willReturn(refreshToken); - given(tokenProvider.findTokenExpiredAt(anyString())) - .willReturn(LocalDateTime.now()); //when final AuthenticationResponse authenticationResponse = authService.login(loginRequest); //then - assertThat(authenticationResponse).isEqualTo(new AuthenticationResponse(refreshToken, accessToken)); + assertThat(authenticationResponse).isEqualTo( + new AuthenticationResponse(refreshToken, accessToken)); } @Test @@ -111,34 +107,33 @@ static void setUp() { @Test void 정상적으로_토큰을_재발행한다() { //given - final String rawAccessToken = "accessToken"; - final String rawRefreshToken = "refreshToken"; + final String accessToken = "accessToken"; + final String refreshToken = "refreshToken"; final ReissueTokenRequest reissueTokenRequest = new ReissueTokenRequest("refreshToken"); - final RefreshToken refreshToken = new RefreshToken(new EncryptedToken(rawRefreshToken), LocalDateTime.MAX, - member); + given(tokenProvider.isValidToken(any())) .willReturn(true); - given(refreshTokenRepository.findByTokenAndIsRevokedFalse(any())) - .willReturn(Optional.of(refreshToken)); given(tokenProvider.createAccessToken(any(), any())) - .willReturn(rawAccessToken); + .willReturn(accessToken); given(tokenProvider.createRefreshToken(any(), any())) - .willReturn(rawRefreshToken); - given(tokenProvider.findTokenExpiredAt(anyString())) - .willReturn(LocalDateTime.now()); + .willReturn(refreshToken); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(refreshTokenRepository.findMemberIdentifierByRefreshToken(any())) + .willReturn(Optional.of(refreshToken)); //when final AuthenticationResponse authenticationResponse = authService.reissueToken(reissueTokenRequest); //then - assertThat(authenticationResponse).isEqualTo(new AuthenticationResponse(rawRefreshToken, rawAccessToken)); + assertThat(authenticationResponse).isEqualTo(new AuthenticationResponse(refreshToken, accessToken)); } @Test void 리프레시_토큰이_유효하지_않을_경우_예외를_던진다() { //given - final String rawRefreshToken = "refreshToken"; - final ReissueTokenRequest reissueTokenRequest = new ReissueTokenRequest(rawRefreshToken); + final String refreshToken = "refreshToken"; + final ReissueTokenRequest reissueTokenRequest = new ReissueTokenRequest(refreshToken); given(tokenProvider.isValidToken(any())) .willReturn(false); @@ -149,13 +144,13 @@ static void setUp() { } @Test - void 리프레시_토큰이_존재하지_않을_경우_예외를_던진다() { + void 리프레시_토큰이_만료_됐을_경우_예외를_던진다() { //given - final String rawRefreshToken = "refreshToken"; - final ReissueTokenRequest reissueTokenRequest = new ReissueTokenRequest(rawRefreshToken); + final String refreshToken = "refreshToken"; + final ReissueTokenRequest reissueTokenRequest = new ReissueTokenRequest(refreshToken); given(tokenProvider.isValidToken(any())) .willReturn(true); - given(refreshTokenRepository.findByTokenAndIsRevokedFalse(any())) + given(refreshTokenRepository.findMemberIdentifierByRefreshToken(any())) .willReturn(Optional.empty()); //when @@ -165,16 +160,16 @@ static void setUp() { } @Test - void 리프레시_토큰이_만료_됐을_경우_예외를_던진다() { + void 리프레시_토큰으로_조회한_회원이_존재하지_않는_경우_예외를_던진다() { //given - final String rawRefreshToken = "refreshToken"; - final ReissueTokenRequest reissueTokenRequest = new ReissueTokenRequest(rawRefreshToken); - final RefreshToken refreshToken = new RefreshToken(new EncryptedToken(rawRefreshToken), LocalDateTime.MIN, - member); + final String refreshToken = "refreshToken"; + final ReissueTokenRequest reissueTokenRequest = new ReissueTokenRequest(refreshToken); given(tokenProvider.isValidToken(any())) .willReturn(true); - given(refreshTokenRepository.findByTokenAndIsRevokedFalse(any())) - .willReturn(Optional.of(refreshToken)); + given(refreshTokenRepository.findMemberIdentifierByRefreshToken(any())) + .willReturn(Optional.of(member.getIdentifier().getValue())); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.empty()); //when //then diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/CacheKeyGeneratorTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/CacheKeyGeneratorTest.java new file mode 100644 index 000000000..08fea3baf --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/CacheKeyGeneratorTest.java @@ -0,0 +1,31 @@ +package co.kirikiri.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; + +class CacheKeyGeneratorTest { + + private final CacheKeyGenerator cacheKeyGenerator = new CacheKeyGenerator(); + + @Test + void 정상적으로_키를_생성한다() throws NoSuchMethodException { + //given + final Class targetClass = Object.class; + final Method method = targetClass.getMethod("toString"); + final Object[] params = new Object[]{"param1", null, 123}; + + //when + final String key = (String) cacheKeyGenerator.generate(targetClass, method, params); + + //then + assertThat(key).contains("Class", "toString"); + for (final Object param : params) { + if (param == null) { + continue; + } + assertThat(key).contains(String.valueOf(param.hashCode())); + } + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomCreateServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomCreateServiceTest.java index 2f87483bc..b409f8ddb 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomCreateServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomCreateServiceTest.java @@ -14,6 +14,7 @@ import static org.mockito.Mockito.when; import co.kirikiri.domain.ImageContentType; +import co.kirikiri.domain.exception.ImageExtensionException; import co.kirikiri.domain.goalroom.CheckFeed; import co.kirikiri.domain.goalroom.GoalRoom; import co.kirikiri.domain.goalroom.GoalRoomMember; @@ -22,6 +23,7 @@ import co.kirikiri.domain.goalroom.GoalRoomRole; import co.kirikiri.domain.goalroom.GoalRoomToDo; import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; +import co.kirikiri.domain.goalroom.exception.GoalRoomException; import co.kirikiri.domain.goalroom.vo.GoalRoomName; import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; @@ -43,8 +45,6 @@ import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; import co.kirikiri.domain.roadmap.RoadmapStatus; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.goalroom.CheckFeedRepository; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomRepository; @@ -56,14 +56,9 @@ import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.goalroom.GoalRoomCreateService; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.mock.web.MockMultipartFile; import java.net.MalformedURLException; import java.net.URL; import java.time.LocalDate; @@ -71,6 +66,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.mock.web.MockMultipartFile; @ExtendWith(MockitoExtension.class) class GoalRoomCreateServiceTest { @@ -250,7 +252,7 @@ static void setUp() { when(memberRepository.findByIdentifier(any())) .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findById(anyLong())) + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) .thenReturn(Optional.of(goalRoom)); //when @@ -280,7 +282,7 @@ static void setUp() { when(memberRepository.findByIdentifier(any())) .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findById(anyLong())) + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) .thenReturn(Optional.empty()); //when, then @@ -302,12 +304,12 @@ static void setUp() { when(memberRepository.findByIdentifier(any())) .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findById(anyLong())) + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) .thenReturn(Optional.of(goalRoom)); //when, then assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) - .isInstanceOf(BadRequestException.class) + .isInstanceOf(GoalRoomException.class) .hasMessage("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다."); } @@ -324,12 +326,12 @@ static void setUp() { when(memberRepository.findByIdentifier(any())) .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findById(anyLong())) + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) .thenReturn(Optional.of(goalRoom)); //when, then assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) - .isInstanceOf(BadRequestException.class) + .isInstanceOf(GoalRoomException.class) .hasMessage("모집 중이지 않은 골룸에는 참여할 수 없습니다."); } @@ -481,7 +483,7 @@ static void setUp() { //when //then assertThatThrownBy(() -> goalRoomCreateService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) - .isInstanceOf(BadRequestException.class); + .isInstanceOf(GoalRoomException.class); } @Test @@ -727,7 +729,7 @@ static void setUp() { // when assertThatThrownBy( () -> goalRoomCreateService.createCheckFeed("identifier", 1L, request)) - .isInstanceOf(BadRequestException.class) + .isInstanceOf(ImageExtensionException.class) .hasMessage("허용되지 않는 확장자입니다."); } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomReadServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomReadServiceTest.java index cf9e3a7d4..cf1452150 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomReadServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomReadServiceTest.java @@ -41,8 +41,6 @@ import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.exception.ForbiddenException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.goalroom.CheckFeedRepository; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; @@ -64,6 +62,9 @@ import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; import co.kirikiri.service.dto.member.response.MemberResponse; +import co.kirikiri.service.exception.ForbiddenException; +import co.kirikiri.service.exception.NotFoundException; +import co.kirikiri.service.goalroom.GoalRoomReadService; import java.net.MalformedURLException; import java.net.URL; import java.time.LocalDate; @@ -71,8 +72,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; - -import co.kirikiri.service.goalroom.GoalRoomReadService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomSchedulerTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomSchedulerTest.java index 3fbbf325e..f4118210d 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomSchedulerTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomSchedulerTest.java @@ -4,9 +4,8 @@ import static co.kirikiri.domain.goalroom.GoalRoomStatus.RUNNING; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.Mockito.times; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -39,15 +38,15 @@ import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomRepository; import co.kirikiri.service.scheduler.GoalRoomScheduler; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; @ExtendWith(MockitoExtension.class) class GoalRoomSchedulerTest { @@ -59,11 +58,11 @@ class GoalRoomSchedulerTest { @Mock private GoalRoomRepository goalRoomRepository; - @Mock - private GoalRoomMemberRepository goalRoomMemberRepository; - @Mock private GoalRoomPendingMemberRepository goalRoomPendingMemberRepository; + + @Mock + private GoalRoomMemberRepository goalRoomMemberRepository; @InjectMocks private GoalRoomScheduler goalRoomScheduler; @@ -83,9 +82,9 @@ class GoalRoomSchedulerTest { final Member follower2 = 사용자를_생성한다(3L, "identifier2", "password3!", "name2", "kirikiri@email.com"); final Member follower3 = 사용자를_생성한다(4L, "identifier3", "password4!", "name3", "kirikiri@email.com"); - final GoalRoomPendingMember goalRoomPendingMember = 골룸_대기자를_생성한다(goalRoom2, creator, GoalRoomRole.FOLLOWER); - final GoalRoomPendingMember goalRoomPendingMember1 = 골룸_대기자를_생성한다(goalRoom1, follower1, GoalRoomRole.FOLLOWER); - final GoalRoomPendingMember goalRoomPendingMember2 = 골룸_대기자를_생성한다(goalRoom1, follower2, GoalRoomRole.FOLLOWER); + 골룸_대기자를_생성한다(goalRoom2, creator, GoalRoomRole.FOLLOWER); + 골룸_대기자를_생성한다(goalRoom1, follower1, GoalRoomRole.FOLLOWER); + 골룸_대기자를_생성한다(goalRoom1, follower2, GoalRoomRole.FOLLOWER); goalRoom1.join(follower1); goalRoom1.join(follower2); @@ -130,9 +129,7 @@ class GoalRoomSchedulerTest { goalRoomScheduler.startGoalRooms(); // then - verify(goalRoomPendingMemberRepository, times(0)).findAllByGoalRoom(any()); - verify(goalRoomMemberRepository, times(0)).saveAll(anyList()); - verify(goalRoomPendingMemberRepository, times(0)).deleteAll(anyList()); + verify(goalRoomPendingMemberRepository, never()).deleteAllByIdIn(anyList()); assertAll( () -> assertThat(goalRoom1.getStatus()).isEqualTo(RECRUITING), diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java index 27caf0432..ec35509ae 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java @@ -4,15 +4,16 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.exception.AuthenticationException; import co.kirikiri.service.auth.JwtTokenProvider; import co.kirikiri.service.auth.TokenProvider; +import co.kirikiri.service.exception.AuthenticationException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; -import org.junit.jupiter.api.Test; +import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; +import org.junit.jupiter.api.Test; class JwtTokenProviderTest { @@ -47,10 +48,10 @@ class JwtTokenProviderTest { final Map claims = new HashMap<>(Map.of("test1", "test1", "test2", "test2")); //when - final String accessToken = tokenProvider.createRefreshToken(subject, claims); + final String refreshToken = tokenProvider.createRefreshToken(subject, claims); //then - final Claims result = getClaims(accessToken); + final Claims result = getClaims(refreshToken); assertThat(result.getSubject()).isEqualTo(subject); // subject 확인 for (final String claimKey : claims.keySet()) { // custom claim 확인 @@ -124,4 +125,18 @@ private Claims getClaims(final String accessToken) { //then assertThat(result).isEqualTo(subject); } + + @Test + void 토큰의_만료기간을_가져온다() { + //given + final String subject = "subject"; + final Map claims = new HashMap<>(Map.of("test1", "test1", "test2", "test2")); + final String refreshToken = tokenProvider.createRefreshToken(subject, claims); + + //when + final LocalDateTime tokenExpiredAt = tokenProvider.findTokenExpiredAt(refreshToken); + + //then + assertThat(tokenExpiredAt).isAfter(LocalDateTime.now()); + } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java index 12fde346e..30d66dc46 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java @@ -15,8 +15,6 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.exception.ConflictException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.auth.RefreshTokenRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.service.auth.TokenProvider; @@ -26,7 +24,12 @@ import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.member.response.MemberInformationForPublicResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; +import co.kirikiri.service.exception.ConflictException; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.member.MemberService; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -35,9 +38,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.env.Environment; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Optional; @ExtendWith(MockitoExtension.class) class MemberServiceTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java index 74a6ac7af..e2ce4b915 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java @@ -17,8 +17,6 @@ import co.kirikiri.domain.roadmap.RoadmapDifficulty; import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ServerException; import co.kirikiri.persistence.roadmap.RoadmapContentRepository; import co.kirikiri.service.dto.FileInformation; import co.kirikiri.service.dto.roadmap.RoadmapNodeSaveDto; @@ -26,7 +24,11 @@ import co.kirikiri.service.dto.roadmap.RoadmapTagSaveDto; import co.kirikiri.service.dto.roadmap.request.RoadmapDifficultyType; import co.kirikiri.service.event.RoadmapCreateEvent; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ServerException; import co.kirikiri.service.roadmap.RoadmapCreateEventListener; +import java.io.IOException; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -34,8 +36,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; -import java.util.List; @ExtendWith(MockitoExtension.class) class RoadmapCreateEventListenerTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java index d807b1713..f0c78c42e 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java @@ -30,11 +30,6 @@ import co.kirikiri.domain.roadmap.RoadmapContents; import co.kirikiri.domain.roadmap.RoadmapDifficulty; import co.kirikiri.domain.roadmap.RoadmapReview; -import co.kirikiri.exception.AuthenticationException; -import co.kirikiri.exception.BadRequestException; -import co.kirikiri.exception.ConflictException; -import co.kirikiri.exception.ForbiddenException; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; import co.kirikiri.persistence.goalroom.GoalRoomRepository; import co.kirikiri.persistence.member.MemberRepository; @@ -47,17 +42,22 @@ import co.kirikiri.service.dto.roadmap.request.RoadmapReviewSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapTagSaveRequest; +import co.kirikiri.service.exception.AuthenticationException; +import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.service.exception.ConflictException; +import co.kirikiri.service.exception.ForbiddenException; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.roadmap.RoadmapCreateService; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.context.ApplicationEventPublisher; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; -import java.util.Optional; @ExtendWith(MockitoExtension.class) class RoadmapCreateServiceTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java index 36ab3e637..d6222964e 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java @@ -1,5 +1,14 @@ package co.kirikiri.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; + import co.kirikiri.domain.ImageContentType; import co.kirikiri.domain.goalroom.GoalRoom; import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; @@ -8,13 +17,24 @@ import co.kirikiri.domain.goalroom.vo.GoalRoomName; import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.domain.member.*; +import co.kirikiri.domain.member.EncryptedPassword; +import co.kirikiri.domain.member.Gender; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.MemberImage; +import co.kirikiri.domain.member.MemberProfile; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.domain.roadmap.*; +import co.kirikiri.domain.roadmap.Roadmap; +import co.kirikiri.domain.roadmap.RoadmapCategory; +import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.domain.roadmap.RoadmapDifficulty; +import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.domain.roadmap.RoadmapReview; +import co.kirikiri.domain.roadmap.RoadmapTag; +import co.kirikiri.domain.roadmap.RoadmapTags; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; -import co.kirikiri.exception.NotFoundException; import co.kirikiri.persistence.goalroom.GoalRoomRepository; import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; import co.kirikiri.persistence.member.MemberRepository; @@ -27,14 +47,20 @@ import co.kirikiri.service.dto.roadmap.RoadmapGoalRoomsOrderTypeDto; import co.kirikiri.service.dto.roadmap.request.RoadmapOrderTypeRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSearchRequest; -import co.kirikiri.service.dto.roadmap.response.*; +import co.kirikiri.service.dto.roadmap.response.MemberRoadmapResponse; +import co.kirikiri.service.dto.roadmap.response.MemberRoadmapResponses; +import co.kirikiri.service.dto.roadmap.response.RoadmapCategoryResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapContentResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponses; +import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; +import co.kirikiri.service.dto.roadmap.response.RoadmapNodeResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; +import co.kirikiri.service.dto.roadmap.response.RoadmapTagResponse; +import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.roadmap.RoadmapReadService; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - import java.net.MalformedURLException; import java.net.URL; import java.time.LocalDate; @@ -42,12 +68,11 @@ import java.util.Collections; import java.util.List; import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.when; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class RoadmapReadServiceTest { @@ -480,11 +505,13 @@ roadmapId, new RoadmapCategoryResponse(1L, "운동"), "로드맵 제목", "로 final RoadmapGoalRoomResponses expected = new RoadmapGoalRoomResponses(List.of( - new RoadmapGoalRoomResponse(2L, "goalroom2", GoalRoomStatus.RECRUITING, 1, 10, LocalDateTime.now(), + new RoadmapGoalRoomResponse(2L, "goalroom2", GoalRoomStatus.RECRUITING, 1, 10, + LocalDateTime.now(), TODAY, TODAY.plusDays(20), new MemberResponse(member3.getId(), member3.getNickname().getValue(), "http://example.com/serverFilePath")), - new RoadmapGoalRoomResponse(1L, "goalroom1", GoalRoomStatus.RECRUITING, 1, 10, LocalDateTime.now(), + new RoadmapGoalRoomResponse(1L, "goalroom1", GoalRoomStatus.RECRUITING, 1, 10, + LocalDateTime.now(), TODAY, TODAY.plusDays(20), new MemberResponse(member2.getId(), member2.getNickname().getValue(), "http://example.com/serverFilePath"))), false); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java index bb5e9a8f2..7e9dc620d 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertTrue; -import co.kirikiri.exception.BadRequestException; +import co.kirikiri.service.exception.BadRequestException; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/resources/application.yml b/backend/kirikiri/src/test/resources/application.yml index 848cc7b50..54e9cdfd7 100644 --- a/backend/kirikiri/src/test/resources/application.yml +++ b/backend/kirikiri/src/test/resources/application.yml @@ -15,6 +15,10 @@ spring: max-file-size: 10MB flyway: enabled: false + data: + redis: + host: localhost + port: 6379 logging: level: @@ -55,14 +59,15 @@ cloud: stack: auto: false credentials: - instanceProfile: true + access-key: access-key + secret-key: secret-key s3: - bucket: 2023-team-project + bucket: 2023-team-project-kirikiri root-directory: 2023-co-kirikiri sub-directory: prod url-expiration: 60000 cloud-front: - distribution-domain: https://d3pqwmpjbeqywx.cloudfront.net + distribution-domain: https://d3c3ldqehj669c.cloudfront.net oauth: naver: