v7.0.0-beta.2 release
This commit is contained in:
@@ -88,6 +88,38 @@ class SetTimezoneTest extends TestCase
|
||||
$this->assertEquals('Asia/Seoul', SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 기존 화이트리스트에 없던 IANA 타임존도 허용되는지 테스트합니다.
|
||||
*
|
||||
* @dataProvider arbitraryIanaTimezoneProvider
|
||||
*/
|
||||
public function test_arbitrary_iana_timezone_accepted(string $timezone): void
|
||||
{
|
||||
$user = User::factory()->create(['timezone' => $timezone]);
|
||||
Auth::login($user);
|
||||
|
||||
$request = Request::create('/api/test', 'GET');
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
|
||||
$this->assertEquals($timezone, SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array{string}>
|
||||
*/
|
||||
public static function arbitraryIanaTimezoneProvider(): array
|
||||
{
|
||||
return [
|
||||
'Africa/Cairo' => ['Africa/Cairo'],
|
||||
'Pacific/Auckland' => ['Pacific/Auckland'],
|
||||
'America/Chicago' => ['America/Chicago'],
|
||||
'Asia/Dubai' => ['Asia/Dubai'],
|
||||
'Antarctica/McMurdo' => ['Antarctica/McMurdo'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 타임존 설정이 없는 경우 기본값이 적용되는지 테스트합니다.
|
||||
*/
|
||||
@@ -147,6 +179,8 @@ class SetTimezoneTest extends TestCase
|
||||
config(['geoip.enabled' => true]);
|
||||
config(['geoip.database_path' => $dbPath]);
|
||||
config(['geoip.cache.enabled' => false]);
|
||||
// 마스터 스위치 ON (g7_core_settings 가드 통과)
|
||||
config(['g7_settings.core.geoip.feature_enabled' => true]);
|
||||
|
||||
// GeoIpService 목업: 특정 타임존 반환
|
||||
$mockGeoIpService = $this->createMock(GeoIpService::class);
|
||||
@@ -156,7 +190,6 @@ class SetTimezoneTest extends TestCase
|
||||
$this->app->instance(GeoIpService::class, $mockGeoIpService);
|
||||
|
||||
$request = Request::create('/api/test', 'GET');
|
||||
// X-Timezone 헤더 없음
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
@@ -164,6 +197,56 @@ class SetTimezoneTest extends TestCase
|
||||
$this->assertEquals('America/New_York', SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 마스터 스위치(geoip.feature_enabled)가 OFF면 GeoIP 조회가 완전히 스킵되는지 테스트합니다.
|
||||
*
|
||||
* 미들웨어 레벨의 short-circuit을 검증합니다 — GeoIpService::getTimezoneByIp()가
|
||||
* 단 한 번도 호출되지 않아야 합니다.
|
||||
*/
|
||||
public function test_geoip_skipped_when_feature_disabled(): void
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
config(['g7_settings.core.geoip.feature_enabled' => false]);
|
||||
|
||||
$mockGeoIpService = $this->createMock(GeoIpService::class);
|
||||
$mockGeoIpService->expects($this->never())
|
||||
->method('getTimezoneByIp');
|
||||
|
||||
$this->app->instance(GeoIpService::class, $mockGeoIpService);
|
||||
|
||||
$request = Request::create('/api/test', 'GET');
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
|
||||
$this->assertEquals('Asia/Seoul', SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 마스터 스위치가 ON이면 GeoIP 조회가 수행되는지 테스트합니다.
|
||||
*/
|
||||
public function test_geoip_invoked_when_feature_enabled(): void
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
config(['g7_settings.core.geoip.feature_enabled' => true]);
|
||||
|
||||
$mockGeoIpService = $this->createMock(GeoIpService::class);
|
||||
$mockGeoIpService->expects($this->once())
|
||||
->method('getTimezoneByIp')
|
||||
->willReturn('America/Chicago');
|
||||
|
||||
$this->app->instance(GeoIpService::class, $mockGeoIpService);
|
||||
|
||||
$request = Request::create('/api/test', 'GET');
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
|
||||
$this->assertEquals('America/Chicago', SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* X-Timezone 헤더가 GeoIP보다 우선하는지 테스트합니다.
|
||||
*/
|
||||
@@ -213,7 +296,10 @@ class SetTimezoneTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* 실제 GeoIP DB를 사용한 통합 테스트 (한국 IP)
|
||||
* 실제 GeoIP DB를 사용한 통합 테스트 (한국 IP).
|
||||
*
|
||||
* 마스터 스위치 ON + 실제 mmdb 파일 + 실제 GeoIpService로
|
||||
* 미들웨어 전 계층(가드 → Service → Reader)이 정상 동작하는지 검증합니다.
|
||||
*/
|
||||
public function test_real_geoip_with_korean_ip(): void
|
||||
{
|
||||
@@ -227,8 +313,9 @@ class SetTimezoneTest extends TestCase
|
||||
config(['geoip.enabled' => true]);
|
||||
config(['geoip.database_path' => $dbPath]);
|
||||
config(['geoip.cache.enabled' => false]);
|
||||
config(['g7_settings.core.geoip.feature_enabled' => true]);
|
||||
|
||||
// 새 GeoIpService 인스턴스 생성
|
||||
// 실제 GeoIpService 사용 (mock 아님)
|
||||
$this->app->forgetInstance(GeoIpService::class);
|
||||
$this->app->singleton(GeoIpService::class);
|
||||
|
||||
@@ -241,4 +328,134 @@ class SetTimezoneTest extends TestCase
|
||||
|
||||
$this->assertEquals('Asia/Seoul', SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 실제 GeoIP DB를 사용한 통합 테스트 (미국 IP).
|
||||
*
|
||||
* 한국 외 지역 IP에서도 올바른 타임존이 감지되는지 검증합니다.
|
||||
*/
|
||||
public function test_real_geoip_with_us_ip(): void
|
||||
{
|
||||
$dbPath = storage_path('app/geoip/GeoLite2-City.mmdb');
|
||||
|
||||
if (! file_exists($dbPath)) {
|
||||
$this->markTestSkipped('GeoLite2-City.mmdb 파일이 없습니다.');
|
||||
}
|
||||
|
||||
Auth::logout();
|
||||
config(['geoip.enabled' => true]);
|
||||
config(['geoip.database_path' => $dbPath]);
|
||||
config(['geoip.cache.enabled' => false]);
|
||||
config(['g7_settings.core.geoip.feature_enabled' => true]);
|
||||
|
||||
$this->app->forgetInstance(GeoIpService::class);
|
||||
$this->app->singleton(GeoIpService::class);
|
||||
|
||||
$request = Request::create('/api/test', 'GET', [], [], [], [
|
||||
'REMOTE_ADDR' => '8.8.8.8', // Google Public DNS (미국)
|
||||
]);
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
|
||||
// Google DNS는 미국 소재 — America/* 타임존이어야 함
|
||||
$timezone = SetTimezone::getTimezone();
|
||||
$this->assertStringStartsWith('America/', $timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* 실제 GeoIP DB를 사용한 통합 테스트 (일본 IP).
|
||||
*/
|
||||
public function test_real_geoip_with_japanese_ip(): void
|
||||
{
|
||||
$dbPath = storage_path('app/geoip/GeoLite2-City.mmdb');
|
||||
|
||||
if (! file_exists($dbPath)) {
|
||||
$this->markTestSkipped('GeoLite2-City.mmdb 파일이 없습니다.');
|
||||
}
|
||||
|
||||
Auth::logout();
|
||||
config(['geoip.enabled' => true]);
|
||||
config(['geoip.database_path' => $dbPath]);
|
||||
config(['geoip.cache.enabled' => false]);
|
||||
config(['g7_settings.core.geoip.feature_enabled' => true]);
|
||||
|
||||
$this->app->forgetInstance(GeoIpService::class);
|
||||
$this->app->singleton(GeoIpService::class);
|
||||
|
||||
$request = Request::create('/api/test', 'GET', [], [], [], [
|
||||
'REMOTE_ADDR' => '203.178.136.1', // WIDE Project (일본)
|
||||
]);
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
|
||||
$this->assertEquals('Asia/Tokyo', SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 마스터 스위치 OFF 시 실제 mmdb 파일이 있어도 GeoIP가 스킵되는지 테스트합니다.
|
||||
*/
|
||||
public function test_real_geoip_skipped_when_feature_disabled_even_with_db(): void
|
||||
{
|
||||
$dbPath = storage_path('app/geoip/GeoLite2-City.mmdb');
|
||||
|
||||
if (! file_exists($dbPath)) {
|
||||
$this->markTestSkipped('GeoLite2-City.mmdb 파일이 없습니다.');
|
||||
}
|
||||
|
||||
Auth::logout();
|
||||
config(['geoip.enabled' => true]);
|
||||
config(['geoip.database_path' => $dbPath]);
|
||||
config(['geoip.cache.enabled' => false]);
|
||||
// 마스터 스위치 OFF
|
||||
config(['g7_settings.core.geoip.feature_enabled' => false]);
|
||||
|
||||
$this->app->forgetInstance(GeoIpService::class);
|
||||
$this->app->singleton(GeoIpService::class);
|
||||
|
||||
$request = Request::create('/api/test', 'GET', [], [], [], [
|
||||
'REMOTE_ADDR' => '168.126.63.1', // 한국 IP인데 마스터 OFF
|
||||
]);
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
|
||||
// GeoIP 스킵 → 기본값 적용
|
||||
$this->assertEquals('Asia/Seoul', SetTimezone::getTimezone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 인증 사용자 타임존이 GeoIP 결과보다 우선하는지 통합 테스트합니다.
|
||||
*/
|
||||
public function test_authenticated_user_timezone_overrides_geoip(): void
|
||||
{
|
||||
$dbPath = storage_path('app/geoip/GeoLite2-City.mmdb');
|
||||
|
||||
if (! file_exists($dbPath)) {
|
||||
$this->markTestSkipped('GeoLite2-City.mmdb 파일이 없습니다.');
|
||||
}
|
||||
|
||||
// 유럽 타임존 사용자가 한국 IP에서 접속하는 시나리오
|
||||
$user = User::factory()->create(['timezone' => 'Europe/London']);
|
||||
Auth::login($user);
|
||||
|
||||
config(['geoip.enabled' => true]);
|
||||
config(['geoip.database_path' => $dbPath]);
|
||||
config(['geoip.cache.enabled' => false]);
|
||||
config(['g7_settings.core.geoip.feature_enabled' => true]);
|
||||
|
||||
$this->app->forgetInstance(GeoIpService::class);
|
||||
$this->app->singleton(GeoIpService::class);
|
||||
|
||||
$request = Request::create('/api/test', 'GET', [], [], [], [
|
||||
'REMOTE_ADDR' => '168.126.63.1', // 한국 IP
|
||||
]);
|
||||
|
||||
$middleware = $this->createMiddleware();
|
||||
$middleware->handle($request, $this->getNextClosure());
|
||||
|
||||
// 인증 사용자 타임존이 GeoIP(Asia/Seoul)보다 우선
|
||||
$this->assertEquals('Europe/London', SetTimezone::getTimezone());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user