Files
Gnuboard7/tests/Unit/Requests/Ecommerce/StoreEcommerceSettingsRequestCustomValidationTest.php
T
2026-05-11 11:29:41 +09:00

462 lines
14 KiB
PHP

<?php
namespace Tests\Unit\Requests\Ecommerce;
use Illuminate\Support\Facades\App;
use Modules\Sirsoft\Ecommerce\Http\Requests\Admin\StoreEcommerceSettingsRequest;
use Tests\TestCase;
/**
* StoreEcommerceSettingsRequest 커스텀 검증 테스트
*
* withValidator 메서드의 커스텀 검증 로직을 테스트합니다.
* - 통화 코드 중복 검증
* - 통화명 필수 검증 (최소 하나의 로케일)
*/
class StoreEcommerceSettingsRequestCustomValidationTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
// 한국어 로케일 설정
App::setLocale('ko');
// sirsoft-ecommerce 모듈 번역은 단위 테스트 환경에서 자동 로드되지 않으므로 수동 등록
app('translator')->addLines([
'validation.custom.language_currency.currencies.name_required' => '통화명은 최소 하나의 언어로 입력해야 합니다.',
'validation.custom.language_currency.currencies.duplicate_code' => '중복된 통화 코드: :code',
], 'ko', 'sirsoft-ecommerce');
}
/**
* FormRequest를 통한 검증 수행 (커스텀 로직 포함)
*
* @param array $data 검증할 데이터
*
* @return \Illuminate\Validation\Validator
*/
protected function validateWithCustomRules(array $data): \Illuminate\Validation\Validator
{
$request = new StoreEcommerceSettingsRequest();
$request->merge($data);
$validator = \Illuminate\Support\Facades\Validator::make($data, $request->rules());
// withValidator 메서드 실행
$request->withValidator($validator);
return $validator;
}
/**
* 통화 코드 중복 - 중복된 코드가 있으면 실패
*/
public function test_duplicate_currency_codes_fail_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => ['ko' => '원'],
],
[
'code' => 'KRW', // 중복
'name' => ['ko' => '원 (중복)'],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertTrue($validator->fails());
$this->assertArrayHasKey('language_currency.currencies.1.code', $validator->errors()->toArray());
}
/**
* 통화 코드 중복 - 대소문자 무시하여 중복 검출
*/
public function test_duplicate_currency_codes_case_insensitive(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => ['ko' => '원'],
],
[
'code' => 'krw', // 소문자로 중복
'name' => ['ko' => '원 (소문자)'],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertTrue($validator->fails());
$this->assertArrayHasKey('language_currency.currencies.1.code', $validator->errors()->toArray());
}
/**
* 통화 코드 중복 - 고유한 코드들은 통과
*/
public function test_unique_currency_codes_pass_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => ['ko' => '원'],
],
[
'code' => 'USD',
'name' => ['ko' => '달러'],
],
[
'code' => 'JPY',
'name' => ['ko' => '엔'],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertFalse($validator->fails());
}
/**
* 통화명 필수 - 빈 배열이면 실패
*/
public function test_empty_currency_name_array_fails_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => [], // 빈 배열
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertTrue($validator->fails());
$this->assertArrayHasKey('language_currency.currencies.0.name', $validator->errors()->toArray());
}
/**
* 통화명 필수 - name이 없으면 실패
*/
public function test_missing_currency_name_fails_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
// name 필드 누락
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertTrue($validator->fails());
$this->assertArrayHasKey('language_currency.currencies.0.name', $validator->errors()->toArray());
}
/**
* 통화명 필수 - 모든 로케일이 빈 문자열이면 실패
*/
public function test_all_empty_locale_names_fail_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => [
'ko' => '',
'en' => '',
],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertTrue($validator->fails());
$this->assertArrayHasKey('language_currency.currencies.0.name', $validator->errors()->toArray());
}
/**
* 통화명 필수 - 모든 로케일이 공백만 있으면 실패
*/
public function test_whitespace_only_locale_names_fail_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => [
'ko' => ' ',
'en' => "\t\n",
],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertTrue($validator->fails());
$this->assertArrayHasKey('language_currency.currencies.0.name', $validator->errors()->toArray());
}
/**
* 통화명 필수 - 하나의 로케일에만 이름이 있으면 통과
*/
public function test_single_locale_name_passes_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => [
'ko' => '원',
// en은 없음
],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertFalse($validator->fails());
}
/**
* 통화명 필수 - 일부 로케일만 비어있어도 다른 로케일에 값이 있으면 통과
*/
public function test_partial_locale_names_pass_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => [
'ko' => '원',
'en' => '', // 빈 문자열이지만 ko에 값이 있음
],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertFalse($validator->fails());
}
/**
* 통화명 필수 - 여러 통화 중 일부만 문제가 있는 경우
*/
public function test_mixed_valid_invalid_currencies(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => ['ko' => '원'], // 유효
],
[
'code' => 'USD',
'name' => [], // 무효 - 빈 배열
],
[
'code' => 'JPY',
'name' => ['ko' => '엔'], // 유효
],
[
'code' => 'EUR',
'name' => ['ko' => '', 'en' => ''], // 무효 - 모두 빈 문자열
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertTrue($validator->fails());
$errors = $validator->errors()->toArray();
// 인덱스 1과 3에서 오류 발생
$this->assertArrayHasKey('language_currency.currencies.1.name', $errors);
$this->assertArrayHasKey('language_currency.currencies.3.name', $errors);
// 인덱스 0과 2는 오류 없음
$this->assertArrayNotHasKey('language_currency.currencies.0.name', $errors);
$this->assertArrayNotHasKey('language_currency.currencies.2.name', $errors);
}
/**
* 통화 목록이 비어있으면 커스텀 검증 건너뜀
*/
public function test_empty_currencies_array_skips_custom_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [],
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertFalse($validator->fails());
}
/**
* 통화 설정이 없으면 커스텀 검증 건너뜀
*/
public function test_missing_currencies_skips_custom_validation(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'default_language' => 'ko',
],
];
$validator = $this->validateWithCustomRules($data);
$this->assertFalse($validator->fails());
}
/**
* 오류 메시지가 다국어로 표시되는지 확인
*
* 빈 배열이 아닌 모든 로케일이 빈 문자열인 경우 테스트
* (빈 배열은 기본 required_with 검증에서 먼저 잡힘)
*/
public function test_error_messages_are_localized(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => ['ko' => '', 'en' => ''], // 모든 로케일이 빈 문자열
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$errors = $validator->errors()->toArray();
$this->assertStringContainsString(
'최소 하나의 언어로 입력',
$errors['language_currency.currencies.0.name'][0]
);
}
/**
* 중복 코드 오류 메시지가 다국어로 표시되는지 확인
*/
public function test_duplicate_code_error_message_is_localized(): void
{
$data = [
'basic_info' => [
'shop_name' => '테스트 쇼핑몰',
'route_path' => 'shop',
],
'language_currency' => [
'currencies' => [
[
'code' => 'KRW',
'name' => ['ko' => '원'],
],
[
'code' => 'KRW',
'name' => ['ko' => '원 중복'],
],
],
],
];
$validator = $this->validateWithCustomRules($data);
$errors = $validator->errors()->toArray();
$this->assertStringContainsString(
'중복된 통화 코드',
$errors['language_currency.currencies.1.code'][0]
);
}
}