Compare commits

..

3 Commits

Author SHA1 Message Date
dongHyo
d0ef6e7e89 refactor: 피드백 반영 2022-07-17 20:52:30 +09:00
dongHyo
123774e06f feat: 관리자 환불 구현 2022-07-15 17:40:00 +09:00
dongHyo
78d6f1a98c feat: 본인결제내역 환불 구현 2022-07-15 17:15:06 +09:00
30 changed files with 181 additions and 575 deletions

View File

@@ -91,7 +91,7 @@ erDiagram
bigint seat_id FK "좌석 ID" bigint seat_id FK "좌석 ID"
bigint movie_time_id FK "상영시간표 ID" bigint movie_time_id FK "상영시간표 ID"
bigint payment_id "결제 ID" bigint payment_id "결제 ID"
varchar status "상태 - 매가능/예약/" varchar status "상태 - 매가능/예약진행중/판매완료"
int ticket_price "가격" int ticket_price "가격"
datetime deleted_at "삭제일시" datetime deleted_at "삭제일시"
datetime created_at "등록일시" datetime created_at "등록일시"
@@ -101,11 +101,10 @@ erDiagram
PAYMENT { PAYMENT {
bigint id PK "결제 ID" bigint id PK "결제 ID"
bigint user_alternate_id "유저 대체ID" bigint user_alternate_id "유저 대체ID"
varchar tid "카카오페이 결제고유번호"
varchar movie_title "영화제목" varchar movie_title "영화제목"
varchar type "결제 타입 - 예) 네이버페이, 카카오페이" varchar type "결제 타입 - 예) 네이버페이, 카카오페이"
varchar status "상태 - 완료/환불" varchar status "상태 - 완료/환불/실패"
varchar failed_message "실패사유" varchar failed_message "실패사유 - 컬럼명을 알아보기 쉬운가?"
varchar payment_number "예매번호" varchar payment_number "예매번호"
int total_price "결제 금액" int total_price "결제 금액"
datetime deleted_at "삭제일시" datetime deleted_at "삭제일시"

View File

@@ -1,15 +0,0 @@
package com.ticketing.server.global.config;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.springframework.security.test.context.support.WithSecurityContext;
@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithAuthUserSecurityContextFactory.class)
public @interface WithAuthUser {
String email();
String role();
}

View File

@@ -1,27 +0,0 @@
package com.ticketing.server.global.config;
import java.util.List;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.test.context.support.WithSecurityContextFactory;
public class WithAuthUserSecurityContextFactory implements WithSecurityContextFactory<WithAuthUser> {
@Override
public SecurityContext createSecurityContext(WithAuthUser annotation) {
String email = annotation.email();
String role = annotation.role();
List<SimpleGrantedAuthority> authorities = List.of(new SimpleGrantedAuthority(role));
User authUser = new User(email, "", authorities);
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(authUser, "", authorities);
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(token);
return context;
}
}

View File

@@ -1,242 +1,7 @@
package com.ticketing.server.user.application; package com.ticketing.server.user.application;
import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ticketing.server.global.config.WithAuthUser;
import com.ticketing.server.user.application.request.LoginRequest;
import com.ticketing.server.user.application.request.SignUpRequest;
import com.ticketing.server.user.application.request.UserChangeGradeRequest;
import com.ticketing.server.user.application.request.UserChangePasswordRequest;
import com.ticketing.server.user.application.request.UserDeleteRequest;
import com.ticketing.server.user.domain.UserGrade;
import com.ticketing.server.user.domain.UserGrade.ROLES;
import com.ticketing.server.user.domain.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Transactional
class UserControllerTest { class UserControllerTest {
private static final String LOGIN_URL = "/api/auth/token";
private static final String BASICS_URL = "/api/users";
private static final String DETAILS_URL = "/api/users/details";
private static final String CHANGE_PASSWORD_URL = "/api/users/password";
private static final String CHANGE_GRADE_URL = "/api/users/grade";
private static final String NAME = "$.name";
private static final String EMAIL = "$.email";
private static final String GRADE = "$.grade";
private static final String PHONE = "$.phone";
private static final String BEFORE_GRADE = "$.beforeGrade";
private static final String AFTER_GRADE = "$.afterGrade";
private static final String USER_EMAIL = "testemail@ticketing.com";
private static final String USER_PW = "qwe123";
private static final String USER_NAME = "김철수";
private static final String USER_PHONE = "010-1234-5678";
@Autowired
UserRepository userRepository;
@Autowired
ObjectMapper mapper;
@Autowired
WebApplicationContext context;
MockMvc mvc;
SignUpRequest signUpRequest;
@Test
@DisplayName("회원가입 성공")
void registerSuccess() throws Exception {
// given
// when
ResultActions resultActions = mvc.perform(
post(BASICS_URL)
.content(mapper.writeValueAsString(signUpRequest))
.contentType(APPLICATION_JSON)
);
// then
resultActions
.andExpect(status().isCreated())
.andExpect(content().contentType(APPLICATION_JSON))
.andExpect(jsonPath(NAME).value(USER_NAME))
.andExpect(jsonPath(EMAIL).value(USER_EMAIL));
}
@Test
@DisplayName("유저 정보 조회")
@WithAuthUser(email = USER_EMAIL, role = ROLES.USER)
void detailsSuccess() throws Exception {
// given
mvc.perform(
post(BASICS_URL)
.content(mapper.writeValueAsString(signUpRequest))
.contentType(APPLICATION_JSON)
);
// when
ResultActions resultActions = mvc.perform(
get(DETAILS_URL)
.content(mapper.writeValueAsString(signUpRequest))
.contentType(APPLICATION_JSON)
);
// then
resultActions
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON))
.andExpect(jsonPath(NAME).value(USER_NAME))
.andExpect(jsonPath(EMAIL).value(USER_EMAIL))
.andExpect(jsonPath(GRADE).value(UserGrade.USER.name()))
.andExpect(jsonPath(PHONE).value(USER_PHONE));
}
@Test
@DisplayName("유저 탈퇴 성공")
@WithAuthUser(email = USER_EMAIL, role = ROLES.USER)
void deleteUserSuccess() throws Exception {
// given
UserDeleteRequest deleteRequest = new UserDeleteRequest(USER_EMAIL, USER_PW);
LoginRequest loginRequest = new LoginRequest(USER_EMAIL, USER_PW);
mvc.perform(
post(BASICS_URL)
.content(mapper.writeValueAsString(signUpRequest))
.contentType(APPLICATION_JSON)
);
// when
// 1. 회원 탈퇴 진행
mvc.perform(
delete(BASICS_URL)
.content(mapper.writeValueAsString(deleteRequest))
.contentType(APPLICATION_JSON)
);
// 2. 탈퇴된 계정 로그인
ResultActions resultActions = mvc.perform(post(LOGIN_URL)
.content(mapper.writeValueAsString(loginRequest))
.contentType(MediaType.APPLICATION_JSON));
// then
resultActions
.andExpect(status().isUnauthorized());
}
@Test
@DisplayName("비밀번호 변경 성공")
@WithAuthUser(email = USER_EMAIL, role = ROLES.USER)
void changePasswordSuccess() throws Exception {
// given
UserChangePasswordRequest changePasswordRequest = new UserChangePasswordRequest(USER_PW, "qwe1234");
LoginRequest loginRequest = new LoginRequest(USER_EMAIL, USER_PW);
mvc.perform(
post(BASICS_URL)
.content(mapper.writeValueAsString(this.signUpRequest))
.contentType(APPLICATION_JSON)
);
// when
// 1. 패스워드 변경
mvc.perform(
put(CHANGE_PASSWORD_URL)
.content(mapper.writeValueAsString(changePasswordRequest))
.contentType(APPLICATION_JSON)
)
.andExpect(status().isOk());
// 2. 변경 전 계정으로 로그인
ResultActions resultActions = mvc.perform(post(LOGIN_URL)
.content(mapper.writeValueAsString(loginRequest))
.contentType(MediaType.APPLICATION_JSON));
// then
resultActions
.andExpect(status().isUnauthorized());
}
@Test
@DisplayName("유저 등급 변경")
@WithAuthUser(email = "admin@ticketing.com", role = ROLES.ADMIN)
void changeGradeSuccess() throws Exception {
// given
UserChangeGradeRequest changeGradeRequest = new UserChangeGradeRequest(USER_EMAIL, UserGrade.STAFF);
mvc.perform(
post(BASICS_URL)
.content(mapper.writeValueAsString(signUpRequest))
.contentType(APPLICATION_JSON)
);
// when
ResultActions resultActions = mvc.perform(
post(CHANGE_GRADE_URL)
.content(mapper.writeValueAsString(changeGradeRequest))
.contentType(APPLICATION_JSON)
);
// then
resultActions
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON))
.andExpect(jsonPath(EMAIL).value(USER_EMAIL))
.andExpect(jsonPath(BEFORE_GRADE).value(UserGrade.USER.name()))
.andExpect(jsonPath(AFTER_GRADE).value(UserGrade.STAFF.name()));
}
@Test
@DisplayName("유저 등급 변경 실패 - 권한 등급이 낮을 경우")
@WithAuthUser(email = "staff@ticketing.com", role = ROLES.STAFF)
void changeGradeFail() throws Exception {
// given
UserChangeGradeRequest changeGradeRequest = new UserChangeGradeRequest(USER_EMAIL, UserGrade.STAFF);
// when
ResultActions resultActions = mvc.perform(
post(CHANGE_GRADE_URL)
.content(mapper.writeValueAsString(changeGradeRequest))
.contentType(APPLICATION_JSON)
);
// then
resultActions
.andExpect(status().isForbidden());
}
@BeforeEach
void init() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
signUpRequest = new SignUpRequest(USER_NAME, USER_EMAIL, USER_PW, USER_PHONE);
}
} }

