\Tests\FeatureLogUserLoginTest

登录日志监听器

被测对象:WriteUserLoginLog::handle(LogUserLoginEvent → td_log_user_login) 守护约定:成功=插入会话行(session_id 存会话指纹而非原始 token_id, 防日志泄露会话劫持,浏览器/OS 自 UA 解析); 失败=插行记真实原因(用户不存在时 user_id 为空); 登出=回填原行 logout_time 不增行;被踢=原行置状态 2 并回填, 无原行时补记;trace_id 恒生成。

Summary

Methods
Properties
Constants
test_login_success_records_row()
test_login_failed_records_reason()
test_logout_fills_logout_time_without_new_row()
test_kicked_marks_session_closed()
No public properties found
No constants found
requireRedis()
buildCacheRegistry()
setUp()
No protected properties found
N/A
givenRequest()
No private properties found
N/A

Methods

test_login_success_records_row()

test_login_success_records_row() : void

登录成功:插行并解析浏览器/OS、绑定会话标识、生成 trace_id

test_login_failed_records_reason()

test_login_failed_records_reason() : void

登录失败:无用户也落行(user_id 为空),记真实失败原因

test_logout_fills_logout_time_without_new_row()

test_logout_fills_logout_time_without_new_row() : void

登出:回填原会话行 logout_time,不产生新行

test_kicked_marks_session_closed()

test_kicked_marks_session_closed() : void

被踢下线:原会话行置状态 2 并回填 logout_time;无原行(如跨实例)补记一行

requireRedis()

requireRedis() : void

Redis 依赖探针:直连 Redis 的测试(限流/会话/验证码)在无 Redis 环境(如 CI) 跳过而非失败——其余用例不受影响。CI 可设 TEST_REQUIRE_REDIS=1 强制模式: Redis 不可达即失败而非跳过,安全回归套件不允许静默消失。

buildCacheRegistry()

buildCacheRegistry(array  $items) : void

建缓存注册表最小 schema(td_sys_cache)并灌入注册项。

测试跑 sqlite :memory:,生产迁移含 PostgreSQL 专属 DDL 跑不通(DataScopeServiceTest 同因自建 schema); 而 CacheManager::registry() 现已从数据库表读取——凡走注册表的测试(remember/get/key/失效推导) 必须在 setUp 先调用本方法,否则注册表为空、remember 未登记名会走「自动登记」路径。

Parameters

array $items

setUp()

setUp() : void

建 td_log_user_login 最小 schema(sqlite :memory: 自建,与生产迁移列对齐)

givenRequest()

givenRequest() : \Illuminate\Http\Request

构造带 UA 与 token_id Cookie 的请求并置为当前请求(监听器从 request() 取上下文)

Returns

\Illuminate\Http\Request —