Skip to content

Commit

Permalink
refactor: Domain 패키지와 Exception 패키지간의 순환 참조 해결 (#581)
Browse files Browse the repository at this point in the history
* refactor: Exception 예외 전달시 순환 참조 문제 해결

* style: 액션 삭제

* refactor: 도메인 매직 넘버 public -> private
  • Loading branch information
Arachneee authored Sep 23, 2024
1 parent bff14b2 commit 5231f2a
Show file tree
Hide file tree
Showing 19 changed files with 56 additions and 69 deletions.
2 changes: 1 addition & 1 deletion server/src/docs/asciidoc/bill.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ operation::updateBill[snippets="path-parameters,http-request,request-body,reques
},
{
"code":"BILL_NOT_FOUND",
"message":"존재하지 않는 지출 액션입니다."
"message":"존재하지 않는 지출입니다."
},
{
"code":"TOKEN_NOT_FOUND",
Expand Down
4 changes: 2 additions & 2 deletions server/src/docs/asciidoc/billDetail.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ operation::findBillDetails[snippets="path-parameters,http-request,http-response,
},
{
"code": "BILL_NOT_FOUND",
"message": "존재하지 않는 지출 액션입니다."
"message": "존재하지 않는 지출입니다."
},
{
"code": "BILL_DETAIL_NOT_FOUND",
Expand Down Expand Up @@ -63,7 +63,7 @@ operation::updateBillDetails[snippets="path-parameters,http-request,request-body
},
{
"code": "BILL_NOT_FOUND",
"message": "존재하지 않는 지출 액션입니다."
"message": "존재하지 않는 지출 입니다."
},
{
"code": "BILL_DETAIL_NOT_FOUND",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import server.haengdong.domain.bill.Bill;
import server.haengdong.domain.bill.BillRepository;
import server.haengdong.domain.member.Member;
import server.haengdong.domain.member.MemberBillReport;
import server.haengdong.domain.bill.MemberBillReport;
import server.haengdong.domain.event.Event;
import server.haengdong.domain.event.EventRepository;
import server.haengdong.domain.event.EventTokenProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ public List<MemberAppResponse> getCurrentMembers(String token) {

private void validateMemberSave(List<String> memberNames, Event event) {
if (memberNamesDuplicated(memberNames)) {
throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE,
"중복된 이름이 존재합니다. 입력된 이름: " + memberNames);
throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE, memberNames);
}
if (memberRepository.findAllByEvent(event).stream()
.anyMatch(member -> memberNames.contains(member.getName()))) {
Expand Down
12 changes: 6 additions & 6 deletions server/src/main/java/server/haengdong/domain/bill/Bill.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
@Entity
public class Bill {

public static final int MIN_TITLE_LENGTH = 1;
public static final int MAX_TITLE_LENGTH = 30;
public static final long MIN_PRICE = 1L;
public static final long MAX_PRICE = 10_000_000L;
private static final int MIN_TITLE_LENGTH = 1;
private static final int MAX_TITLE_LENGTH = 30;
private static final long MIN_PRICE = 1L;
private static final long MAX_PRICE = 10_000_000L;
private static final long DEFAULT_PRICE = 0L;

@Id
Expand Down Expand Up @@ -63,13 +63,13 @@ public Bill(Event event, String title, Long price) {
private void validateTitle(String title) {
int titleLength = title.trim().length();
if (titleLength < MIN_TITLE_LENGTH || titleLength > MAX_TITLE_LENGTH) {
throw new HaengdongException(HaengdongErrorCode.BILL_TITLE_INVALID);
throw new HaengdongException(HaengdongErrorCode.BILL_TITLE_INVALID, MIN_TITLE_LENGTH, MAX_TITLE_LENGTH);
}
}

private void validatePrice(Long price) {
if (price < MIN_PRICE || price > MAX_PRICE) {
throw new HaengdongException(HaengdongErrorCode.BILL_PRICE_INVALID);
throw new HaengdongException(HaengdongErrorCode.BILL_PRICE_INVALID, MAX_PRICE);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package server.haengdong.domain.member;
package server.haengdong.domain.bill;

import static java.util.stream.Collectors.toMap;

import java.util.List;
import java.util.Map;
import lombok.Getter;
import server.haengdong.domain.bill.Bill;
import server.haengdong.domain.bill.BillDetail;
import server.haengdong.domain.member.Member;

@Getter
public class MemberBillReport {
Expand Down
4 changes: 2 additions & 2 deletions server/src/main/java/server/haengdong/domain/event/Bank.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public static void isExists(String bankName) {
Arrays.stream(Bank.values())
.filter(bank -> bank.name.equals(bankName))
.findFirst()
.orElseThrow(() -> new HaengdongException(HaengdongErrorCode.BANK_NAME_INVALID));
.orElseThrow(() -> new HaengdongException(HaengdongErrorCode.BANK_NAME_INVALID, getSupportedBanks()));
}

public static String getSupportedBanks() {
private static String getSupportedBanks() {
return Arrays.stream(Bank.values())
.map(Bank::getName)
.reduce((bank1, bank2) -> bank1 + ", " + bank2)
Expand Down
14 changes: 8 additions & 6 deletions server/src/main/java/server/haengdong/domain/event/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
@Entity
public class Event {

public static final int MIN_NAME_LENGTH = 1;
public static final int MAX_NAME_LENGTH = 20;
public static final int MIN_ACCOUNT_NUMBER_LENGTH = 8;
public static final int MAX_ACCOUNT_NUMBER_LENGTH = 30;
private static final int MIN_NAME_LENGTH = 1;
private static final int MAX_NAME_LENGTH = 20;
private static final int MIN_ACCOUNT_NUMBER_LENGTH = 8;
private static final int MAX_ACCOUNT_NUMBER_LENGTH = 30;
private static final String SPACES = " ";

@Id
Expand Down Expand Up @@ -53,7 +53,8 @@ public Event(String name, String password, String token) {
private void validateName(String name) {
int nameLength = name.trim().length();
if (nameLength < MIN_NAME_LENGTH || MAX_NAME_LENGTH < nameLength) {
throw new HaengdongException(HaengdongErrorCode.EVENT_NAME_LENGTH_INVALID);
throw new HaengdongException(
HaengdongErrorCode.EVENT_NAME_LENGTH_INVALID, MIN_NAME_LENGTH, MAX_NAME_LENGTH);
}
if (isBlankContinuous(name)) {
throw new HaengdongException(HaengdongErrorCode.EVENT_NAME_CONSECUTIVE_SPACES);
Expand Down Expand Up @@ -90,7 +91,8 @@ private void validateBankName(String bankName) {
private void validateAccountNumber(String accountNumber) {
int accountLength = accountNumber.trim().length();
if (accountLength < MIN_ACCOUNT_NUMBER_LENGTH || MAX_ACCOUNT_NUMBER_LENGTH < accountLength) {
throw new HaengdongException(HaengdongErrorCode.ACCOUNT_LENGTH_INVALID);
throw new HaengdongException(
HaengdongErrorCode.ACCOUNT_LENGTH_INVALID, MIN_ACCOUNT_NUMBER_LENGTH, MAX_ACCOUNT_NUMBER_LENGTH);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
@Embeddable
public class Password {

public static final int PASSWORD_LENGTH = 4;
private static final int PASSWORD_LENGTH = 4;
private static final Pattern PASSWORD_PATTERN = Pattern.compile(String.format("^\\d{%d}$", PASSWORD_LENGTH));
private static final String HASH_ALGORITHM = "SHA-256";

Expand All @@ -31,7 +31,7 @@ public Password(String password) {
private void validatePassword(String password) {
Matcher matcher = PASSWORD_PATTERN.matcher(password);
if (!matcher.matches()) {
throw new HaengdongException(HaengdongErrorCode.EVENT_PASSWORD_FORMAT_INVALID);
throw new HaengdongException(HaengdongErrorCode.EVENT_PASSWORD_FORMAT_INVALID, PASSWORD_LENGTH);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
@Entity
public class Member {

public static final int MIN_NAME_LENGTH = 1;
public static final int MAX_NAME_LENGTH = 8;
private static final int MIN_NAME_LENGTH = 1;
private static final int MAX_NAME_LENGTH = 8;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down Expand Up @@ -56,7 +56,7 @@ public Member(Long id, Event event, String name, boolean isDeposited) {
private void validateName(String name) {
int nameLength = name.length();
if (nameLength < MIN_NAME_LENGTH || nameLength > MAX_NAME_LENGTH) {
throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_LENGTH_INVALID);
throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_LENGTH_INVALID, MIN_NAME_LENGTH, MAX_NAME_LENGTH);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package server.haengdong.exception;

public record ErrorResponse(
HaengdongErrorCode errorCode,
String errorCode,
String message
) {

public static ErrorResponse of(HaengdongErrorCode errorCode) {
return new ErrorResponse(errorCode, errorCode.getMessage());
return new ErrorResponse(errorCode.name(), errorCode.getMessage());
}

public static ErrorResponse of(HaengdongErrorCode errorCode, String message) {
return new ErrorResponse(errorCode, message);
return new ErrorResponse(errorCode.name(), message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(Metho
public ResponseEntity<ErrorResponse> haengdongException(HttpServletRequest req, HaengdongException e) {
log.warn(LOG_FORMAT, req.getMethod(), req.getRequestURI(), getRequestBody(req), e.getMessage(), e);
return ResponseEntity.badRequest()
.body(ErrorResponse.of(e.getErrorCode()));
.body(ErrorResponse.of(e.getErrorCode(), e.getMessage()));
}

@ExceptionHandler(Exception.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,28 @@
package server.haengdong.exception;

import lombok.Getter;
import server.haengdong.domain.bill.Bill;
import server.haengdong.domain.member.Member;
import server.haengdong.domain.event.Bank;
import server.haengdong.domain.event.Event;
import server.haengdong.domain.event.Password;

@Getter
public enum HaengdongErrorCode {

/* Domain */

EVENT_NOT_FOUND("존재하지 않는 행사입니다."),
EVENT_NAME_LENGTH_INVALID(String.format("행사 이름은 %d자 이상 %d자 이하만 입력 가능합니다.",
Event.MIN_NAME_LENGTH,
Event.MAX_NAME_LENGTH)),
EVENT_NAME_LENGTH_INVALID("행사 이름은 %d자 이상 %d자 이하만 입력 가능합니다."),
EVENT_NAME_CONSECUTIVE_SPACES("행사 이름에는 공백 문자가 연속될 수 없습니다."),
EVENT_PASSWORD_FORMAT_INVALID(String.format("비밀번호는 %d자리 숫자만 가능합니다.", Password.PASSWORD_LENGTH)),
BANK_NAME_INVALID(String.format("지원하지 않는 은행입니다. 지원하는 은행 목록: %s",
Bank.getSupportedBanks())),
ACCOUNT_LENGTH_INVALID(String.format("계좌번호는 %d자 이상 %d자 이하만 입력 가능합니다.",
Event.MIN_ACCOUNT_NUMBER_LENGTH,
Event.MAX_ACCOUNT_NUMBER_LENGTH)),

MEMBER_NAME_LENGTH_INVALID(String.format("멤버 이름은 %d자 이상 %d자 이하만 입력 가능합니다.",
Member.MIN_NAME_LENGTH,
Member.MAX_NAME_LENGTH)),
EVENT_PASSWORD_FORMAT_INVALID("비밀번호는 %d자리 숫자만 가능합니다."),
BANK_NAME_INVALID("지원하지 않는 은행입니다. 지원하는 은행 목록: %s"),
ACCOUNT_LENGTH_INVALID("계좌번호는 %d자 이상 %d자 이하만 입력 가능합니다."),

MEMBER_NAME_LENGTH_INVALID("멤버 이름은 %d자 이상 %d자 이하만 입력 가능합니다."),
MEMBER_NAME_DUPLICATE("중복된 행사 참여 인원 이름이 존재합니다."),
MEMBER_NOT_FOUND("존재하지 않는 참여자입니다."),
MEMBER_ALREADY_EXIST("현재 참여하고 있는 인원이 존재합니다."),
MEMBER_NAME_CHANGE_DUPLICATE("중복된 참여 인원 이름 변경 요청이 존재합니다."),

BILL_NOT_FOUND("존재하지 않는 지출입니다."),
BILL_TITLE_INVALID(String.format("앞뒤 공백을 제거한 지출 내역 제목은 %d ~ %d자여야 합니다.",
Bill.MIN_TITLE_LENGTH,
Bill.MAX_TITLE_LENGTH)),
BILL_PRICE_INVALID(String.format("지출 금액은 %,d 이하의 자연수여야 합니다.", Bill.MAX_PRICE)),
BILL_TITLE_INVALID("앞뒤 공백을 제거한 지출 내역 제목은 %d ~ %d자여야 합니다."),
BILL_PRICE_INVALID("지출 금액은 %,d 이하의 자연수여야 합니다."),
BILL_DETAIL_NOT_FOUND("존재하지 않는 참여자 지출입니다."),
BILL_PRICE_NOT_MATCHED("지출 총액이 일치하지 않습니다."),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
public class HaengdongException extends RuntimeException {

private final HaengdongErrorCode errorCode;
private final String message;

public HaengdongException(HaengdongErrorCode errorCode) {
this(errorCode, errorCode.getMessage());
super(errorCode.getMessage());
this.errorCode = errorCode;
}

public HaengdongException(HaengdongErrorCode errorCode, String message) {
public HaengdongException(HaengdongErrorCode errorCode, Object... args) {
super(String.format(errorCode.getMessage(), args));
this.errorCode = errorCode;
this.message = message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void saveMembersTest2() {

assertThatThrownBy(() -> memberService.saveMembers(event.getToken(), request))
.isInstanceOf(HaengdongException.class)
.hasMessageContaining("중복된 이름이 존재합니다. 입력된 이름: [토다리, 토다리]");
.hasMessageContaining("중복된 행사 참여 인원 이름이 존재합니다.");
}

@DisplayName("행사 참여 인원을 삭제한다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void findBills() throws Exception {

@DisplayName("참여자별 지출 금액을 조회한다.")
@Test
void findBillActionDetails() throws Exception {
void findBillDetails() throws Exception {
BillDetailsAppResponse appResponse = new BillDetailsAppResponse(
List.of(new BillDetailAppResponse(1L, "토다리", 1000L, false)));
given(billService.findBillDetails(anyString(), anyLong())).willReturn(appResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.junit.jupiter.api.Test;
import server.haengdong.domain.bill.Bill;
import server.haengdong.domain.event.Event;
import server.haengdong.domain.bill.MemberBillReport;
import server.haengdong.support.fixture.Fixture;

class MemberBillReportTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void findBills() throws Exception {

@DisplayName("참여자별 지출 금액을 조회한다.")
@Test
void findBillActionDetails() throws Exception {
void findBillDetails() throws Exception {
BillDetailsAppResponse appResponse = new BillDetailsAppResponse(
List.of(new BillDetailAppResponse(1L, "토다리", 1000L, false)));
given(billService.findBillDetails(anyString(), anyLong())).willReturn(appResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class AdminBillControllerTest extends ControllerTestSupport {

@DisplayName("지출 내역을 생성한다.")
@Test
void saveAllBillAction() throws Exception {
void saveAllBill() throws Exception {
List<Long> members = List.of(1L, 2L);
BillSaveRequest request = new BillSaveRequest("뽕족", 10_000L, members);

Expand All @@ -43,7 +43,7 @@ void saveAllBillAction() throws Exception {

@DisplayName("title이 비어 있는 경우 지출 내역을 생성할 수 없다.")
@Test
void saveAllBillAction1() throws Exception {
void saveAllBill1() throws Exception {
List<Long> members = List.of(1L, 2L);
BillSaveRequest request = new BillSaveRequest("", 10_000L, members);

Expand All @@ -59,7 +59,7 @@ void saveAllBillAction1() throws Exception {

@DisplayName("지출 액션을 수정한다.")
@Test
void updateBillAction() throws Exception {
void updateBill() throws Exception {
BillUpdateRequest request = new BillUpdateRequest("뽕족", 10_000L);

String requestBody = objectMapper.writeValueAsString(request);
Expand All @@ -75,7 +75,7 @@ void updateBillAction() throws Exception {

@DisplayName("지출 내역을 삭제한다.")
@Test
void deleteBillAction() throws Exception {
void deleteBill() throws Exception {
String eventId = "토다리토큰";

mockMvc.perform(delete("/api/admin/events/{eventId}/bills/{billId}", eventId, 1))
Expand All @@ -85,7 +85,7 @@ void deleteBillAction() throws Exception {

@DisplayName("존재하지 않는 행사에 대한 지출 내역을 삭제할 수 없다.")
@Test
void deleteBillAction1() throws Exception {
void deleteBill1() throws Exception {
String eventId = "이상해토큰";
doThrow(new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND))
.when(billService).deleteBill(any(String.class), any(Long.class));
Expand All @@ -97,13 +97,13 @@ void deleteBillAction1() throws Exception {

@DisplayName("참여자별 지출 금액을 수정한다.")
@Test
void updateBillActionDetailsTest() throws Exception {
List<BillDetailUpdateRequest> billActionDetailUpdateRequests = List.of(
void updateBillDetailsTest() throws Exception {
List<BillDetailUpdateRequest> billDetailUpdateRequests = List.of(
new BillDetailUpdateRequest(1L, 10000L, true),
new BillDetailUpdateRequest(2L, 20000L, true)
);
BillDetailsUpdateRequest request = new BillDetailsUpdateRequest(
billActionDetailUpdateRequests);
billDetailUpdateRequests);

String json = objectMapper.writeValueAsString(request);

Expand Down

0 comments on commit 5231f2a

Please sign in to comment.