View File

@@ -20,9 +20,6 @@ spring:
pathmatch: pathmatch:
matching-strategy: ant_path_matcher matching-strategy: ant_path_matcher
config:
import: "optional:configserver:"
jasypt: jasypt:
encryptor: encryptor:
bean: jasyptStringEncryptor bean: jasyptStringEncryptor

View File

@@ -21,7 +21,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError; import org.springframework.validation.ObjectError;
@@ -212,17 +211,6 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response); return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
} }
/**
* 이메일이 존재하지 않을 경우
*/
@ExceptionHandler(value = BadCredentialsException.class)
protected ResponseEntity<ErrorResponse> handleBadCredentialsException(BadCredentialsException ex) {
log.error("BadCredentialsException :: ", ex);
ErrorResponse response = new ErrorResponse(UNAUTHORIZED, ex.getLocalizedMessage(), "아이디 혹은 패스워드가 일치하지 않습니다.");
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
}
/** /**
* 인증 정보가 없을 때 * 인증 정보가 없을 때
*/ */

View File

@@ -8,12 +8,11 @@ import com.ticketing.server.movie.application.response.MovieDeleteResponse;
import com.ticketing.server.movie.application.response.MovieListResponse; import com.ticketing.server.movie.application.response.MovieListResponse;
import com.ticketing.server.movie.application.response.MovieInfoResponse; import com.ticketing.server.movie.application.response.MovieInfoResponse;
import com.ticketing.server.movie.service.dto.DeletedMovieDTO; import com.ticketing.server.movie.service.dto.DeletedMovieDTO;
import com.ticketing.server.movie.service.dto.MovieDTO; import com.ticketing.server.movie.service.dto.MovieListDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieDTO; import com.ticketing.server.movie.service.dto.RegisteredMovieDTO;
import com.ticketing.server.movie.service.interfaces.MovieService; import com.ticketing.server.movie.service.interfaces.MovieService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.util.List;
import javax.validation.Valid; import javax.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -52,11 +51,11 @@ public class MovieController {
@GetMapping() @GetMapping()
@ApiOperation(value = "영화 목록 조회") @ApiOperation(value = "영화 목록 조회")
public ResponseEntity<MovieListResponse> getMovies() { public ResponseEntity<MovieListResponse> getMovies() {
List<MovieDTO> movieDtos = movieService.getMovies(); MovieListDTO movieListDto = movieService.getMovies();
return ResponseEntity.status(HttpStatus.OK) return ResponseEntity.status(HttpStatus.OK)
.body( .body(
new MovieListResponse(movieDtos) movieListDto.toResponse()
); );
} }

View File

@@ -5,14 +5,13 @@ import static com.ticketing.server.user.domain.UserGrade.ROLES.STAFF;
import com.ticketing.server.movie.application.request.MovieTimeRegisterRequest; import com.ticketing.server.movie.application.request.MovieTimeRegisterRequest;
import com.ticketing.server.movie.application.response.MovieTimeInfoResponse; import com.ticketing.server.movie.application.response.MovieTimeInfoResponse;
import com.ticketing.server.movie.application.response.MovieTimeListResponse; import com.ticketing.server.movie.application.response.MovieTimeListResponse;
import com.ticketing.server.movie.service.dto.MovieTimeDTO; import com.ticketing.server.movie.service.dto.MovieTimeListDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieTimeDTO; import com.ticketing.server.movie.service.dto.RegisteredMovieTimeDTO;
import com.ticketing.server.movie.service.interfaces.MovieTimeService; import com.ticketing.server.movie.service.interfaces.MovieTimeService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -59,11 +58,11 @@ public class MovieTimeController {
public ResponseEntity<MovieTimeListResponse> getMovieTimes( public ResponseEntity<MovieTimeListResponse> getMovieTimes(
@ApiParam(value = "영화 ID", required = true) @RequestParam @NotNull Long movieId, @ApiParam(value = "영화 ID", required = true) @RequestParam @NotNull Long movieId,
@ApiParam(value = "상영 날짜", required = true) @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate runningDate) { @ApiParam(value = "상영 날짜", required = true) @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate runningDate) {
List<MovieTimeDTO> movieTimeDtos = movieTimeService.getMovieTimes(movieId, runningDate); MovieTimeListDTO movieTimeListDto = movieTimeService.getMovieTimes(movieId, runningDate);
return ResponseEntity.status(HttpStatus.OK) return ResponseEntity.status(HttpStatus.OK)
.body( .body(
new MovieTimeListResponse(movieTimeDtos) movieTimeListDto.toResponse()
); );
} }

View File

@@ -4,11 +4,10 @@ import static com.ticketing.server.user.domain.UserGrade.ROLES.USER;
import com.ticketing.server.movie.application.response.TicketDetailsResponse; import com.ticketing.server.movie.application.response.TicketDetailsResponse;
import com.ticketing.server.movie.application.response.TicketListResponse; import com.ticketing.server.movie.application.response.TicketListResponse;
import com.ticketing.server.movie.service.dto.TicketDTO; import com.ticketing.server.movie.service.dto.TicketDetailsDTO;
import com.ticketing.server.movie.service.dto.TicketListDTO;
import com.ticketing.server.movie.service.interfaces.TicketService; import com.ticketing.server.movie.service.interfaces.TicketService;
import com.ticketing.server.payment.service.dto.TicketDetailDTO;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import java.util.List;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@@ -33,11 +32,11 @@ public class TicketController {
@Secured(USER) @Secured(USER)
public ResponseEntity<TicketListResponse> getTickets( public ResponseEntity<TicketListResponse> getTickets(
@ApiParam(value = "영화 시간표 ID", required = true) @RequestParam @NotNull Long movieTimeId) { @ApiParam(value = "영화 시간표 ID", required = true) @RequestParam @NotNull Long movieTimeId) {
List<TicketDTO> tickets = ticketService.getTickets(movieTimeId); TicketListDTO ticketListDto = ticketService.getTickets(movieTimeId);
return ResponseEntity.status(HttpStatus.OK) return ResponseEntity.status(HttpStatus.OK)
.body( .body(
new TicketListResponse(tickets) ticketListDto.toResponse()
); );
} }
@@ -45,11 +44,11 @@ public class TicketController {
@Secured(USER) @Secured(USER)
public ResponseEntity<TicketDetailsResponse> findTicketsByPaymentId( public ResponseEntity<TicketDetailsResponse> findTicketsByPaymentId(
@PathVariable("paymentId") @NotNull Long paymentId) { @PathVariable("paymentId") @NotNull Long paymentId) {
List<TicketDetailDTO> tickets = ticketService.findTicketsByPaymentId(paymentId); TicketDetailsDTO tickets = ticketService.findTicketsByPaymentId(paymentId);
return ResponseEntity.status(HttpStatus.OK) return ResponseEntity.status(HttpStatus.OK)
.body( .body(
new TicketDetailsResponse(tickets) tickets.toResponse()
); );
} }

View File

@@ -1,6 +1,7 @@
package com.ticketing.server.movie.domain.repository; package com.ticketing.server.movie.domain.repository;
import com.ticketing.server.movie.domain.Movie; import com.ticketing.server.movie.domain.Movie;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
@@ -16,8 +17,8 @@ public interface MovieRepository extends JpaRepository<Movie, Long> {
@Query(value = "SELECT m " @Query(value = "SELECT m "
+ "FROM Movie m " + "FROM Movie m "
+ "WHERE m.title = :title " + "WHERE title = :title "
+ "AND m.deletedAt IS NULL") + "AND deleted_at IS NULL")
Optional<Movie> findValidMovieWithTitle(String title); Optional<Movie> findValidMovieWithTitle(String title);
@Query(value = "SELECT * " @Query(value = "SELECT * "

View File

@@ -5,6 +5,7 @@ import com.ticketing.server.movie.domain.Movie;
import com.ticketing.server.movie.domain.repository.MovieRepository; import com.ticketing.server.movie.domain.repository.MovieRepository;
import com.ticketing.server.movie.service.dto.DeletedMovieDTO; import com.ticketing.server.movie.service.dto.DeletedMovieDTO;
import com.ticketing.server.movie.service.dto.MovieDTO; import com.ticketing.server.movie.service.dto.MovieDTO;
import com.ticketing.server.movie.service.dto.MovieListDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieDTO; import com.ticketing.server.movie.service.dto.RegisteredMovieDTO;
import com.ticketing.server.movie.service.interfaces.MovieService; import com.ticketing.server.movie.service.interfaces.MovieService;
import java.util.List; import java.util.List;
@@ -38,12 +39,14 @@ public class MovieServiceImpl implements MovieService {
} }
@Override @Override
public List<MovieDTO> getMovies() { public MovieListDTO getMovies() {
List<Movie> movies = movieRepository.findValidMovies(); List<Movie> movies = movieRepository.findValidMovies();
return movies.stream() List<MovieDTO> movieDtos = movies.stream()
.map(movie -> movie.toMovieDTO()) .map(movie -> movie.toMovieDTO())
.collect(Collectors.toList()); .collect(Collectors.toList());
return new MovieListDTO(movieDtos);
} }
@Override @Override

View File

@@ -8,7 +8,9 @@ import com.ticketing.server.movie.domain.repository.MovieRepository;
import com.ticketing.server.movie.domain.repository.MovieTimeRepository; import com.ticketing.server.movie.domain.repository.MovieTimeRepository;
import com.ticketing.server.movie.domain.repository.TheaterRepository; import com.ticketing.server.movie.domain.repository.TheaterRepository;
import com.ticketing.server.movie.service.dto.MovieTimeDTO; import com.ticketing.server.movie.service.dto.MovieTimeDTO;
import com.ticketing.server.movie.service.dto.MovieTimeListDTO;
import com.ticketing.server.movie.service.dto.MovieTimeRegisterDTO; import com.ticketing.server.movie.service.dto.MovieTimeRegisterDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieTimeDTO; import com.ticketing.server.movie.service.dto.RegisteredMovieTimeDTO;
import com.ticketing.server.movie.service.interfaces.MovieTimeService; import com.ticketing.server.movie.service.interfaces.MovieTimeService;
import java.time.LocalDate; import java.time.LocalDate;
@@ -54,7 +56,7 @@ public class MovieTimeServiceImpl implements MovieTimeService {
} }
@Override @Override
public List<MovieTimeDTO> getMovieTimes(Long movieId, LocalDate runningDate) { public MovieTimeListDTO getMovieTimes(Long movieId, LocalDate runningDate) {
Movie movie = findMovieById(movieId); Movie movie = findMovieById(movieId);
LocalDateTime startOfDay = runningDate.atStartOfDay().plusHours(6); LocalDateTime startOfDay = runningDate.atStartOfDay().plusHours(6);
@@ -62,9 +64,11 @@ public class MovieTimeServiceImpl implements MovieTimeService {
List<MovieTime> movieTimes = movieTimeRepository.findValidMovieTimes(movie, startOfDay, endOfDay); List<MovieTime> movieTimes = movieTimeRepository.findValidMovieTimes(movie, startOfDay, endOfDay);
return movieTimes.stream() List<MovieTimeDTO> movieTimeDtos = movieTimes.stream()
.map(movieTime -> movieTime.toMovieTimeDTO()) .map(movieTime -> movieTime.toMovieTimeDTO())
.collect(Collectors.toList()); .collect(Collectors.toList());
return new MovieTimeListDTO(movieTimeDtos);
} }
@Override @Override

View File

@@ -1,21 +1,26 @@
package com.ticketing.server.movie.service; package com.ticketing.server.movie.service;
import com.ticketing.server.global.exception.ErrorCode; import com.ticketing.server.global.exception.ErrorCode;
import com.ticketing.server.global.validator.constraints.NotEmptyCollection;
import com.ticketing.server.movie.domain.MovieTime; import com.ticketing.server.movie.domain.MovieTime;
import com.ticketing.server.movie.domain.Ticket;
import com.ticketing.server.movie.domain.repository.MovieTimeRepository; import com.ticketing.server.movie.domain.repository.MovieTimeRepository;
import com.ticketing.server.global.validator.constraints.NotEmptyCollection;
import com.ticketing.server.movie.domain.Ticket;
import com.ticketing.server.movie.domain.repository.TicketRepository; import com.ticketing.server.movie.domain.repository.TicketRepository;
import com.ticketing.server.movie.service.dto.TicketDTO; import com.ticketing.server.movie.service.dto.TicketDTO;
import com.ticketing.server.movie.service.dto.TicketDetailsDTO;
import com.ticketing.server.movie.service.dto.TicketListDTO;
import com.ticketing.server.movie.service.dto.TicketRefundDTO; import com.ticketing.server.movie.service.dto.TicketRefundDTO;
import com.ticketing.server.movie.service.dto.TicketReservationDTO; import com.ticketing.server.movie.service.dto.TicketReservationDTO;
import com.ticketing.server.movie.service.dto.TicketSoldDTO; import com.ticketing.server.movie.service.dto.TicketSoldDTO;
import com.ticketing.server.movie.service.dto.TicketsCancelDTO; import com.ticketing.server.movie.service.dto.TicketsCancelDTO;
import com.ticketing.server.movie.service.dto.TicketsRefundDTO;
import com.ticketing.server.movie.service.dto.TicketsReservationDTO; import com.ticketing.server.movie.service.dto.TicketsReservationDTO;
import com.ticketing.server.movie.service.dto.TicketsSoldDTO; import com.ticketing.server.movie.service.dto.TicketsSoldDTO;
import com.ticketing.server.movie.service.interfaces.TicketService; import com.ticketing.server.movie.service.interfaces.TicketService;
import com.ticketing.server.payment.service.dto.TicketDetailDTO; import com.ticketing.server.payment.service.dto.TicketDetailDTO;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
@@ -37,18 +42,20 @@ public class TicketServiceImpl implements TicketService {
private final MovieTimeRepository movieTimeRepository; private final MovieTimeRepository movieTimeRepository;
@Override @Override
public List<TicketDTO> getTickets(@NotNull Long movieTimeId) { public TicketListDTO getTickets(@NotNull Long movieTimeId) {
MovieTime movieTime = movieTimeRepository.findById(movieTimeId) MovieTime movieTime = movieTimeRepository.findById(movieTimeId)
.orElseThrow(ErrorCode::throwMovieTimeNotFound); .orElseThrow(ErrorCode::throwMovieTimeNotFound);
return ticketRepository.findValidTickets(movieTime) List<TicketDTO> tickets = ticketRepository.findValidTickets(movieTime)
.stream() .stream()
.map(TicketDTO::new) .map(TicketDTO::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
return new TicketListDTO(tickets);
} }
@Override @Override
public List<TicketDetailDTO> findTicketsByPaymentId(@NotNull Long paymentId) { public TicketDetailsDTO findTicketsByPaymentId(@NotNull Long paymentId) {
List<TicketDetailDTO> ticketDetails = ticketRepository.findTicketFetchJoinByPaymentId(paymentId) List<TicketDetailDTO> ticketDetails = ticketRepository.findTicketFetchJoinByPaymentId(paymentId)
.stream() .stream()
.map(TicketDetailDTO::new) .map(TicketDetailDTO::new)
@@ -58,7 +65,7 @@ public class TicketServiceImpl implements TicketService {
throw ErrorCode.throwPaymentIdNotFound(); throw ErrorCode.throwPaymentIdNotFound();
} }
return ticketDetails; return new TicketDetailsDTO(ticketDetails);
} }
@Override @Override
@@ -99,18 +106,20 @@ public class TicketServiceImpl implements TicketService {
List<Ticket> tickets = getTicketsByInTicketIds(ticketIds); List<Ticket> tickets = getTicketsByInTicketIds(ticketIds);
tickets.forEach(Ticket::cancel); tickets.forEach(Ticket::cancel);
return new TicketsCancelDTO(tickets); return new TicketsCancelDTO(ticketIds);
} }
@Override @Override
@Transactional @Transactional
public List<TicketRefundDTO> ticketsRefund(@NotNull Long paymentId, UnaryOperator<Ticket> refund) { public TicketsRefundDTO ticketsRefund(@NotNull Long paymentId, UnaryOperator<Ticket> refund) {
List<Ticket> tickets = ticketRepository.findTicketFetchJoinByPaymentId(paymentId); List<Ticket> tickets = ticketRepository.findTicketFetchJoinByPaymentId(paymentId);
return tickets.stream() List<TicketRefundDTO> refundDtoList = tickets.stream()
.map(refund) .map(refund)
.map(TicketRefundDTO::new) .map(TicketRefundDTO::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
return new TicketsRefundDTO(refundDtoList);
} }
private List<Ticket> getTicketsByInTicketIds(List<Long> ticketIds) { private List<Ticket> getTicketsByInTicketIds(List<Long> ticketIds) {

View File

@@ -0,0 +1,18 @@
package com.ticketing.server.movie.service.dto;
import com.ticketing.server.movie.application.response.MovieListResponse;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class MovieListDTO {
private final List<MovieDTO> movieDtos;
public MovieListResponse toResponse() {
return new MovieListResponse(movieDtos);
}
}

View File

@@ -0,0 +1,18 @@
package com.ticketing.server.movie.service.dto;
import com.ticketing.server.movie.application.response.MovieTimeListResponse;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class MovieTimeListDTO {
private final List<MovieTimeDTO> movieTimeDtos;
public MovieTimeListResponse toResponse() {
return new MovieTimeListResponse(movieTimeDtos);
}
}

View File

@@ -0,0 +1,18 @@
package com.ticketing.server.movie.service.dto;
import com.ticketing.server.movie.application.response.TicketDetailsResponse;
import com.ticketing.server.payment.service.dto.TicketDetailDTO;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class TicketDetailsDTO {
private final List<TicketDetailDTO> ticketDetails;
public TicketDetailsResponse toResponse() {
return new TicketDetailsResponse(ticketDetails);
}
}

View File

@@ -0,0 +1,18 @@
package com.ticketing.server.movie.service.dto;
import com.ticketing.server.movie.application.response.TicketListResponse;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class TicketListDTO {
private final List<TicketDTO> ticketDtos;
public TicketListResponse toResponse() {
return new TicketListResponse(ticketDtos);
}
}

View File

@@ -1,22 +1,16 @@
package com.ticketing.server.movie.service.dto; package com.ticketing.server.movie.service.dto;
import com.ticketing.server.movie.application.response.TicketCancelResponse; import com.ticketing.server.movie.application.response.TicketCancelResponse;
import com.ticketing.server.movie.domain.Ticket;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
@AllArgsConstructor
public class TicketsCancelDTO { public class TicketsCancelDTO {
private final List<Long> ticketIds; private final List<Long> ticketIds;
public TicketsCancelDTO(List<Ticket> tickets) {
ticketIds = tickets.stream()
.map(Ticket::getId)
.collect(Collectors.toList());
}
public TicketCancelResponse toResponse() { public TicketCancelResponse toResponse() {
return new TicketCancelResponse(ticketIds); return new TicketCancelResponse(ticketIds);
} }

View File

@@ -0,0 +1,16 @@
package com.ticketing.server.movie.service.dto;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class TicketsRefundDTO {
private List<TicketRefundDTO> tickets;
public TicketsRefundResponse toResponse() {
return new TicketsRefundResponse(tickets);
}
}

View File

@@ -1,15 +1,14 @@
package com.ticketing.server.movie.service.interfaces; package com.ticketing.server.movie.service.interfaces;
import com.ticketing.server.movie.service.dto.DeletedMovieDTO; import com.ticketing.server.movie.service.dto.DeletedMovieDTO;
import com.ticketing.server.movie.service.dto.MovieDTO; import com.ticketing.server.movie.service.dto.MovieListDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieDTO; import com.ticketing.server.movie.service.dto.RegisteredMovieDTO;
import java.util.List;
public interface MovieService { public interface MovieService {
RegisteredMovieDTO registerMovie(String title, Long runningTime); RegisteredMovieDTO registerMovie(String title, Long runningTime);
List<MovieDTO> getMovies(); MovieListDTO getMovies();
DeletedMovieDTO deleteMovie(Long id); DeletedMovieDTO deleteMovie(Long id);
} }

View File

@@ -2,18 +2,17 @@ package com.ticketing.server.movie.service.interfaces;
import com.ticketing.server.movie.domain.Movie; import com.ticketing.server.movie.domain.Movie;
import com.ticketing.server.movie.domain.Theater; import com.ticketing.server.movie.domain.Theater;
import com.ticketing.server.movie.service.dto.MovieTimeDTO; import com.ticketing.server.movie.service.dto.MovieTimeListDTO;
import com.ticketing.server.movie.service.dto.MovieTimeRegisterDTO; import com.ticketing.server.movie.service.dto.MovieTimeRegisterDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieTimeDTO; import com.ticketing.server.movie.service.dto.RegisteredMovieTimeDTO;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List;
import javax.validation.Valid; import javax.validation.Valid;
public interface MovieTimeService { public interface MovieTimeService {
RegisteredMovieTimeDTO registerMovieTime(@Valid MovieTimeRegisterDTO movieTimeRegisterDto); RegisteredMovieTimeDTO registerMovieTime(@Valid MovieTimeRegisterDTO movieTimeRegisterDto);
List<MovieTimeDTO> getMovieTimes(Long movieId, LocalDate runningDate); MovieTimeListDTO getMovieTimes(Long movieId, LocalDate runningDate);
Movie findMovieById(Long movieId); Movie findMovieById(Long movieId);

View File

@@ -2,21 +2,21 @@ package com.ticketing.server.movie.service.interfaces;
import com.ticketing.server.global.validator.constraints.NotEmptyCollection; import com.ticketing.server.global.validator.constraints.NotEmptyCollection;
import com.ticketing.server.movie.domain.Ticket; import com.ticketing.server.movie.domain.Ticket;
import com.ticketing.server.movie.service.dto.TicketDTO; import com.ticketing.server.movie.service.dto.TicketDetailsDTO;
import com.ticketing.server.movie.service.dto.TicketRefundDTO; import com.ticketing.server.movie.service.dto.TicketListDTO;
import com.ticketing.server.movie.service.dto.TicketsCancelDTO; import com.ticketing.server.movie.service.dto.TicketsCancelDTO;
import com.ticketing.server.movie.service.dto.TicketsRefundDTO;
import com.ticketing.server.movie.service.dto.TicketsReservationDTO; import com.ticketing.server.movie.service.dto.TicketsReservationDTO;
import com.ticketing.server.movie.service.dto.TicketsSoldDTO; import com.ticketing.server.movie.service.dto.TicketsSoldDTO;
import com.ticketing.server.payment.service.dto.TicketDetailDTO;
import java.util.List; import java.util.List;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
public interface TicketService { public interface TicketService {
List<TicketDTO> getTickets(@NotNull Long movieTimeId); TicketListDTO getTickets(@NotNull Long movieTimeId);
List<TicketDetailDTO> findTicketsByPaymentId(@NotNull Long paymentId); TicketDetailsDTO findTicketsByPaymentId(@NotNull Long paymentId);
TicketsReservationDTO ticketReservation(@NotEmptyCollection List<Long> ticketIds); TicketsReservationDTO ticketReservation(@NotEmptyCollection List<Long> ticketIds);
@@ -24,6 +24,6 @@ public interface TicketService {
TicketsCancelDTO ticketCancel(@NotEmptyCollection List<Long> ticketIds); TicketsCancelDTO ticketCancel(@NotEmptyCollection List<Long> ticketIds);
List<TicketRefundDTO> ticketsRefund(@NotNull Long paymentId, UnaryOperator<Ticket> refund); TicketsRefundDTO ticketsRefund(@NotNull Long paymentId, UnaryOperator<Ticket> refund);
} }

View File

@@ -8,16 +8,15 @@ import com.ticketing.server.movie.application.response.TicketDetailsResponse;
import com.ticketing.server.movie.application.response.TicketReservationResponse; import com.ticketing.server.movie.application.response.TicketReservationResponse;
import com.ticketing.server.movie.application.response.TicketSoldResponse; import com.ticketing.server.movie.application.response.TicketSoldResponse;
import com.ticketing.server.movie.domain.Ticket; import com.ticketing.server.movie.domain.Ticket;
import com.ticketing.server.movie.service.dto.TicketRefundDTO; import com.ticketing.server.movie.service.dto.TicketDetailsDTO;
import com.ticketing.server.movie.service.dto.TicketsCancelDTO; import com.ticketing.server.movie.service.dto.TicketsCancelDTO;
import com.ticketing.server.movie.service.dto.TicketsRefundDTO;
import com.ticketing.server.movie.service.dto.TicketsRefundResponse; import com.ticketing.server.movie.service.dto.TicketsRefundResponse;
import com.ticketing.server.movie.service.dto.TicketsReservationDTO; import com.ticketing.server.movie.service.dto.TicketsReservationDTO;
import com.ticketing.server.movie.service.dto.TicketsSoldDTO; import com.ticketing.server.movie.service.dto.TicketsSoldDTO;
import com.ticketing.server.movie.service.interfaces.TicketService; import com.ticketing.server.movie.service.interfaces.TicketService;
import com.ticketing.server.payment.api.MovieClient; import com.ticketing.server.payment.api.MovieClient;
import com.ticketing.server.payment.service.dto.TicketDetailDTO;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -32,8 +31,8 @@ public class MovieClientImpl implements MovieClient {
@Override @Override
public TicketDetailsResponse getTicketsByPaymentId(@NotNull Long paymentId) { public TicketDetailsResponse getTicketsByPaymentId(@NotNull Long paymentId) {
List<TicketDetailDTO> ticketDetails = ticketService.findTicketsByPaymentId(paymentId); TicketDetailsDTO ticketDetails = ticketService.findTicketsByPaymentId(paymentId);
return new TicketDetailsResponse(ticketDetails); return ticketDetails.toResponse();
} }
@Override @Override
@@ -56,14 +55,14 @@ public class MovieClientImpl implements MovieClient {
@Override @Override
public TicketsRefundResponse ticketRefundByDateTime(TicketsRefundRequest request, LocalDateTime dateTime) { public TicketsRefundResponse ticketRefundByDateTime(TicketsRefundRequest request, LocalDateTime dateTime) {
List<TicketRefundDTO> ticketRefundDTOS = ticketService.ticketsRefund(request.getPaymentId(), ticket -> ticket.refund(dateTime)); TicketsRefundDTO ticketsRefundDto = ticketService.ticketsRefund(request.getPaymentId(), ticket -> ticket.refund(dateTime));
return new TicketsRefundResponse(ticketRefundDTOS); return ticketsRefundDto.toResponse();
} }
@Override @Override
public TicketsRefundResponse ticketRefund(TicketsRefundRequest request) { public TicketsRefundResponse ticketRefund(TicketsRefundRequest request) {
List<TicketRefundDTO> ticketRefundDtos = ticketService.ticketsRefund(request.getPaymentId(), Ticket::refund); TicketsRefundDTO ticketsRefundDto = ticketService.ticketsRefund(request.getPaymentId(), Ticket::refund);
return new TicketsRefundResponse(ticketRefundDtos); return ticketsRefundDto.toResponse();
} }
} }

View File

@@ -4,13 +4,9 @@ import com.ticketing.server.user.domain.UserGrade;
import javax.validation.constraints.Email; import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter @Getter
@NoArgsConstructor
@AllArgsConstructor
public class UserChangeGradeRequest { public class UserChangeGradeRequest {
@NotEmpty(message = "{validation.not.empty.email}") @NotEmpty(message = "{validation.not.empty.email}")

View File

@@ -1,6 +1,8 @@
package com.ticketing.server.user.application.response; package com.ticketing.server.user.application.response;
import com.ticketing.server.user.domain.UserGrade; import com.ticketing.server.user.domain.UserGrade;
import com.ticketing.server.user.service.dto.UserDetailDTO;
import lombok.AccessLevel;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,5 +1,6 @@
package com.ticketing.server.user.service; package com.ticketing.server.user.service;
import com.ticketing.server.global.exception.ErrorCode;
import com.ticketing.server.user.domain.User; import com.ticketing.server.user.domain.User;
import com.ticketing.server.user.domain.repository.UserRepository; import com.ticketing.server.user.domain.repository.UserRepository;
import java.util.Collections; import java.util.Collections;
@@ -20,7 +21,7 @@ public class CustomUserDetailsService implements UserDetailsService {
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return userRepository.findByEmailAndDeletedAtNull(email) return userRepository.findByEmailAndDeletedAtNull(email)
.map(this::createUserDetails) .map(this::createUserDetails)
.orElseThrow(() -> new UsernameNotFoundException(email)); .orElseThrow(ErrorCode::throwEmailNotFound);
} }
private UserDetails createUserDetails(User user) { private UserDetails createUserDetails(User user) {

View File

@@ -1,120 +0,0 @@
package com.ticketing.server.global.security.jwt;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.ticketing.server.global.factory.YamlPropertySourceFactory;
import com.ticketing.server.user.domain.UserGrade;
import com.ticketing.server.user.domain.UserGrade.ROLES;
import com.ticketing.server.user.service.dto.TokenDTO;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import javax.servlet.ServletException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties(value = JwtProperties.class)
@PropertySource(value = "classpath:application.yml", factory = YamlPropertySourceFactory.class)
class JwtFilterTest {
@Autowired
private JwtProperties jwtProperties;
private MockHttpServletRequest mockRequest;
private MockHttpServletResponse mockResponse;
private MockFilterChain mockFilterChain;
private JwtFilter jwtFilter;
@BeforeEach
void init() {
mockRequest = new MockHttpServletRequest();
mockResponse = new MockHttpServletResponse();
mockFilterChain = new MockFilterChain();
JwtProvider jwtProvider = new JwtProvider(jwtProperties);
jwtFilter = new JwtFilter(jwtProperties, jwtProvider);
SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(UserGrade.USER.name());
Collection<SimpleGrantedAuthority> authorities = Collections.singleton(grantedAuthority);
User user = new User(
"kdhyo98@gmail.com",
"",
authorities
);
TokenDTO tokenDto = jwtProvider.generateTokenDto(new UsernamePasswordAuthenticationToken(user, null, authorities));
mockRequest.addHeader("Authorization", "Bearer " + tokenDto.getAccessToken());
SecurityContextHolder.clearContext();
}
@ParameterizedTest
@DisplayName("Header 정보가 올바르지 않을 경우")
@ValueSource(strings = {"Bearer tokenTest", "Bearer", "BearertokenTest"})
void validateToken(String authorization) {
// given
mockRequest.removeHeader("Authorization");
mockRequest.addHeader("Authorization", authorization);
// when
// then
assertThatThrownBy(() -> jwtFilter.doFilterInternal(mockRequest, mockResponse, mockFilterChain))
.isInstanceOf(RuntimeException.class);
}
@Test
@DisplayName("다음 필터 실행")
void continuesToNextFilter() throws ServletException, IOException {
// given
MockFilterChain mockFilterChainSpy = spy(this.mockFilterChain);
// when
jwtFilter.doFilter(mockRequest, mockResponse, mockFilterChainSpy);
// then
verify(mockFilterChainSpy, times(1)).doFilter(mockRequest, mockResponse);
}
@Test
@DisplayName("setAuthentication 데이터 확인")
void setsAuthenticationInSecurityContext() throws ServletException, IOException {
// given
SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(ROLES.USER);
Collection<GrantedAuthority> authorities = Collections.singleton(grantedAuthority);
// when
jwtFilter.doFilter(mockRequest, mockResponse, mockFilterChain);
// then
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
User principal = (User) authentication.getPrincipal();
assertAll(
() -> assertThat(principal.getUsername()).isEqualTo("kdhyo98@gmail.com"),
() -> assertThat(principal.getAuthorities()).isEqualTo(authorities)
);
}
}

View File

@@ -1,23 +1,15 @@
package com.ticketing.server.movie.service; package com.ticketing.server.movie.service;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import com.ticketing.server.global.exception.TicketingException;
import com.ticketing.server.movie.domain.Movie; import com.ticketing.server.movie.domain.Movie;
import com.ticketing.server.movie.domain.repository.MovieRepository; import com.ticketing.server.movie.domain.repository.MovieRepository;
import com.ticketing.server.movie.service.dto.DeletedMovieDTO;
import com.ticketing.server.movie.service.dto.MovieDTO; import com.ticketing.server.movie.service.dto.MovieDTO;
import com.ticketing.server.movie.service.dto.RegisteredMovieDTO; import com.ticketing.server.movie.service.dto.MovieListDTO;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional;
import org.hibernate.sql.Delete;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@@ -29,7 +21,9 @@ import org.mockito.junit.jupiter.MockitoExtension;
public class MovieServiceImplTest { public class MovieServiceImplTest {
Movie movie; Movie movie;
MovieDTO movieDto;
List<Movie> movies = new ArrayList<>(); List<Movie> movies = new ArrayList<>();
List<MovieDTO> movieDTOS = new ArrayList<>();
@Mock @Mock
MovieRepository movieRepository; MovieRepository movieRepository;
@@ -45,10 +39,10 @@ public class MovieServiceImplTest {
.thenReturn(Collections.emptyList()); .thenReturn(Collections.emptyList());
// when // when
List<MovieDTO> movieDtos = movieService.getMovies(); MovieListDTO movieListDto = movieService.getMovies();
// then // then
assertTrue(movieDtos.isEmpty()); assertTrue(movieListDto.getMovieDtos().isEmpty());
} }
@Test @Test
@@ -62,79 +56,10 @@ public class MovieServiceImplTest {
.thenReturn(movies); .thenReturn(movies);
// when // when
List<MovieDTO> movieDtos = movieService.getMovies(); MovieListDTO movieListDto = movieService.getMovies();
// then // then
assertTrue(!movieDtos.isEmpty()); assertTrue(!movieListDto.getMovieDtos().isEmpty());
} }
@Test
@DisplayName("Movie Service Test - register movie")
void shouldAbleToRegisterMovie() {
// given
String title = "추가할 영화 제목";
movie = new Movie(title, 100L);
when(movieRepository.findValidMovieWithTitle(title))
.thenReturn(Optional.empty());
when(movieRepository.save(any()))
.thenReturn(movie);
// when
RegisteredMovieDTO registeredMovieDto =
movieService.registerMovie(title, movie.getRunningTime());
// then
assertThat(registeredMovieDto).isNotNull();
assertTrue(registeredMovieDto.getTitle().equals(title));
}
@Test
@DisplayName("Movie Service Test - register movie when there is same movie already")
void shouldThrowExceptionWhenRegistering() {
// given
String title = "이미 중복된 영화 제목";
Movie movie = new Movie(title, 100L);
when(movieRepository.findValidMovieWithTitle(title))
.thenReturn(Optional.of(movie));
// when
// then
assertThatThrownBy(() -> movieService.registerMovie(title, 100L))
.isInstanceOf(TicketingException.class);
}
@Test
@DisplayName("Movie Service Test - delete movie")
void shouldAbleToDeleteMovie() {
// given
Movie movie = new Movie("삭제할 영화 제목", 100L);
when(movieRepository.findByIdAndDeletedAtNull(1L))
.thenReturn(Optional.of(movie));
// when
DeletedMovieDTO deletedMovieDto =
movieService.deleteMovie(1L);
// then
assertTrue(deletedMovieDto.getTitle().equals("삭제할 영화 제목"));
assertThat(deletedMovieDto.getDeletedAt()).isNotNull();
}
@Test
@DisplayName("Movie Service Test - delete movie when there is no such movie")
void shouldThrowExceptionWhenDeleting() {
// given
when(movieRepository.findByIdAndDeletedAtNull(1L))
.thenReturn(Optional.empty());
// when
// then
assertThatThrownBy(() -> movieService.deleteMovie(1L))
.isInstanceOf(TicketingException.class);
}
} }

View File

@@ -9,7 +9,7 @@ import com.ticketing.server.movie.domain.MovieTime;
import com.ticketing.server.movie.domain.Theater; import com.ticketing.server.movie.domain.Theater;
import com.ticketing.server.movie.domain.repository.MovieRepository; import com.ticketing.server.movie.domain.repository.MovieRepository;
import com.ticketing.server.movie.domain.repository.MovieTimeRepository; import com.ticketing.server.movie.domain.repository.MovieTimeRepository;
import com.ticketing.server.movie.service.dto.MovieTimeDTO; import com.ticketing.server.movie.service.dto.MovieTimeListDTO;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
@@ -51,10 +51,10 @@ public class MovieTimeServiceImplTest {
.thenReturn(Collections.emptyList()); .thenReturn(Collections.emptyList());
// when // when
List<MovieTimeDTO> movieTimeDtos = movieTimeService.getMovieTimes(any(), LocalDate.now()); MovieTimeListDTO movieTimeListDto = movieTimeService.getMovieTimes(any(), LocalDate.now());
// then // then
assertTrue(movieTimeDtos.isEmpty()); assertTrue(movieTimeListDto.getMovieTimeDtos().isEmpty());
} }
@Test @Test
@@ -76,10 +76,10 @@ public class MovieTimeServiceImplTest {
.thenReturn(movieTimes); .thenReturn(movieTimes);
// when // when
List<MovieTimeDTO> movieTimeDtos = movieTimeService.getMovieTimes(any(), LocalDate.of(2022, 07, 01)); MovieTimeListDTO movieTimeListDto = movieTimeService.getMovieTimes(any(), LocalDate.of(2022, 07, 01));
// then // then
assertTrue(!movieTimeDtos.isEmpty()); assertTrue(!movieTimeListDto.getMovieTimeDtos().isEmpty());
} }
} }

View File

@@ -10,6 +10,7 @@ import com.ticketing.server.global.exception.ErrorCode;
import com.ticketing.server.global.exception.TicketingException; import com.ticketing.server.global.exception.TicketingException;
import com.ticketing.server.movie.domain.Ticket; import com.ticketing.server.movie.domain.Ticket;
import com.ticketing.server.movie.domain.repository.TicketRepository; import com.ticketing.server.movie.domain.repository.TicketRepository;
import com.ticketing.server.movie.service.dto.TicketDetailsDTO;
import com.ticketing.server.movie.service.dto.TicketsReservationDTO; import com.ticketing.server.movie.service.dto.TicketsReservationDTO;
import com.ticketing.server.payment.service.dto.TicketDetailDTO; import com.ticketing.server.payment.service.dto.TicketDetailDTO;
import java.util.Collections; import java.util.Collections;
@@ -52,7 +53,8 @@ class TicketServiceImplTest {
when(ticketRepository.findTicketFetchJoinByPaymentId(1L)).thenReturn(List.of(tickets.get(0))); when(ticketRepository.findTicketFetchJoinByPaymentId(1L)).thenReturn(List.of(tickets.get(0)));
// when // when
List<TicketDetailDTO> ticketDetails = ticketService.findTicketsByPaymentId(1L); TicketDetailsDTO ticketDetailDto = ticketService.findTicketsByPaymentId(1L);
List<TicketDetailDTO> ticketDetails = ticketDetailDto.getTicketDetails();
// then // then
assertAll( assertAll(