Files
Gnuboard7/plugins/_bundled/sirsoft-verification_kginicis/tests/Feature/Identity/InicisVerifyReuseGuardTest.php
T
2026-07-01 10:30:32 +09:00

77 lines
2.6 KiB
PHP

<?php
namespace Plugins\Sirsoft\VerificationKginicis\Tests\Feature\Identity;
use App\Enums\IdentityVerificationStatus;
use App\Models\IdentityVerificationLog;
use Plugins\Sirsoft\VerificationKginicis\Exceptions\AlreadyConsumedException;
use Plugins\Sirsoft\VerificationKginicis\Identity\InicisIdentityProvider;
use Plugins\Sirsoft\VerificationKginicis\Tests\PluginTestCase;
/**
* 회귀 테스트 — 응답 재사용 토큰 무제한 재발급 차단.
*
* 배경: verify()/cancel() 의 재처리 가드가 `$log->status === 'verified'` 로 enum 캐스팅된
* status 와 문자열을 비교해 항상 false → 이미 처리된 mTxId 로 토큰을 무제한 재발급받을 수 있었다.
* `$log->isVerified()` (=== IdentityVerificationStatus::Verified) 로 정정.
*
* @since 1.0.0-beta.1
*/
class InicisVerifyReuseGuardTest extends PluginTestCase
{
/**
* verified 상태 challenge 로그를 생성한다.
*
* @return IdentityVerificationLog
*/
private function makeVerifiedLog(): IdentityVerificationLog
{
return IdentityVerificationLog::create([
'id' => (string) \Illuminate\Support\Str::uuid(),
'provider_id' => InicisIdentityProvider::PROVIDER_ID,
'purpose' => 'signup',
'channel' => 'ipin',
'user_id' => null,
'target_hash' => hash('sha256', 'reuse@example.com'),
'status' => IdentityVerificationStatus::Verified,
'render_hint' => 'text_code',
'attempts' => 0,
'max_attempts' => 0,
]);
}
private function provider(): InicisIdentityProvider
{
return app(InicisIdentityProvider::class);
}
/**
* @scenario mode=live,live_credentials=filled
* @effects verify_on_already_verified_log_throws_already_consumed_exception
*/
public function test_verify_on_already_verified_log_throws_already_consumed(): void
{
$log = $this->makeVerifiedLog();
$this->expectException(AlreadyConsumedException::class);
$this->provider()->verify($log->id, ['mTxId' => 'dummy-mtxid']);
}
/**
* @scenario mode=live,live_credentials=filled
* @effects cancel_on_already_verified_log_returns_false_and_keeps_verified_status
*/
public function test_cancel_on_already_verified_log_returns_false(): void
{
$log = $this->makeVerifiedLog();
$result = $this->provider()->cancel($log->id);
$this->assertFalse($result);
// 상태가 cancelled 로 바뀌지 않고 verified 로 보존되어야 한다.
$this->assertTrue($log->fresh()->isVerified());
}
}