Skip to content

Commit e0057d8

Browse files
authored
Merge pull request #173 from UruruLab/test/172-seller
판매자 회원가입 Service계층 테스트 코드 작성
2 parents 016face + 42be4b0 commit e0057d8

File tree

4 files changed

+860
-67
lines changed

4 files changed

+860
-67
lines changed

src/main/java/com/ururulab/ururu/seller/domain/entity/Seller.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@ public class Seller extends BaseEntity {
3737
@Column(length = SellerConstants.EMAIL_MAX_LENGTH, nullable = false, unique = true)
3838
private String email;
3939

40-
@Column(length = 255, nullable = false) // 암호화된 비밀번호는 고정 길이
40+
@Column(length = SellerConstants.PASSWORD_COLUMN_LENGTH, nullable = false) // 암호화된 비밀번호는 고정 길이
4141
private String password; // 암호화된 비밀번호
4242

4343
@Column(length = SellerConstants.PHONE_MAX_LENGTH, nullable = false)
4444
private String phone;
4545

46-
@Column(length = 255) // 이미지 URL은 고정 길이
46+
@Column(length = SellerConstants.IMAGE_COLUMN_LENGTH) // 이미지 URL은 고정 길이
4747
private String image; // 브랜드 대표 이미지
4848

49-
@Column(length = 255, nullable = false) // 주소는 고정 길이
49+
@Column(length = SellerConstants.ADDRESS_COLUMN_LENGTH, nullable = false) // 주소는 고정 길이
5050
private String address1;
5151

52-
@Column(length = 255, nullable = false) // 주소는 고정 길이
52+
@Column(length = SellerConstants.ADDRESS_COLUMN_LENGTH, nullable = false) // 주소는 고정 길이
5353
private String address2;
5454

5555
@Column(length = SellerConstants.MAIL_ORDER_NUMBER_MAX_LENGTH, nullable = false)

src/main/java/com/ururulab/ururu/seller/service/SellerService.java

Lines changed: 139 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.ururulab.ururu.seller.service;
22

3+
import com.ururulab.ururu.global.exception.BusinessException;
4+
import com.ururulab.ururu.global.exception.error.ErrorCode;
35
import com.ururulab.ururu.global.util.MaskingUtils;
46
import com.ururulab.ururu.seller.dto.request.SellerSignupRequest;
57
import com.ururulab.ururu.seller.dto.response.SellerAvailabilityResponse;
@@ -32,31 +34,25 @@ public class SellerService {
3234
*/
3335
@Transactional
3436
public SellerResponse signup(final SellerSignupRequest request) {
37+
// null 체크 강화
38+
if (request == null) {
39+
log.error("판매자 회원가입 요청이 null입니다.");
40+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "회원가입 요청은 null일 수 없습니다.");
41+
}
42+
3543
log.info("판매자 회원가입 시작: {}", MaskingUtils.maskEmail(request.email()));
3644

37-
// 이메일 정규화 (소문자 변환)
38-
final String normalizedEmail = request.email().toLowerCase().trim();
45+
// 이메일 정규화
46+
final String normalizedEmail = normalizeEmail(request.email());
3947

4048
// 트랜잭션 범위 내에서 중복 체크 (1차 방어)
4149
validateSignupRequest(request, normalizedEmail);
4250

4351
// 비밀번호 암호화
44-
final String encodedPassword = passwordEncoder.encode(request.password());
52+
final String encodedPassword = encodePassword(request.password());
4553

46-
// 판매자 엔티티 생성
47-
final Seller seller = Seller.of(
48-
request.name(),
49-
request.businessName(),
50-
request.ownerName(),
51-
request.businessNumber(),
52-
normalizedEmail,
53-
encodedPassword,
54-
request.phone(),
55-
request.image(),
56-
request.address1(),
57-
request.address2(),
58-
request.mailOrderNumber()
59-
);
54+
// 정규화된 데이터로 판매자 엔티티 생성
55+
final Seller seller = createSellerEntity(request, normalizedEmail, encodedPassword);
6056

6157
try {
6258
// 저장 (DB UNIQUE 제약조건이 2차 방어선)
@@ -70,9 +66,131 @@ public SellerResponse signup(final SellerSignupRequest request) {
7066
} catch (DataIntegrityViolationException e) {
7167
// DB 레벨에서 중복 감지 (동시성 환경에서 최종 방어선)
7268
log.warn("DB 중복 제약조건 위반: {}", e.getMessage());
73-
throw new com.ururulab.ururu.global.exception.BusinessException(
74-
com.ururulab.ururu.global.exception.error.ErrorCode.DUPLICATE_EMAIL);
69+
throw new BusinessException(ErrorCode.DUPLICATE_EMAIL);
70+
}
71+
}
72+
73+
/**
74+
* 이메일 정규화
75+
*/
76+
private String normalizeEmail(final String email) {
77+
if (email == null || email.isBlank()) {
78+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "이메일은 필수입니다.");
79+
}
80+
return email.toLowerCase().trim();
81+
}
82+
83+
/**
84+
* 비밀번호 암호화
85+
*/
86+
private String encodePassword(final String password) {
87+
if (password == null || password.isBlank()) {
88+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "비밀번호는 필수입니다.");
89+
}
90+
return passwordEncoder.encode(password);
91+
}
92+
93+
/**
94+
* 판매자 엔티티 생성
95+
*/
96+
private Seller createSellerEntity(final SellerSignupRequest request, final String normalizedEmail, final String encodedPassword) {
97+
// 통신판매업 번호 정규화
98+
final String normalizedMailOrderNumber = normalizeField(request.mailOrderNumber());
99+
100+
// 사업자명 정규화
101+
final String normalizedBusinessName = normalizeField(request.businessName());
102+
103+
// 대표자명 정규화
104+
final String normalizedOwnerName = normalizeField(request.ownerName());
105+
106+
// 전화번호 정규화
107+
final String normalizedPhone = normalizeField(request.phone());
108+
109+
// 주소 정규화 (앞뒤 공백만 제거, 중간 공백 유지)
110+
final String normalizedAddress1 = normalizeField(request.address1());
111+
final String normalizedAddress2 = normalizeField(request.address2());
112+
113+
return Seller.of(
114+
request.name(),
115+
normalizedBusinessName,
116+
normalizedOwnerName,
117+
request.businessNumber(),
118+
normalizedEmail,
119+
encodedPassword,
120+
normalizedPhone,
121+
request.image(),
122+
normalizedAddress1,
123+
normalizedAddress2,
124+
normalizedMailOrderNumber
125+
);
126+
}
127+
128+
/**
129+
* 필드 정규화 (null 체크 포함)
130+
*/
131+
private String normalizeField(final String field) {
132+
return field != null ? field.trim() : null;
133+
}
134+
135+
//회원가입 요청 유효성 검증
136+
private void validateSignupRequest(final SellerSignupRequest request, final String normalizedEmail) {
137+
// 필수 필드 검증
138+
validateRequiredFields(request);
139+
140+
// 이메일 중복 체크
141+
if (!sellerRepository.isEmailAvailable(normalizedEmail)) {
142+
log.warn("이메일 중복: {}", MaskingUtils.maskEmail(normalizedEmail));
143+
throw new BusinessException(ErrorCode.DUPLICATE_EMAIL);
144+
}
145+
146+
// 사업자등록번호 정규화 후 중복 체크
147+
final String normalizedBusinessNumber = normalizeBusinessNumber(request.businessNumber());
148+
if (!sellerRepository.isBusinessNumberAvailable(normalizedBusinessNumber)) {
149+
log.warn("사업자등록번호 중복: {}", MaskingUtils.maskBusinessNumber(normalizedBusinessNumber));
150+
throw new BusinessException(ErrorCode.DUPLICATE_BUSINESS_NUMBER);
151+
}
152+
153+
// 브랜드명 정규화 후 중복 체크
154+
final String normalizedName = normalizeName(request.name());
155+
if (!sellerRepository.isNameAvailable(normalizedName)) {
156+
log.warn("브랜드명 중복: {}", normalizedName);
157+
throw new BusinessException(ErrorCode.DUPLICATE_BRAND_NAME);
158+
}
159+
}
160+
161+
/**
162+
* 필수 필드 검증
163+
*/
164+
private void validateRequiredFields(final SellerSignupRequest request) {
165+
if (request.name() == null || request.name().isBlank()) {
166+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "브랜드명은 필수입니다.");
167+
}
168+
if (request.businessNumber() == null || request.businessNumber().isBlank()) {
169+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "사업자등록번호는 필수입니다.");
170+
}
171+
if (request.password() == null || request.password().isBlank()) {
172+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "비밀번호는 필수입니다.");
173+
}
174+
}
175+
176+
/**
177+
* 사업자등록번호 정규화
178+
*/
179+
private String normalizeBusinessNumber(final String businessNumber) {
180+
if (businessNumber == null || businessNumber.isBlank()) {
181+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "사업자등록번호는 필수입니다.");
182+
}
183+
return businessNumber.trim();
184+
}
185+
186+
/**
187+
* 브랜드명 정규화
188+
*/
189+
private String normalizeName(final String name) {
190+
if (name == null || name.isBlank()) {
191+
throw new BusinessException(ErrorCode.INVALID_ARGUMENT, "브랜드명은 필수입니다.");
75192
}
193+
return name.trim();
76194
}
77195

