| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- <?php
- namespace Tests\Unit;
- use App\Jobs\IpRiskDetection;
- use Illuminate\Support\Facades\Redis;
- use Tests\TestCase;
- /**
- * IpRiskDetection Job 单元测试
- *
- * 测试 Job handle() 方法的核心逻辑:
- * - 重复 IP 跳过检测
- * - 空参数跳过
- * - Redis Hash 写入/读取/删除
- */
- class IpRiskDetectionTest extends TestCase
- {
- // ==================== 边界值:空参数 ====================
- /** @test */
- public function test_skips_when_user_id_is_empty()
- {
- $job = new IpRiskDetection(0, '1.2.3.4');
- $job->handle();
- $this->assertTrue(true);
- }
- /** @test */
- public function test_skips_when_ip_is_empty()
- {
- $job = new IpRiskDetection(12345, '');
- $job->handle();
- $this->assertTrue(true);
- }
- /** @test */
- public function test_skips_when_both_are_empty()
- {
- $job = new IpRiskDetection(0, '');
- $job->handle();
- $this->assertTrue(true);
- }
- // ==================== 重复检测跳过 ====================
- /** @test */
- public function test_skips_detection_when_same_ip_in_today_hash()
- {
- $userId = 10001;
- $ip = '73.162.0.1';
- $todayKey = IpRiskDetection::LAST_DETECTED_PREFIX . date('Ymd');
- Redis::shouldReceive('hget')
- ->once()
- ->with($todayKey, $userId)
- ->andReturn($ip);
- $job = new IpRiskDetection($userId, $ip);
- $job->handle();
- $this->assertTrue(true);
- }
- /** @test */
- public function test_skips_detection_when_same_ip_in_yesterday_hash()
- {
- $userId = 10001;
- $ip = '73.162.0.1';
- $todayKey = IpRiskDetection::LAST_DETECTED_PREFIX . date('Ymd');
- $yesterdayKey = IpRiskDetection::LAST_DETECTED_PREFIX . date('Ymd', strtotime('-1 day'));
- // today miss → yesterday hit
- Redis::shouldReceive('hget')
- ->once()
- ->with($todayKey, $userId)
- ->andReturn(null);
- Redis::shouldReceive('hget')
- ->once()
- ->with($yesterdayKey, $userId)
- ->andReturn($ip);
- $job = new IpRiskDetection($userId, $ip);
- $job->handle();
- $this->assertTrue(true);
- }
- // ==================== 容器内集成测试 ====================
- /**
- * 以下测试需要模拟 IpRiskService,但 Job 内部通过 new 创建服务实例。
- *
- * 测试策略:
- * - IpRiskService 自身的 detect() 逻辑已在 IpRiskServiceTest 中覆盖
- * - Job 与 Redis 的交互在上述测试中覆盖
- * - 完整链路测试建议在验收环境中通过实际登录/注册流程验证
- */
- /** @test */
- public function test_has_correct_constants()
- {
- $this->assertEquals('ip_risk_users', IpRiskDetection::REDIS_HASH_KEY);
- $this->assertEquals('ip_risk_last_detected:', IpRiskDetection::LAST_DETECTED_PREFIX);
- $this->assertEquals(3, IpRiskDetection::DETECTION_WINDOW_DAYS);
- }
- /** @test */
- public function test_implements_should_queue()
- {
- $job = new IpRiskDetection(1, '1.2.3.4');
- $this->assertInstanceOf(\Illuminate\Contracts\Queue\ShouldQueue::class, $job);
- }
- }
|