From f0a9e62c60953be16de0d8c53f48660dfc784a66 Mon Sep 17 00:00:00 2001 From: nuyh Date: Thu, 3 Aug 2023 18:03:07 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #1397 --- .../common/exception/BadRequestCode.java | 3 + .../roadmap/domain/RecommendedPost.java | 30 +++++++++- .../roadmap/domain/RecommendedPostTest.java | 57 ++++++++++++++++++- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/wooteco/prolog/common/exception/BadRequestCode.java b/backend/src/main/java/wooteco/prolog/common/exception/BadRequestCode.java index 26c6e70c4..430ab9861 100644 --- a/backend/src/main/java/wooteco/prolog/common/exception/BadRequestCode.java +++ b/backend/src/main/java/wooteco/prolog/common/exception/BadRequestCode.java @@ -2,6 +2,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import wooteco.prolog.roadmap.domain.RecommendedPost; import wooteco.prolog.session.domain.Mission; import wooteco.prolog.session.domain.Session; import wooteco.prolog.studylog.domain.TagName; @@ -71,6 +72,8 @@ public enum BadRequestCode { ESSAY_ANSWER_NOT_VALID_USER(8014, "본인이 작성한 답변만 수정할 수 있습니다."), ROADMAP_RECOMMENDED_POST_NOT_FOUND(8101, "해당 추천 포스트가 존재하지 않습니다."), + ROADMAP_RECOMMENDED_POST_INVALID_URL_LENGTH(8102, String.format( + "해당 추천 포스트의 URL 길이는 1 ~ %d여야 합니다.", RecommendedPost.URL_LENGTH_UPPER_BOUND)), FILE_NAME_EMPTY_EXCEPTION(9001, "파일 이름이 존재하지 않습니다."), UNSUPPORTED_FILE_EXTENSION_EXCEPTION(9002, "지원하지 않는 파일 확장자입니다."), diff --git a/backend/src/main/java/wooteco/prolog/roadmap/domain/RecommendedPost.java b/backend/src/main/java/wooteco/prolog/roadmap/domain/RecommendedPost.java index 51c9b3f6b..69be9f18e 100644 --- a/backend/src/main/java/wooteco/prolog/roadmap/domain/RecommendedPost.java +++ b/backend/src/main/java/wooteco/prolog/roadmap/domain/RecommendedPost.java @@ -1,9 +1,9 @@ package wooteco.prolog.roadmap.domain; import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import wooteco.prolog.common.exception.BadRequestException; import javax.persistence.Column; import javax.persistence.Entity; @@ -14,12 +14,18 @@ import javax.persistence.ManyToOne; import java.util.Objects; +import static java.util.Objects.hash; +import static java.util.Objects.isNull; +import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION; +import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_RECOMMENDED_POST_INVALID_URL_LENGTH; + @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor @Getter public class RecommendedPost { + public static final int URL_LENGTH_UPPER_BOUND = 512; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -31,6 +37,24 @@ public class RecommendedPost { @JoinColumn(nullable = false) private Keyword keyword; + public RecommendedPost(final Long id, final String url, final Keyword keyword) { + final String trimmed = url.trim(); + validate(trimmed, keyword); + + this.id = id; + this.url = trimmed; + this.keyword = keyword; + } + + private void validate(final String url, final Keyword keyword) { + if (isNull(keyword)) { + throw new BadRequestException(ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION); + } + if (url.isEmpty() || url.length() > URL_LENGTH_UPPER_BOUND) { + throw new BadRequestException(ROADMAP_RECOMMENDED_POST_INVALID_URL_LENGTH); + } + } + public RecommendedPost(final String url, final Keyword keyword) { this(null, url, keyword); } @@ -58,6 +82,6 @@ public boolean equals(final Object o) { @Override public int hashCode() { - return Objects.hash(id); + return hash(id); } } diff --git a/backend/src/test/java/wooteco/prolog/roadmap/domain/RecommendedPostTest.java b/backend/src/test/java/wooteco/prolog/roadmap/domain/RecommendedPostTest.java index 3d6909d82..5b741a807 100644 --- a/backend/src/test/java/wooteco/prolog/roadmap/domain/RecommendedPostTest.java +++ b/backend/src/test/java/wooteco/prolog/roadmap/domain/RecommendedPostTest.java @@ -2,19 +2,72 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import wooteco.prolog.common.exception.BadRequestException; + +import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION; +import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_RECOMMENDED_POST_INVALID_URL_LENGTH; class RecommendedPostTest { + @Test + @DisplayName("추천 포스트 생성 시 키워드가 null이면 예외가 발생한다") + void construct_fail1() { + assertThatThrownBy(() -> new RecommendedPost("https://example.com", null)) + .isInstanceOf(BadRequestException.class) + .hasMessage(ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION.getMessage()); + } + + @Test + @DisplayName("추천 포스트 생성 시 url의 길이가 공백 제외 0이면 예외가 발생한다") + void construct_fail2() { + //given + final String url = " "; + + //when, then + assertThatThrownBy(() -> new RecommendedPost(url, null)) + .isInstanceOf(BadRequestException.class) + .hasMessage(ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION.getMessage()); + } + + @Test + @DisplayName("추천 포스트 생성 시 url의 길이가 공백 제외 512보다 크면 예외가 발생한다") + void construct_fail3() { + //given + final Keyword keyword = Keyword.createKeyword("name", "description", 1, 1, 1L, null); + final String url = Stream.generate(() -> "a") + .limit(513) + .collect(Collectors.joining()); + + //when, then + assertThatThrownBy(() -> new RecommendedPost(url, keyword)) + .isInstanceOf(BadRequestException.class) + .hasMessage(ROADMAP_RECOMMENDED_POST_INVALID_URL_LENGTH.getMessage()); + } + + @Test + @DisplayName("추천 포스트 생성 테스트") + void construct() { + //given + final Keyword keyword = Keyword.createKeyword("name", "description", 1, 1, 1L, null); + final String url = "http://www.salmon"; + + //when, then + assertDoesNotThrow(() -> new RecommendedPost(url, keyword)); + } + @Test @DisplayName("삭제 기능 테스트") void remove() { //given final Keyword keyword = Keyword.createKeyword("이름", "설명", 1, 1, 1L, null); - final RecommendedPost recommendedPost = new RecommendedPost(1L, "https://example.com", null); - recommendedPost.addKeyword(keyword); + final RecommendedPost recommendedPost = new RecommendedPost("https://example.com", keyword); //when recommendedPost.remove();