diff --git a/src/main/java/org/myteam/server/comment/service/CommentService.java b/src/main/java/org/myteam/server/comment/service/CommentService.java index 610297a7..66820b7f 100644 --- a/src/main/java/org/myteam/server/comment/service/CommentService.java +++ b/src/main/java/org/myteam/server/comment/service/CommentService.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.UUID; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.myteam.server.comment.domain.Comment; @@ -17,9 +16,9 @@ import org.myteam.server.common.filter.util.BadWordFilter; import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; -import org.myteam.server.global.util.redis.service.RedisCountService; +import org.myteam.server.global.util.media.MediaUtils; import org.myteam.server.global.util.redis.ServiceType; -import org.myteam.server.global.util.upload.MediaUtils; +import org.myteam.server.global.util.redis.service.RedisCountService; import org.myteam.server.member.entity.Member; import org.myteam.server.member.repository.MemberJpaRepository; import org.myteam.server.member.service.SecurityReadService; diff --git a/src/main/java/org/myteam/server/global/util/upload/MediaUtils.java b/src/main/java/org/myteam/server/global/util/media/MediaUtils.java similarity index 95% rename from src/main/java/org/myteam/server/global/util/upload/MediaUtils.java rename to src/main/java/org/myteam/server/global/util/media/MediaUtils.java index 81347dec..7278eead 100644 --- a/src/main/java/org/myteam/server/global/util/upload/MediaUtils.java +++ b/src/main/java/org/myteam/server/global/util/media/MediaUtils.java @@ -1,4 +1,4 @@ -package org.myteam.server.global.util.upload; +package org.myteam.server.global.util.media; import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; diff --git a/src/main/java/org/myteam/server/global/util/media/ThumbnailUrlUtils.java b/src/main/java/org/myteam/server/global/util/media/ThumbnailUrlUtils.java new file mode 100644 index 00000000..be9f1944 --- /dev/null +++ b/src/main/java/org/myteam/server/global/util/media/ThumbnailUrlUtils.java @@ -0,0 +1,44 @@ +package org.myteam.server.global.util.media; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import org.myteam.server.global.domain.Category; + +/** + * 크롤링 된 뉴스 이미지 썸네일 url을 디코딩 + */ +public class ThumbnailUrlUtils { + + public static String extractCleanThumbImg(String thumbImg, Category category) { + if (thumbImg == null || category == null) { + return thumbImg; + } + + // BASEBALL, FOOTBALL만 디코딩 대상 + if (category == Category.BASEBALL || category == Category.FOOTBALL) { + + // dthumb URL 안에 src 파라미터가 있는 경우만 추출 + if (thumbImg.contains("src=")) { + try { + // src=...& 이전까지만 추출 + String encodedSrc = thumbImg.split("src=")[1].split("&")[0]; + return URLDecoder.decode(encodedSrc, StandardCharsets.UTF_8) + .replace("\"", ""); + } catch (Exception e) { + return thumbImg; // 실패 시 원본 그대로 + } + } + + // src 파라미터 없으면 원본 그대로 + return thumbImg; + } + + // BASEBALL, FOOTBALL이 아닌 경우 → ? 뒤 제거 + int questionMarkIndex = thumbImg.indexOf('?'); + if (questionMarkIndex != -1) { + return thumbImg.substring(0, questionMarkIndex); + } + + return thumbImg; + } +} \ No newline at end of file diff --git a/src/main/java/org/myteam/server/improvement/service/ImprovementService.java b/src/main/java/org/myteam/server/improvement/service/ImprovementService.java index a1df4111..c6244357 100644 --- a/src/main/java/org/myteam/server/improvement/service/ImprovementService.java +++ b/src/main/java/org/myteam/server/improvement/service/ImprovementService.java @@ -6,10 +6,10 @@ import org.myteam.server.comment.service.CommentService; import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; +import org.myteam.server.global.util.media.MediaUtils; import org.myteam.server.global.util.redis.CommonCountDto; -import org.myteam.server.global.util.redis.service.RedisCountService; import org.myteam.server.global.util.redis.ServiceType; -import org.myteam.server.global.util.upload.MediaUtils; +import org.myteam.server.global.util.redis.service.RedisCountService; import org.myteam.server.improvement.domain.Improvement; import org.myteam.server.improvement.domain.ImprovementCount; import org.myteam.server.improvement.domain.ImprovementStatus; diff --git a/src/main/java/org/myteam/server/news/news/dto/repository/NewsDto.java b/src/main/java/org/myteam/server/news/news/dto/repository/NewsDto.java index b60dbc9f..8ae223d6 100644 --- a/src/main/java/org/myteam/server/news/news/dto/repository/NewsDto.java +++ b/src/main/java/org/myteam/server/news/news/dto/repository/NewsDto.java @@ -1,55 +1,56 @@ package org.myteam.server.news.news.dto.repository; -import java.time.LocalDateTime; +import static org.myteam.server.global.util.media.ThumbnailUrlUtils.extractCleanThumbImg; import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.Setter; -import org.myteam.server.board.dto.reponse.CommentSearchDto; -import org.myteam.server.global.domain.Category; - import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDateTime; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; +import org.myteam.server.board.dto.reponse.CommentSearchDto; +import org.myteam.server.global.domain.Category; @Getter @NoArgsConstructor public class NewsDto { - @Schema(description = "뉴스 ID") - private Long id; - @Schema(description = "뉴스 카테고리") - private Category category; - @Schema(description = "뉴스 제목") - private String title; - @Schema(description = "뉴스 썸네일 이미지") - private String thumbImg; - @Schema(description = "뉴스 본문") - private String content; - @Schema(description = "뉴스 댓글 수") - private int commentCount; - @Schema(description = "뉴스 계시 날짜") - private LocalDateTime postDate; - @Schema(description = "댓글 검색 시 최상단 댓글 데이터") - private NewsCommentSearchDto newsCommentSearchDto; - @Schema(description = "Hot 계시물 여부") - private boolean isHot; - - @Setter - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private CommentSearchDto commentSearchList; - - public NewsDto(Long id, Category category, String title, String thumbImg, String content, int commentCount, LocalDateTime postDate, boolean isHot) { - this.id = id; - this.category = category; - this.title = title; - this.thumbImg = thumbImg; - this.content = content; - this.commentCount = commentCount; - this.postDate = postDate; - this.isHot = isHot; - } - - public void updateNewsCommentSearchDto(NewsCommentSearchDto newsCommentSearchDto){ - this.newsCommentSearchDto = newsCommentSearchDto; - } + @Schema(description = "뉴스 ID") + private Long id; + @Schema(description = "뉴스 카테고리") + private Category category; + @Schema(description = "뉴스 제목") + private String title; + @Schema(description = "뉴스 썸네일 이미지") + private String thumbImg; + @Schema(description = "뉴스 본문") + private String content; + @Schema(description = "뉴스 댓글 수") + private int commentCount; + @Schema(description = "뉴스 계시 날짜") + private LocalDateTime postDate; + @Schema(description = "댓글 검색 시 최상단 댓글 데이터") + private NewsCommentSearchDto newsCommentSearchDto; + @Schema(description = "Hot 계시물 여부") + private boolean isHot; + + @Setter + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private CommentSearchDto commentSearchList; + + public NewsDto(Long id, Category category, String title, String thumbImg, String content, int commentCount, + LocalDateTime postDate, boolean isHot) { + this.id = id; + this.category = category; + this.title = title; + this.thumbImg = extractCleanThumbImg(thumbImg, category); + this.content = content; + this.commentCount = commentCount; + this.postDate = postDate; + this.isHot = isHot; + } + + public void updateNewsCommentSearchDto(NewsCommentSearchDto newsCommentSearchDto) { + this.newsCommentSearchDto = newsCommentSearchDto; + } } diff --git a/src/main/java/org/myteam/server/news/news/dto/service/response/NewsResponse.java b/src/main/java/org/myteam/server/news/news/dto/service/response/NewsResponse.java index 1a47a6b0..e62efb15 100644 --- a/src/main/java/org/myteam/server/news/news/dto/service/response/NewsResponse.java +++ b/src/main/java/org/myteam/server/news/news/dto/service/response/NewsResponse.java @@ -1,5 +1,7 @@ package org.myteam.server.news.news.dto.service.response; +import static org.myteam.server.global.util.media.ThumbnailUrlUtils.extractCleanThumbImg; + import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import lombok.Builder; @@ -61,11 +63,12 @@ public NewsResponse(Long id, Category category, String title, String thumbImg, C public static NewsResponse createResponse(News news, boolean isRecommend, Long previousId, Long nextId, CommonCountDto commonCountDto) { + return NewsResponse.builder() .id(news.getId()) .category(news.getCategory()) .title(news.getTitle()) - .thumbImg(news.getThumbImg()) + .thumbImg(extractCleanThumbImg(news.getThumbImg(), news.getCategory())) .postDate(news.getPostDate()) .commonCountDto(commonCountDto) .isRecommend(isRecommend) diff --git a/src/main/java/org/myteam/server/notice/service/NoticeService.java b/src/main/java/org/myteam/server/notice/service/NoticeService.java index b5e8f9c1..5c2e6c73 100644 --- a/src/main/java/org/myteam/server/notice/service/NoticeService.java +++ b/src/main/java/org/myteam/server/notice/service/NoticeService.java @@ -7,10 +7,10 @@ import org.myteam.server.comment.service.CommentService; import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; +import org.myteam.server.global.util.media.MediaUtils; import org.myteam.server.global.util.redis.CommonCountDto; import org.myteam.server.global.util.redis.ServiceType; import org.myteam.server.global.util.redis.service.RedisCountService; -import org.myteam.server.global.util.upload.MediaUtils; import org.myteam.server.member.entity.Member; import org.myteam.server.member.service.SecurityReadService; import org.myteam.server.notice.domain.Notice; diff --git a/src/test/java/org/myteam/server/comment/service/CommentDeleteServiceTest.java b/src/test/java/org/myteam/server/comment/service/CommentDeleteServiceTest.java index d3fc1f6b..f11e0162 100644 --- a/src/test/java/org/myteam/server/comment/service/CommentDeleteServiceTest.java +++ b/src/test/java/org/myteam/server/comment/service/CommentDeleteServiceTest.java @@ -1,40 +1,43 @@ package org.myteam.server.comment.service; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; -import org.myteam.server.support.IntegrationTestSupport; import org.myteam.server.board.domain.Board; import org.myteam.server.board.domain.CategoryType; import org.myteam.server.comment.domain.Comment; import org.myteam.server.comment.domain.CommentType; -import org.myteam.server.comment.dto.request.CommentRequest.*; +import org.myteam.server.comment.dto.request.CommentRequest.CommentDeleteRequest; import org.myteam.server.global.domain.Category; import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; +import org.myteam.server.global.util.media.MediaUtils; import org.myteam.server.global.util.redis.CommonCountDto; import org.myteam.server.global.util.redis.ServiceType; -import org.myteam.server.global.util.upload.MediaUtils; import org.myteam.server.match.match.domain.Match; import org.myteam.server.match.match.domain.MatchCategory; import org.myteam.server.match.team.domain.Team; import org.myteam.server.match.team.domain.TeamCategory; import org.myteam.server.member.entity.Member; import org.myteam.server.report.domain.DomainType; +import org.myteam.server.support.IntegrationTestSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import static org.assertj.core.api.Assertions.*; - -import static org.mockito.Mockito.*; - -class CommentDeleteServiceTest extends IntegrationTestSupport { +class CommentDeleteServiceTest extends IntegrationTestSupport { @Autowired private CommentService commentService; diff --git a/src/test/java/org/myteam/server/improvement/service/ImprovementUpdateServiceTest.java b/src/test/java/org/myteam/server/improvement/service/ImprovementUpdateServiceTest.java index 61146424..4026a234 100644 --- a/src/test/java/org/myteam/server/improvement/service/ImprovementUpdateServiceTest.java +++ b/src/test/java/org/myteam/server/improvement/service/ImprovementUpdateServiceTest.java @@ -1,33 +1,32 @@ package org.myteam.server.improvement.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; -import org.myteam.server.support.IntegrationTestSupport; import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; +import org.myteam.server.global.util.media.MediaUtils; import org.myteam.server.global.util.redis.CommonCountDto; import org.myteam.server.global.util.redis.ServiceType; -import org.myteam.server.global.util.upload.MediaUtils; import org.myteam.server.improvement.domain.Improvement; import org.myteam.server.improvement.domain.ImprovementStatus; -import org.myteam.server.improvement.dto.request.ImprovementRequest.*; -import org.myteam.server.improvement.dto.response.ImprovementResponse.*; +import org.myteam.server.improvement.dto.request.ImprovementRequest.ImprovementSaveRequest; +import org.myteam.server.improvement.dto.response.ImprovementResponse.ImprovementSaveResponse; import org.myteam.server.member.entity.Member; import org.myteam.server.report.domain.DomainType; +import org.myteam.server.support.IntegrationTestSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.*; - class ImprovementUpdateServiceTest extends IntegrationTestSupport { @Autowired @@ -121,7 +120,8 @@ void updateImprovement_image_changed() { ); try (MockedStatic utilities = mockStatic(MediaUtils.class)) { - utilities.when(() -> MediaUtils.verifyImageUrlAndRequestImageUrl(improvement.getImgUrl(), request.getImgUrl())) + utilities.when( + () -> MediaUtils.verifyImageUrlAndRequestImageUrl(improvement.getImgUrl(), request.getImgUrl())) .thenReturn(true); // when