fix(app-iced, presenter): M114 r4 —— 登录面板 Close 不再是死按钮 + 面板态删掉原文字段(把「画原文」变成编译错)
复审 r2 P2-1:`Account::Close` 只在 `phase.busy()` 时派 `CancelDeviceLogin`,而 `Page::build` 只要非 Idle 就强制回 Microsoft ⇒ Failed/Succeeded 下 Close 点了没反应。 - 判据改成「两条轨任一非 Idle 就取消」;host 侧 `CancelDeviceLogin` 本来就把两条轨收成 Idle - mock 补 `AppCommand::CancelDeviceLogin` 分支(按真 host 契约发 Idle),否则 mock 下不可验 - 新增 headless 回归闸:失败/成功/第三方轨三种态 → Close → `panel == None` (变异实证:判据退回 `busy()` ⇒ 该用例红,打印 left: Microsoft / right: None) 复审 r2 P2-2:`DevicePanel`/`AuthlibPanel` 删掉 `message`/`detail` 字段。 视图没有材料可画,「把后端原文画上屏」从测试问题变成**类型错误**; `tests_text.rs` 的 docstring 改成真实边界(只覆盖模型 + i18n 查表,视图靠类型 + 出图)。 顺带(塔看图标出):alert 的 `Code: …` 与标题同排,省一整行高度, 避免 1180×760 把 All accounts 第三行挤到折线下;新增 `closed` 取证场景出「关掉之后」的对照图。
This commit is contained in:
1 parent
bc71834bc3
commit
f3e20b670e
9 files changed
+188
-81
No files matched your search
@@ -2,6 +2,13 @@
|
||||
//!
|
||||
//! 从 `model.rs` 拆出来守 400 行硬线:这些类型是「UI 要画什么」的枚举,
|
||||
//! 判定逻辑(倒计时 → 已过期、服务发现 → 可用)也在这里,页面与表单只消费结果。
|
||||
//!
|
||||
//! ## 为什么这里**没有** `message` / `detail` 字段(M114 r3 / 复审 r2 P2-2)
|
||||
//!
|
||||
//! 后端的原始诊断串是中文人话,只该进日志。r2 时它们还以 `message`/`detail` 存在于此,
|
||||
//! 「页面把它们画上屏」只能靠一条**平行实现**的取样断言去拦(复审用变异证明那条断言是哑的)。
|
||||
//! 现在直接把字段删掉:视图**没有材料可画**,想画原文是编译错误——比任何测试都硬。
|
||||
//! 原文仍在 presenter 的 `DeviceLoginView/AuthlibLoginView::message` 里(只进 `eprintln!`)。
|
||||
|
||||
use unlucky_presenter::dto::{AuthlibLoginView, DeviceLoginPhase, DeviceLoginView, LoginFailure};
|
||||
|
||||
@@ -10,11 +17,8 @@ use unlucky_presenter::dto::{AuthlibLoginView, DeviceLoginPhase, DeviceLoginView
|
||||
pub enum DevicePanel {
|
||||
/// 没有登录在跑
|
||||
Hidden,
|
||||
/// 正在申请设备码
|
||||
Requesting {
|
||||
/// 状态文案(presenter 给的,已脱敏)
|
||||
message: String,
|
||||
},
|
||||
/// 正在申请设备码(进度文案由页面按 i18n 出)
|
||||
Requesting,
|
||||
/// 设备码等待用户操作
|
||||
Code {
|
||||
/// 用户码
|
||||
@@ -25,8 +29,6 @@ pub enum DevicePanel {
|
||||
remaining: Option<u64>,
|
||||
/// 是否已过期
|
||||
expired: bool,
|
||||
/// 状态文案
|
||||
message: String,
|
||||
},
|
||||
/// 授权码流:等浏览器回调
|
||||
Browser {
|
||||
@@ -36,15 +38,11 @@ pub enum DevicePanel {
|
||||
remaining: Option<u64>,
|
||||
/// 是否已过期
|
||||
expired: bool,
|
||||
/// 状态文案
|
||||
message: String,
|
||||
},
|
||||
/// 失败(**原因码上屏,原文只进日志**)
|
||||
/// 失败(**只有原因码**;原文在 presenter 的日志里)
|
||||
Failed {
|
||||
/// 原因码(页面据此选 i18n)
|
||||
failure: LoginFailure,
|
||||
/// 原始诊断(不上屏)
|
||||
detail: String,
|
||||
},
|
||||
/// 成功
|
||||
Succeeded {
|
||||
@@ -59,23 +57,16 @@ pub enum AuthlibPanel {
|
||||
/// 没在跑
|
||||
Idle,
|
||||
/// 正在校验/登录
|
||||
Running {
|
||||
/// 状态文案
|
||||
message: String,
|
||||
},
|
||||
Running,
|
||||
/// 地址校验通过(服务发现拿到服务器名)
|
||||
Ready {
|
||||
/// 服务器名
|
||||
server_name: String,
|
||||
/// 状态文案
|
||||
message: String,
|
||||
},
|
||||
/// 失败(**原因码上屏,原文只进日志**)
|
||||
/// 失败(**只有原因码**;原文在 presenter 的日志里)
|
||||
Failed {
|
||||
/// 原因码(页面据此选 i18n)
|
||||
failure: LoginFailure,
|
||||
/// 原始诊断(不上屏)
|
||||
detail: String,
|
||||
},
|
||||
/// 成功
|
||||
Succeeded {
|
||||
@@ -89,16 +80,13 @@ pub(super) fn device_panel(view: &DeviceLoginView, remaining: Option<u64>) -> De
|
||||
let expired = remaining == Some(0);
|
||||
match view.phase {
|
||||
DeviceLoginPhase::Idle => DevicePanel::Hidden,
|
||||
DeviceLoginPhase::Requesting => DevicePanel::Requesting {
|
||||
message: view.message.clone(),
|
||||
},
|
||||
DeviceLoginPhase::Requesting => DevicePanel::Requesting,
|
||||
DeviceLoginPhase::Waiting => {
|
||||
if view.user_code.trim().is_empty() {
|
||||
DevicePanel::Browser {
|
||||
link: view.verification_uri.clone(),
|
||||
remaining,
|
||||
expired,
|
||||
message: view.message.clone(),
|
||||
}
|
||||
} else {
|
||||
DevicePanel::Code {
|
||||
@@ -106,13 +94,11 @@ pub(super) fn device_panel(view: &DeviceLoginView, remaining: Option<u64>) -> De
|
||||
link: view.qr_link.clone(),
|
||||
remaining,
|
||||
expired,
|
||||
message: view.message.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
DeviceLoginPhase::Failed => DevicePanel::Failed {
|
||||
failure: view.failure.unwrap_or(LoginFailure::Other),
|
||||
detail: view.message.clone(),
|
||||
},
|
||||
DeviceLoginPhase::Succeeded => DevicePanel::Succeeded {
|
||||
name: view.account_name.clone(),
|
||||
@@ -124,16 +110,10 @@ pub(super) fn device_panel(view: &DeviceLoginView, remaining: Option<u64>) -> De
|
||||
pub(super) fn authlib_panel(view: &AuthlibLoginView) -> (AuthlibPanel, String) {
|
||||
match view.phase {
|
||||
DeviceLoginPhase::Idle => (AuthlibPanel::Idle, String::new()),
|
||||
DeviceLoginPhase::Requesting => (
|
||||
AuthlibPanel::Running {
|
||||
message: view.message.clone(),
|
||||
},
|
||||
String::new(),
|
||||
),
|
||||
DeviceLoginPhase::Requesting => (AuthlibPanel::Running, String::new()),
|
||||
DeviceLoginPhase::Waiting => (
|
||||
AuthlibPanel::Ready {
|
||||
server_name: view.server_name.clone(),
|
||||
message: view.message.clone(),
|
||||
},
|
||||
view.server_name.clone(),
|
||||
),
|
||||
@@ -146,7 +126,6 @@ pub(super) fn authlib_panel(view: &AuthlibLoginView) -> (AuthlibPanel, String) {
|
||||
DeviceLoginPhase::Failed => (
|
||||
AuthlibPanel::Failed {
|
||||
failure: view.failure.unwrap_or(LoginFailure::Other),
|
||||
detail: view.message.clone(),
|
||||
},
|
||||
String::new(),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user