From 119b49cf83daa36eae0d174c49ca961f9ebcbdf7 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Thu, 5 Nov 2026 20:06:55 +0800 Subject: [PATCH] =?UTF-8?q?test(presenter):=20M132=20=E7=83=98=E7=84=99?= =?UTF-8?q?=E4=BA=86=20client=20id=20=E7=9A=84=E6=9E=84=E5=BB=BA=E9=87=8C?= =?UTF-8?q?=E8=AE=A9=E5=85=A5=E5=8F=A3=E9=94=9A=E7=9B=B4=E6=8E=A5=E7=BA=A2?= =?UTF-8?q?=EF=BC=88r2=20P2-1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit r2 复审实测:`ULL_MSA_CLIENT_ID=fake-0000-test-id` 构建 + 同一处变异 → `ok. 22 passed`。 原因是我上一条写成了 `if is_configured() { assert!(CLIENT_ID_BUILD.is_some_and(..)); return; }` ——`remove_var` 之后 `is_configured()` 等价于 `CLIENT_ID_BUILD` 非空,随后的 `assert!` 判的是 同一条件的反面,恒真、无失败路径,于是锚在那种构建里**绿着失效**。这正是本 mission 要防的 「守门空跑」形态,而我报告里还把它写成了「只允许是这个原因」,与代码不符。 改成 `if let Some(source) = client_id_status().source() { panic!(..) }`:环境变量摘掉后仍 报告已配置,就带着 `source=` 和两条出路(不带 id 构建 / 给 `resolve_client_id` 加接缝)直接 红,逼人做决定。没有 `#[ignore]`、没有开关;正常的「两处都没有 id」构建照旧跑两条真登录流。 验证(贴原生输出): - 注入 id + 变异 → FAILED(panic,`source=Build`),旧代码此处是 `ok. 22 passed`; - 注入 id + 无变异 → 也 FAILED(这才是重点:不是靠变异才红,而是拒绝空跑); - 无 id + 变异 → `220 passed; 1 failed`,红的正是这条锚; - 无 id 正常 → `221 passed; 1 ignored`。 --- crates/presenter/src/host/accounts/tests.rs | 23 ++++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/crates/presenter/src/host/accounts/tests.rs b/crates/presenter/src/host/accounts/tests.rs index d8c9be9..cce5d36 100644 --- a/crates/presenter/src/host/accounts/tests.rs +++ b/crates/presenter/src/host/accounts/tests.rs @@ -11,7 +11,7 @@ use std::time::Duration; -use unlucky_core::auth::microsoft::{client_id_status, CLIENT_ID_BUILD, CLIENT_ID_ENV}; +use unlucky_core::auth::microsoft::{client_id_status, CLIENT_ID_ENV}; use unlucky_core::auth::AuthError; use super::*; @@ -91,6 +91,10 @@ fn only_a_missing_client_id_becomes_the_config_gap_code() { /// 的唯一开关,而 `auth_failure` 自己的单测对它一声不响。 /// 零网络:`MicrosoftAuth::from_env` 在 id 判定处就地早退,连 HTTP 客户端都不建,所以这里 /// 不需要任何桩,也不会因为没网而红。 +/// +/// **它要求一个「两处都没有 client id」的构建**:构建期烘焙了 id(`option_env!`)的构建里它 +/// `panic!` 而不是跳过——跳过就等于让这条锚悄悄失效(r2 复审实测过那种形态),红着喊人才 +/// 逼得人做决定(不带 id 构建,或给 `resolve_client_id` 加接缝后重写这条锚)。 #[test] fn a_missing_client_id_reaches_the_login_panel_as_a_config_gap() { // 环境变量是**进程级**的:动它的用例必须串行(core 侧同一套写法),否则并行跑互相污染。 @@ -111,14 +115,17 @@ fn a_missing_client_id_reaches_the_login_panel_as_a_config_gap() { } let _restore = Restore(saved); - if client_id_status().is_configured() { - // 构建期注入过 id(`ULL_MSA_CLIENT_ID= cargo build`)的构建里没有「缺配置」可言; - // 本仓库 CI 与本地都不注入,走到这里只允许是这个原因(不是「跳过」开关)。 - assert!( - CLIENT_ID_BUILD.is_some_and(|value| !value.trim().is_empty()), - "没配环境变量却报告已配置" + // 环境变量已经摘掉了,此时若仍报告「已配置」,来源只可能是构建期注入 + // (`ULL_MSA_CLIENT_ID= cargo build` ⇒ `option_env!`),或者 `resolve_client_id` 的 + // 实现变了。**这种构建里必须红**:这条锚验证不了缺 id 路径,静默 `return` 就是让锚悄悄失效 + // (r2 复审实测:注入 id + 同一变异 → 全绿 22 passed,正是塔台最怕的「守门空跑」形态)。 + if let Some(source) = client_id_status().source() { + panic!( + "这条锚要求「两处都没有 client id」的构建,但二进制里 client id 已被报告为已配置\ + (source={source:?},环境变量 {CLIENT_ID_ENV} 已摘掉)。要么不带 \ + ULL_MSA_CLIENT_ID 构建,要么给 `unlucky_core::auth::microsoft::resolve_client_id` \ + 加一个可注入的接缝,再按接缝重写这条锚。" ); - return; } assert_config_gap("device", start_login);