Files
Gnuboard7/tests/Unit/ActivityLog/ActivityLogProcessorTest.php
2026-04-01 10:30:52 +09:00

162 lines
4.5 KiB
PHP

<?php
namespace Tests\Unit\ActivityLog;
use App\ActivityLog\ActivityLogProcessor;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Auth;
use Monolog\Level;
use Monolog\LogRecord;
use Tests\TestCase;
/**
* ActivityLogProcessor 테스트
*
* Monolog Processor가 요청별 공통 데이터(user_id, ip_address, user_agent)를
* 올바르게 자동 주입하는지 검증합니다.
*/
class ActivityLogProcessorTest extends TestCase
{
use RefreshDatabase;
private ActivityLogProcessor $processor;
protected function setUp(): void
{
parent::setUp();
$this->processor = new ActivityLogProcessor;
}
/**
* 인증된 사용자의 user_id가 자동 주입되는지 확인
*/
public function test_auto_injects_user_id_from_auth(): void
{
$user = User::factory()->create();
Auth::login($user);
$record = $this->createRecord();
$result = ($this->processor)($record);
$this->assertEquals($user->id, $result->context['user_id']);
}
/**
* ip_address가 자동 주입되는지 확인
*/
public function test_auto_injects_ip_address(): void
{
$record = $this->createRecord();
$result = ($this->processor)($record);
$this->assertArrayHasKey('ip_address', $result->context);
}
/**
* user_agent가 자동 주입되는지 확인
*/
public function test_auto_injects_user_agent(): void
{
$record = $this->createRecord();
$result = ($this->processor)($record);
$this->assertArrayHasKey('user_agent', $result->context);
}
/**
* 명시적으로 전달된 user_id를 덮어쓰지 않는지 확인
*/
public function test_does_not_overwrite_explicit_user_id(): void
{
$user = User::factory()->create();
Auth::login($user);
$explicitUserId = 99999;
$record = $this->createRecord(['user_id' => $explicitUserId]);
$result = ($this->processor)($record);
$this->assertEquals($explicitUserId, $result->context['user_id']);
}
/**
* 명시적으로 전달된 ip_address를 덮어쓰지 않는지 확인
*/
public function test_does_not_overwrite_explicit_ip_address(): void
{
$record = $this->createRecord(['ip_address' => '192.168.1.100']);
$result = ($this->processor)($record);
$this->assertEquals('192.168.1.100', $result->context['ip_address']);
}
/**
* 명시적으로 전달된 user_agent를 덮어쓰지 않는지 확인
*/
public function test_does_not_overwrite_explicit_user_agent(): void
{
$record = $this->createRecord(['user_agent' => 'CustomBot/1.0']);
$result = ($this->processor)($record);
$this->assertEquals('CustomBot/1.0', $result->context['user_agent']);
}
/**
* 인증된 사용자가 없으면 user_id가 null인지 확인
*/
public function test_user_id_defaults_to_null_when_no_auth(): void
{
Auth::logout();
$record = $this->createRecord();
$result = ($this->processor)($record);
$this->assertNull($result->context['user_id']);
}
/**
* Processor가 원본 레코드를 변경하지 않고 새 레코드를 반환하는지 확인
*/
public function test_returns_new_log_record_instance(): void
{
$record = $this->createRecord();
$result = ($this->processor)($record);
// LogRecord는 불변 객체 — with()로 새 인스턴스 반환
$this->assertNotSame($record, $result);
$this->assertInstanceOf(LogRecord::class, $result);
}
/**
* 기존 context 데이터가 보존되는지 확인
*/
public function test_preserves_existing_context_data(): void
{
$record = $this->createRecord([
'log_type' => 'admin',
'description_key' => 'test.key',
]);
$result = ($this->processor)($record);
$this->assertEquals('admin', $result->context['log_type']);
$this->assertEquals('test.key', $result->context['description_key']);
}
/**
* 테스트용 LogRecord를 생성합니다.
*
* @param array $context 추가 context 데이터
* @return LogRecord
*/
private function createRecord(array $context = []): LogRecord
{
return new LogRecord(
datetime: new \DateTimeImmutable,
channel: 'activity',
level: Level::Info,
message: 'test.action',
context: $context,
);
}
}