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 @@ -30,6 +30,7 @@ public enum SuccessMessage {
// VENDOR
CREATE_VENDOR_SUCCESS("발주처 등록 성공"),
UPDATE_VENDOR_SUCCESS("발주처 수정 성공"),
GET_VENDOR_DETAIL_SUCCESS("발주처 상세 조회 성공"),
;

private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down Expand Up @@ -60,4 +61,19 @@ public ResponseEntity<ApiResponse<VendorResponse>> updateVendor(
ApiResponse.success(SuccessMessage.UPDATE_VENDOR_SUCCESS.getMessage(), response)
);
}

@GetMapping("/{vendorId}")
@Operation(summary = "발주처 상세 조회", description = "발주처 정보를 반환합니다.")
public ResponseEntity<ApiResponse<VendorResponse>> getVendorDetail(
@PathVariable Long vendorId,
@AuthenticationPrincipal CustomUserPrincipal userPrincipal
) {
Long userId = userPrincipal.getId();
log.info("[VendorController] 발주처 상세 조회 요청 - vendorId: {}, userId: {}", vendorId, userId);
VendorResponse response = vendorService.getVendorDetail(vendorId, userId);

return ResponseEntity.ok(
ApiResponse.success(SuccessMessage.GET_VENDOR_DETAIL_SUCCESS.getMessage(), response)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ public VendorResponse updateVendor(Long vendorId, UpdateVendorRequest request, L
return VendorResponse.from(vendor);
}

@Transactional(readOnly = true)
public VendorResponse getVendorDetail(Long vendorId, Long userId) {
User user = findUserById(userId);
Vendor vendor = findVendorByIdAndValidateAccess(vendorId, user);

log.info("[VendorService] 발주처 상세 조회 성공 - vendorId: {}", vendor.getId());
return VendorResponse.from(vendor);
}

private Vendor toEntity(CreateVendorRequest request, User user) {
return Vendor.builder()
.store(user.getStore())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import com.almang.inventory.global.api.SuccessMessage;
Expand Down Expand Up @@ -234,4 +235,58 @@ private UsernamePasswordAuthenticationToken auth() {
.value(ErrorCode.INVALID_INPUT_VALUE.getMessage()))
.andExpect(jsonPath("$.data").doesNotExist());
}

@Test
void 발주처_상세_조회에_성공한다() throws Exception {
// given
Long vendorId = 1L;

VendorResponse response = new VendorResponse(
vendorId,
"테스트 발주처",
VendorChannel.KAKAO,
"010-1111-2222",
"메모",
true,
1L
);

when(vendorService.getVendorDetail(anyLong(), anyLong()))
.thenReturn(response);

// when & then
mockMvc.perform(get("/api/v1/vendor/{vendorId}", vendorId)
.with(authentication(auth()))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value(200))
.andExpect(jsonPath("$.message")
.value(SuccessMessage.GET_VENDOR_DETAIL_SUCCESS.getMessage()))
.andExpect(jsonPath("$.data.vendorId").value(vendorId))
.andExpect(jsonPath("$.data.name").value("테스트 발주처"))
.andExpect(jsonPath("$.data.channel").value("KAKAO"))
.andExpect(jsonPath("$.data.contactPoint").value("010-1111-2222"))
.andExpect(jsonPath("$.data.note").value("메모"))
.andExpect(jsonPath("$.data.storeId").value(1L))
.andExpect(jsonPath("$.data.activated").value(true));
}

@Test
void 발주처_상세_조회_시_존재하지_않는_발주처면_예외가_발생한다() throws Exception {
// given
Long vendorId = 9999L;

when(vendorService.getVendorDetail(anyLong(), anyLong()))
.thenThrow(new BaseException(ErrorCode.VENDOR_NOT_FOUND));

// when & then
mockMvc.perform(get("/api/v1/vendor/{vendorId}", vendorId)
.with(authentication(auth()))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.status")
.value(ErrorCode.VENDOR_NOT_FOUND.getHttpStatus().value()))
.andExpect(jsonPath("$.message").value(ErrorCode.VENDOR_NOT_FOUND.getMessage()))
.andExpect(jsonPath("$.data").doesNotExist());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,73 @@ private Vendor newVendor(Store store) {
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.VENDOR_ACCESS_DENIED.getMessage());
}

@Test
void 발주처_상세_조회에_성공한다() {
// given
Store store = newStore();
User user = newUser(store);
Vendor vendor = newVendor(store);

// when
VendorResponse response = vendorService.getVendorDetail(vendor.getId(), user.getId());

// then
assertThat(response.vendorId()).isEqualTo(vendor.getId());
assertThat(response.name()).isEqualTo("기존 발주처");
assertThat(response.channel()).isEqualTo(VendorChannel.KAKAO);
assertThat(response.contactPoint()).isEqualTo("010-1111-1111");
assertThat(response.note()).isEqualTo("원본 메모");
assertThat(response.storeId()).isEqualTo(store.getId());
assertThat(response.activated()).isTrue();
}

@Test
void 존재하지_않는_발주처_상세_조회시_예외가_발생한다() {
// given
Store store = newStore();
User user = newUser(store);
Long notExistVendorId = 9999L;

// when & then
assertThatThrownBy(() -> vendorService.getVendorDetail(notExistVendorId, user.getId()))
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.VENDOR_NOT_FOUND.getMessage());
}

@Test
void 다른_상점_발주처_상세_조회시_예외가_발생한다() {
// given
Store store1 = newStore();
Store store2 = newStore();

User userOfStore1 = newUser(store1);
User userOfStore2 = userRepository.save(
User.builder()
.store(store2)
.username("detail_tester_store2")
.password("password")
.name("상점2 관리자")
.role(UserRole.ADMIN)
.build()
);

Vendor vendorOfStore2 = vendorRepository.save(
Vendor.builder()
.store(store2)
.name("상점2 발주처")
.channel(VendorChannel.KAKAO)
.contactPoint("010-2222-2222")
.note("상점2 메모")
.activated(true)
.build()
);

// when & then
assertThatThrownBy(() ->
vendorService.getVendorDetail(vendorOfStore2.getId(), userOfStore1.getId())
)
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.VENDOR_ACCESS_DENIED.getMessage());
}
}