Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class StoreController {
* 매장 생성 API
*/
@PostMapping
public ResponseEntity<ApiResponse<StoreCreateResponse>> createStore(@Valid @RequestBody StoreCreateRequest request) {
StoreCreateResponse response = storeService.createStore(request);
public ResponseEntity<ApiResponse<StoreCreateResponse>> createStore(@RequestParam Long userId, @Valid @RequestBody StoreCreateRequest request) {
StoreCreateResponse response = storeService.createStore(userId, request);
return ResponseEntity.ok(ApiResponse.success(response));
}

Expand Down Expand Up @@ -108,7 +108,7 @@ public ResponseEntity<ApiResponse<StoreResponse>> getStoreSimpleInfo(@RequestPar
/**
* 매장 입장 API
*/
@GetMapping("/join")
@PostMapping("/join")
public ResponseEntity<ApiResponse<Void>> getStore(@RequestParam UUID storeCode) {
// UserId는 spring security의 @AuthenticationPrincipal로 받아올 수 있음
// Long userId = userDetails.getUserId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ public interface UserStoreRepository extends JpaRepository<UserStore, Long> {

@Query("SELECT u FROM UserStore us JOIN us.user u WHERE us.store.id = :storeId")
List<User> findUsersByStoreId(@Param("storeId") Long storeId);

List<UserStore> findAllByStore(Store store);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.UUID;

public interface StoreService {
StoreCreateResponse createStore(StoreCreateRequest request);
StoreCreateResponse createStore(Long userId, StoreCreateRequest request);

void updateStore(Long storeId, StoreUpdateRequest request);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.burntoburn.easyshift.common.util.DateUtil;
import com.burntoburn.easyshift.dto.store.use.*;
import com.burntoburn.easyshift.dto.user.UserDTO;
import com.burntoburn.easyshift.entity.schedule.Shift;
import com.burntoburn.easyshift.entity.store.Store;
import com.burntoburn.easyshift.entity.store.UserStore;
Expand Down Expand Up @@ -38,11 +37,28 @@ public class StoreServiceImpl implements StoreService {

@Override
@Transactional
public StoreCreateResponse createStore(StoreCreateRequest request) {
Store store = StoreCreateRequest.toEntity(request.getStoreName(), request.getDescription());
public StoreCreateResponse createStore(Long userId, StoreCreateRequest request) {
// 1) 유저 찾기 (매장을 만든 사람)
User user = userRepository.findById(userId)
.orElseThrow(UserException::userNotFound);

// 2) 새 매장 엔티티 생성
Store store = StoreCreateRequest.toEntity(request.getStoreName(), request.getDescription());
Store savedStore = storeRepository.save(store);
return new StoreCreateResponse(savedStore.getId(), savedStore.getStoreName(), savedStore.getStoreCode());

// 3) UserStore 엔티티로 유저-매장 관계 생성
UserStore userStore = UserStore.builder()
.user(user)
.store(savedStore)
.build();
userStoreRepository.save(userStore);

// 4) 응답 DTO 리턴
return new StoreCreateResponse(
savedStore.getId(),
savedStore.getStoreName(),
savedStore.getStoreCode()
);
}

@Override
Expand Down Expand Up @@ -119,7 +135,7 @@ public void joinUserStore(UUID storeCode, Long userId) {
User user = userRepository.findById(userId).orElseThrow(UserException::userNotFound);

boolean alreadyJoined = userStoreRepository.existsByUserIdAndStoreId(userId, store.getId());
if(alreadyJoined){
if (alreadyJoined) {
throw StoreException.userAlreadyJoined();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.burntoburn.easyshift.repository.store.StoreRepository;
import com.burntoburn.easyshift.repository.store.UserStoreRepository;
import com.burntoburn.easyshift.repository.user.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;
Expand Down Expand Up @@ -43,6 +44,8 @@ public class StoreQueryTest {

@Autowired
private ShiftRepository shiftRepository;


@Test
@DisplayName("매장 생성 쿼리 확인")
void createStoreQueryTest(){
Expand All @@ -51,8 +54,17 @@ void createStoreQueryTest(){
request.setStoreName("Test Store");
request.setDescription("Test Store Description");

User user = User.builder()
.name("Test User")
.email("testuser@example.com")
.role(Role.GUEST)
.build();
user = userRepository.save(user); // <-- 실제 DB에 저장 (영속화)
Long userId = user.getId(); // <-- DB에서 자동 생성된 ID 사용


// when
StoreCreateResponse response = storeService.createStore(request);
StoreCreateResponse response = storeService.createStore(userId, request);

// then
assertNotNull(response);
Expand All @@ -72,7 +84,16 @@ void testUpdateStoreQueryExecution() {
StoreCreateRequest createRequest = new StoreCreateRequest();
createRequest.setStoreName("Original Store Name");
createRequest.setDescription("Original Description");
StoreCreateResponse createResponse = storeService.createStore(createRequest);

User user = User.builder()
.name("Test User")
.email("testuser@example.com")
.role(Role.GUEST)
.build();
user = userRepository.save(user); // <-- 실제 DB에 저장 (영속화)
Long userId = user.getId(); // <-- DB에서 자동 생성된 ID 사용

StoreCreateResponse createResponse = storeService.createStore(userId, createRequest);
Long storeId = createResponse.getStoreId();

// when: 매장 정보 수정
Expand All @@ -90,21 +111,39 @@ void testUpdateStoreQueryExecution() {
@Test
@DisplayName("매장 삭제 쿼리 확인")
void testDeleteStoreQueryExecution() {
// given: 삭제할 매장을 생성
// given: 삭제할 매장을 생성하기 위해 유효한 User를 먼저 저장합니다.
User user = User.builder()
.name("Test User")
.email("testuser@example.com")
.role(Role.GUEST)
.build();
user = userRepository.save(user);
Long userId = user.getId(); // 실제 DB에 저장된 ID 사용

// 매장 생성 (자동으로 해당 User와 연결되었다고 가정)
StoreCreateRequest createRequest = new StoreCreateRequest();
createRequest.setStoreName("Store To Delete");
createRequest.setDescription("Store To Delete Description");
StoreCreateResponse createResponse = storeService.createStore(createRequest);
StoreCreateResponse createResponse = storeService.createStore(userId, createRequest);
Long storeId = createResponse.getStoreId();

// 삭제 전에, 해당 매장에 연결된 모든 UserStore 엔티티들을 명시적으로 삭제합니다.
Store store = storeRepository.findById(storeId)
.orElseThrow(StoreException::storeNotFound);
// UserStoreRepository에 매장으로 조회하는 메서드를 통해 삭제
var userStores = userStoreRepository.findAllByStore(store);
if (!userStores.isEmpty()) {
userStoreRepository.deleteAll(userStores);
userStoreRepository.flush(); // DB에 삭제 반영
}

// when: 매장 삭제
storeService.deleteStore(storeId);
storeRepository.flush();

// then: 삭제된 매장을 조회할 때 null이어야 함
Optional<Store> storeOpt = storeRepository.findById(storeId);
assertFalse(storeOpt.isPresent(), "매장이 삭제되어 조회되지 않아야 합니다.");
// ※ 콘솔 로그에 delete 쿼리가 출력됩니다.
}

@Test
Expand All @@ -122,8 +161,7 @@ void testGetUserStoresQueryExecution() {
StoreCreateRequest createRequest = new StoreCreateRequest();
createRequest.setStoreName("User Store");
createRequest.setDescription("User Store Description");
StoreCreateResponse createResponse = storeService.createStore(createRequest);
storeService.joinUserStore(createResponse.getStoreCode(), user.getId());
StoreCreateResponse createResponse = storeService.createStore(user.getId(), createRequest);

// when: 사용자의 매장 목록 조회
UserStoresResponse userStoresResponse = storeService.getUserStores(user.getId());
Expand All @@ -138,10 +176,18 @@ void testGetUserStoresQueryExecution() {
@DisplayName("매장 사용자 목록 조회 쿼리 확인")
void testGetStoreUsersQueryExecution() {
// given: 매장 생성
User user = User.builder()
.name("Test User")
.email("testuser@example.com")
.role(Role.GUEST)
.build();
user = userRepository.save(user); // <-- 실제 DB에 저장 (영속화)
Long userId = user.getId(); // <-- DB에서 자동 생성된 ID 사용

StoreCreateRequest createRequest = new StoreCreateRequest();
createRequest.setStoreName("Store For Users");
createRequest.setDescription("Desc for store users");
StoreCreateResponse createResponse = storeService.createStore(createRequest);
StoreCreateResponse createResponse = storeService.createStore(userId, createRequest);
Long storeId = createResponse.getStoreId();

// 두 명의 사용자 생성 후 매장 가입
Expand Down Expand Up @@ -170,7 +216,7 @@ void testGetStoreUsersQueryExecution() {

// then
assertNotNull(response);
assertEquals(2, response.getUsers().size(), "매장 사용자 목록에 두 명의 사용자가 포함되어야 합니다.");
assertEquals(3, response.getUsers().size(), "매장 사용자 목록에 두 명의 사용자가 포함되어야 합니다.");
// ※ 콘솔 로그에 select 쿼리가 출력됨을 확인하세요.
}

Expand All @@ -188,9 +234,8 @@ void testGetStoreInfoNoScheduleTemplate() {
StoreCreateRequest createRequest = new StoreCreateRequest();
createRequest.setStoreName("Info Store");
createRequest.setDescription("Store for info test");
StoreCreateResponse createResponse = storeService.createStore(createRequest);
StoreCreateResponse createResponse = storeService.createStore(user.getId(),createRequest);
Long storeId = createResponse.getStoreId();
storeService.joinUserStore(createResponse.getStoreCode(), user.getId());

// when: 매장 정보 조회 (스케줄 템플릿 관련 데이터가 없다면 빈 리스트 반환)
var storeInfoResponse = storeService.getStoreInfo(storeId, user.getId());
Expand All @@ -216,12 +261,10 @@ void testJoinUserStoreAlreadyJoined() {
StoreCreateRequest createRequest = new StoreCreateRequest();
createRequest.setStoreName("Join Store");
createRequest.setDescription("Join store test");
StoreCreateResponse createResponse = storeService.createStore(createRequest);
StoreCreateResponse createResponse = storeService.createStore(user.getId(), createRequest);

// when: 첫 가입 시도
storeService.joinUserStore(createResponse.getStoreCode(), savedUser.getId());

// then: 동일 매장에 다시 가입 시도하면 예외가 발생해야 함
// when then: 동일 매장에 다시 가입 시도하면 예외가 발생해야 함
assertThrows(StoreException.class, () ->
storeService.joinUserStore(createResponse.getStoreCode(), savedUser.getId())
);
Expand All @@ -232,10 +275,18 @@ void testJoinUserStoreAlreadyJoined() {
@DisplayName("매장 정보 단순 조회 쿼리 확인")
void testGetStoreSimpleInfo() {
// given: 매장 생성
User user = User.builder()
.name("Test User")
.email("testuser@example.com")
.role(Role.GUEST)
.build();
user = userRepository.save(user); // <-- 실제 DB에 저장 (영속화)
Long userId = user.getId(); // <-- DB에서 자동 생성된 ID 사용

StoreCreateRequest createRequest = new StoreCreateRequest();
createRequest.setStoreName("Simple Info Store");
createRequest.setDescription("Simple info description");
StoreCreateResponse createResponse = storeService.createStore(createRequest);
StoreCreateResponse createResponse = storeService.createStore(userId, createRequest);

Store store = storeRepository.findById(createResponse.getStoreId()).orElseThrow();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ class StoreServiceImplTest {
@DisplayName("매장 생성 성공 테스트")
void testCreateStoreSuccess() {
// given
Long userId = 1L;
User mockUser = User.builder()
.id(userId)
.name("MockUser")
.build();
when(userRepository.findById(userId)).thenReturn(Optional.of(mockUser));

StoreCreateRequest request = new StoreCreateRequest();
ReflectionTestUtils.setField(request, "storeName", "Test Store");
ReflectionTestUtils.setField(request, "description", "Test Description");
Expand All @@ -69,7 +76,7 @@ void testCreateStoreSuccess() {
when(storeRepository.save(any(Store.class))).thenReturn(savedStore);

// when
StoreCreateResponse response = storeService.createStore(request);
StoreCreateResponse response = storeService.createStore(userId, request);

// then
assertNotNull(response);
Expand Down