-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[FEAT/#287] 단일 Banner 상세 조회 기능
- Loading branch information
Showing
22 changed files
with
863 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
operation-api/src/main/java/org/sopt/makers/operation/web/banner/api/BannerApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.sopt.makers.operation.web.banner.api; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
|
||
import org.sopt.makers.operation.dto.BaseResponse; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
|
||
public interface BannerApi { | ||
@Operation( | ||
summary = "배너 상세 조회 API", | ||
responses = { | ||
@ApiResponse( | ||
responseCode = "200", | ||
description = "배너 상세 조회 성공" | ||
), | ||
@ApiResponse( | ||
responseCode = "400", | ||
description = "잘못된 요청" | ||
), | ||
@ApiResponse( | ||
responseCode = "404", | ||
description = "존재하지 않는 배너 ID 요청" | ||
), | ||
@ApiResponse( | ||
responseCode = "500", | ||
description = "서버 내부 오류" | ||
) | ||
} | ||
) | ||
ResponseEntity<BaseResponse<?>> getBannerDetail(Long bannerId); | ||
|
||
} |
31 changes: 31 additions & 0 deletions
31
...ation-api/src/main/java/org/sopt/makers/operation/web/banner/api/BannerApiController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.sopt.makers.operation.web.banner.api; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.val; | ||
|
||
import org.sopt.makers.operation.dto.BaseResponse; | ||
import org.sopt.makers.operation.util.ApiResponseUtil; | ||
import org.sopt.makers.operation.web.banner.service.BannerService; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import static org.sopt.makers.operation.code.success.web.BannerSuccessCode.SUCCESS_GET_BANNER_DETAIL; | ||
|
||
@RestController | ||
@RequestMapping("/api/v1/banners") | ||
@RequiredArgsConstructor | ||
public class BannerApiController implements BannerApi { | ||
private final BannerService bannerService; | ||
|
||
@Override | ||
@GetMapping("/{bannerId}") | ||
public ResponseEntity<BaseResponse<?>> getBannerDetail( | ||
@PathVariable("bannerId") Long bannerId | ||
) { | ||
val response = bannerService.getBannerDetail(bannerId); | ||
return ApiResponseUtil.success(SUCCESS_GET_BANNER_DETAIL, response); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
...n-api/src/main/java/org/sopt/makers/operation/web/banner/dto/response/BannerResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.sopt.makers.operation.web.banner.dto.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import lombok.Builder; | ||
import lombok.RequiredArgsConstructor; | ||
import org.sopt.makers.operation.banner.domain.Banner; | ||
|
||
import java.time.LocalDate; | ||
|
||
import static lombok.AccessLevel.PRIVATE; | ||
|
||
@RequiredArgsConstructor(access = PRIVATE) | ||
public final class BannerResponse { | ||
|
||
@Builder(access = PRIVATE) | ||
public record BannerDetail( | ||
@JsonProperty("id") long bannerId, | ||
@JsonProperty("status") String bannerStatus, | ||
@JsonProperty("location") String bannerLocation, | ||
@JsonProperty("content_type") String bannerType, | ||
@JsonProperty("publisher") String publisher, | ||
@JsonProperty("start_date") LocalDate startDate, | ||
@JsonProperty("end_date") LocalDate endDate, | ||
@JsonProperty("image_url_pc") String pcImageUrl, | ||
@JsonProperty("image_url_mobile") String mobileImageUrl | ||
) { | ||
|
||
public static BannerDetail fromEntity(Banner banner) { | ||
return BannerDetail.builder() | ||
.bannerId(banner.getId()) | ||
.bannerStatus(banner.getPeriod().getPublishStatus(LocalDate.now()).getValue()) | ||
.bannerLocation(banner.getLocation().getValue()) | ||
.bannerType(banner.getContentType().getValue()) | ||
.publisher(banner.getPublisher()) | ||
.startDate(banner.getPeriod().getStartDate()) | ||
.endDate(banner.getPeriod().getEndDate()) | ||
.pcImageUrl(banner.getImage().getPcImageUrl()) | ||
.mobileImageUrl(banner.getImage().getMobileImageUrl()) | ||
.build(); | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
operation-api/src/main/java/org/sopt/makers/operation/web/banner/service/BannerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.sopt.makers.operation.web.banner.service; | ||
|
||
import org.sopt.makers.operation.web.banner.dto.response.BannerResponse; | ||
|
||
public interface BannerService { | ||
|
||
BannerResponse.BannerDetail getBannerDetail(final long bannerId); | ||
} |
28 changes: 28 additions & 0 deletions
28
...ion-api/src/main/java/org/sopt/makers/operation/web/banner/service/BannerServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.sopt.makers.operation.web.banner.service; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.val; | ||
import org.sopt.makers.operation.banner.domain.Banner; | ||
import org.sopt.makers.operation.banner.repository.BannerRepository; | ||
import org.sopt.makers.operation.code.failure.BannerFailureCode; | ||
import org.sopt.makers.operation.exception.BannerException; | ||
import org.sopt.makers.operation.web.banner.dto.response.BannerResponse; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class BannerServiceImpl implements BannerService { | ||
|
||
private final BannerRepository bannerRepository; | ||
|
||
@Override | ||
public BannerResponse.BannerDetail getBannerDetail(final long bannerId) { | ||
val banner = getBannerById(bannerId); | ||
return BannerResponse.BannerDetail.fromEntity(banner); | ||
} | ||
|
||
private Banner getBannerById(final long id) { | ||
return bannerRepository.findById(id) | ||
.orElseThrow(() -> new BannerException(BannerFailureCode.NOT_FOUNT_BANNER)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
spring: | ||
config: | ||
activate: | ||
on-profile: test | ||
datasource: | ||
username: sa | ||
password: | ||
url: jdbc:h2:mem:test;DATABASE_TO_LOWER=true # ;DATABASE_TO_UPPER=false;MODE=PostgreSQL | ||
jpa: | ||
hibernate: | ||
ddl-auto: update # create-drop 이나 create로 할경우, 자동으로 실행되는 schema & table drop 에서 DDL 오류 발생 (not exist -> not found) | ||
properties: | ||
hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect | ||
hibernate: | ||
format_sql: true | ||
show_sql: true | ||
show-sql: true | ||
generate-ddl: true | ||
jwt: | ||
secretKey: | ||
app: test | ||
access: test | ||
refresh: test | ||
platform_code: test | ||
secretKey: | ||
playground: test | ||
|
||
sopt: | ||
current: | ||
generation: 0 | ||
makers: | ||
playground: | ||
server: test | ||
token: test | ||
alarm: | ||
message: | ||
title_end: test | ||
content_end: test | ||
|
||
admin: | ||
url: | ||
prod: test | ||
dev: test | ||
local: test | ||
|
||
notification: | ||
url: test | ||
key: test | ||
arn: test | ||
|
||
oauth: | ||
apple: | ||
aud: test | ||
sub: test | ||
key: | ||
id: test | ||
path: test | ||
team: | ||
id: test | ||
google: | ||
redirect: | ||
url: test | ||
client: | ||
id: test | ||
secret: test | ||
|
||
cloud: | ||
aws: | ||
credentials: | ||
accessKey: test | ||
secretKey: test | ||
eventBridge: | ||
roleArn: test | ||
|
||
logging: | ||
level: | ||
org: | ||
hibernate: | ||
SQL: DEBUG | ||
type: | ||
descriptor: | ||
sql: trace |
84 changes: 84 additions & 0 deletions
84
...n-api/src/test/java/org/sopt/makers/operation/web/banner/api/BannerApiControllerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package org.sopt.makers.operation.web.banner.api; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
|
||
import org.sopt.makers.operation.code.success.web.BannerSuccessCode; | ||
import org.sopt.makers.operation.filter.JwtAuthenticationFilter; | ||
import org.sopt.makers.operation.filter.JwtExceptionFilter; | ||
import org.sopt.makers.operation.jwt.JwtTokenProvider; | ||
import org.sopt.makers.operation.web.banner.dto.response.BannerResponse; | ||
import org.sopt.makers.operation.web.banner.service.BannerService; | ||
|
||
import org.springframework.http.MediaType; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
import org.springframework.context.annotation.FilterType; | ||
import org.springframework.context.annotation.ComponentScan; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
|
||
import java.security.Principal; | ||
import java.time.LocalDate; | ||
|
||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
@WebMvcTest( | ||
controllers = {BannerApiController.class}, | ||
excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JwtAuthenticationFilter.class, JwtExceptionFilter.class})}, | ||
excludeAutoConfiguration = {SecurityAutoConfiguration.class, JwtTokenProvider.class} | ||
) | ||
@DisplayName("[Web Layer Test] Banner API Controller") | ||
class BannerApiControllerTest { | ||
private static final long MOCK_BANNER_ID = 1L; | ||
|
||
@MockBean | ||
private BannerService bannerService; | ||
@Autowired | ||
private MockMvc mockMvc; | ||
|
||
@BeforeEach | ||
void setMockBanner() { | ||
BannerResponse.BannerDetail mockBannerDetail = new BannerResponse.BannerDetail( | ||
MOCK_BANNER_ID, "in_progress", "pg_community", "product", "publisher", | ||
LocalDate.of(2024, 1, 1), LocalDate.of(2024, 12, 31), "image-url-pc", "image-url-mobile" | ||
); | ||
|
||
when(bannerService.getBannerDetail(MOCK_BANNER_ID)) | ||
.thenReturn(mockBannerDetail); | ||
} | ||
|
||
|
||
@Test | ||
@DisplayName("(GET) Banner Detail") | ||
void getBannerDetail() throws Exception { | ||
// given | ||
BannerResponse.BannerDetail givenBannerDetail = bannerService.getBannerDetail(MOCK_BANNER_ID); | ||
|
||
this.mockMvc.perform( | ||
// when | ||
get("/api/v1/banners/" + MOCK_BANNER_ID) | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.principal(mock(Principal.class))) | ||
// then | ||
.andExpect(status().isOk()) | ||
.andExpect(jsonPath("$.success").value("true")) | ||
.andExpect(jsonPath("$.message").value(BannerSuccessCode.SUCCESS_GET_BANNER_DETAIL.getMessage())) | ||
.andExpect(jsonPath("$.data.id").value(givenBannerDetail.bannerId())) | ||
.andExpect(jsonPath("$.data.status").value(givenBannerDetail.bannerStatus())) | ||
.andExpect(jsonPath("$.data.location").value(givenBannerDetail.bannerLocation())) | ||
.andExpect(jsonPath("$.data.content_type").value(givenBannerDetail.bannerType())) | ||
.andExpect(jsonPath("$.data.publisher").value(givenBannerDetail.publisher())) | ||
.andExpect(jsonPath("$.data.start_date").value(givenBannerDetail.startDate().toString())) | ||
.andExpect(jsonPath("$.data.end_date").value(givenBannerDetail.endDate().toString())) | ||
.andExpect(jsonPath("$.data.image_url_pc").value(givenBannerDetail.pcImageUrl())) | ||
.andExpect(jsonPath("$.data.image_url_mobile").value(givenBannerDetail.mobileImageUrl())); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
operation-common/src/main/java/org/sopt/makers/operation/code/failure/BannerFailureCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.sopt.makers.operation.code.failure; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpStatus; | ||
|
||
import static org.springframework.http.HttpStatus.NOT_FOUND; | ||
|
||
@RequiredArgsConstructor | ||
@Getter | ||
public enum BannerFailureCode implements FailureCode { | ||
NOT_FOUND_STATUS(NOT_FOUND, "존재하지 않는 게시 상태입니다."), | ||
NOT_FOUND_LOCATION(NOT_FOUND, "존재하지 않는 게시 위치입니다."), | ||
NOT_FOUND_CONTENT_TYPE(NOT_FOUND, "존재하지 않는 게시 유형입니다."), | ||
NOT_FOUNT_BANNER(NOT_FOUND, "존재하지 않는 배너입니다."), | ||
; | ||
|
||
private final HttpStatus status; | ||
private final String message; | ||
} |
18 changes: 18 additions & 0 deletions
18
...on-common/src/main/java/org/sopt/makers/operation/code/success/web/BannerSuccessCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.sopt.makers.operation.code.success.web; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.sopt.makers.operation.code.success.SuccessCode; | ||
import org.springframework.http.HttpStatus; | ||
|
||
import static lombok.AccessLevel.PRIVATE; | ||
|
||
@Getter | ||
@RequiredArgsConstructor(access = PRIVATE) | ||
public enum BannerSuccessCode implements SuccessCode { | ||
SUCCESS_GET_BANNER_DETAIL(HttpStatus.OK, "배너 상세 정보 조회 성공"), | ||
; | ||
|
||
private final HttpStatus status; | ||
private final String message; | ||
} |
15 changes: 15 additions & 0 deletions
15
operation-common/src/main/java/org/sopt/makers/operation/exception/BannerException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.sopt.makers.operation.exception; | ||
|
||
import lombok.Getter; | ||
import org.sopt.makers.operation.code.failure.FailureCode; | ||
|
||
@Getter | ||
public class BannerException extends RuntimeException { | ||
private final FailureCode failureCode; | ||
|
||
public BannerException(FailureCode failureCode) { | ||
super("[BannerException] : " + failureCode.getMessage()); | ||
this.failureCode = failureCode; | ||
} | ||
|
||
} |
Oops, something went wrong.