78196
/**
@@ -121,31 +239,6 @@ public SellerResponse getSellerProfile(final Long sellerId) {
121239
return SellerResponse.from(seller);
122240
}
123241

124-
125-
//회원가입 요청 유효성 검증
126-
private void validateSignupRequest(final SellerSignupRequest request, final String normalizedEmail) {
127-
// 이메일 중복 체크
128-
if (!sellerRepository.isEmailAvailable(normalizedEmail)) {
129-
log.warn("이메일 중복: {}", MaskingUtils.maskEmail(normalizedEmail));
130-
throw new com.ururulab.ururu.global.exception.BusinessException(
131-
com.ururulab.ururu.global.exception.error.ErrorCode.DUPLICATE_EMAIL);
132-
}
133-
134-
// 사업자등록번호 중복 체크
135-
if (!sellerRepository.isBusinessNumberAvailable(request.businessNumber())) {
136-
log.warn("사업자등록번호 중복: {}", MaskingUtils.maskBusinessNumber(request.businessNumber()));
137-
throw new com.ururulab.ururu.global.exception.BusinessException(
138-
com.ururulab.ururu.global.exception.error.ErrorCode.DUPLICATE_BUSINESS_NUMBER);
139-
}
140-
141-
// 브랜드명 중복 체크
142-
if (!sellerRepository.isNameAvailable(request.name())) {
143-
log.warn("브랜드명 중복: {}", request.name());
144-
throw new com.ururulab.ururu.global.exception.BusinessException(
145-
com.ururulab.ururu.global.exception.error.ErrorCode.DUPLICATE_BRAND_NAME);
146-
}
147-
}
148-
149242
/**
150243
* 이메일로 판매자 조회
151244
*
@@ -156,14 +249,12 @@ private void validateSignupRequest(final SellerSignupRequest request, final Stri
156249
public Seller findByEmail(final String email) {
157250
final String normalizedEmail = email.toLowerCase().trim();
158251
return sellerRepository.findByEmail(normalizedEmail)
159-
.orElseThrow(() -> new com.ururulab.ururu.global.exception.BusinessException(
160-
com.ururulab.ururu.global.exception.error.ErrorCode.SELLER_NOT_FOUND));
252+
.orElseThrow(() -> new BusinessException(ErrorCode.SELLER_NOT_FOUND));
161253
}
162254

163255
// 활성 판매자 조회
164256
private Seller findActiveSellerById(final Long sellerId) {
165257
return sellerRepository.findActiveSeller(sellerId)
166-
.orElseThrow(() -> new com.ururulab.ururu.global.exception.BusinessException(
167-
com.ururulab.ururu.global.exception.error.ErrorCode.SELLER_NOT_FOUND, sellerId));
258+
.orElseThrow(() -> new BusinessException(ErrorCode.SELLER_NOT_FOUND, sellerId));
168259
}
169260
}

0 commit comments

Comments
 (0)