From e42342311f731f5766ae01c84ff994ada31177e6 Mon Sep 17 00:00:00 2001 From: aloekun Date: Wed, 15 Apr 2026 15:15:39 +0900 Subject: [PATCH] =?UTF-8?q?fix(cli-pr-monitor):=20=E4=B8=8D=E6=AD=A3?= =?UTF-8?q?=E3=83=9A=E3=82=A4=E3=83=AD=E3=83=BC=E3=83=89=E3=81=A7=E6=97=A2?= =?UTF-8?q?=E5=AD=98=20state=20=E3=82=92=E6=B6=88=E3=81=95=E3=81=AA?= =?UTF-8?q?=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update_state_from_check_result で serde_json::from_value(...).ok() を if let Ok(...) パターンに変更。デシリアライズ失敗時に既存の state.ci / state.coderabbit が None で上書きされる問題を修正。 CodeRabbit PR #38 指摘への対応。テスト2件追加。 --- src/cli-pr-monitor/src/state.rs | 36 +++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/cli-pr-monitor/src/state.rs b/src/cli-pr-monitor/src/state.rs index ab6f187c..4f1f299b 100644 --- a/src/cli-pr-monitor/src/state.rs +++ b/src/cli-pr-monitor/src/state.rs @@ -102,10 +102,14 @@ pub(crate) fn update_state_from_check_result( state.summary = summary.to_string(); } if let Some(ci_val) = result.get("ci") { - state.ci = serde_json::from_value(ci_val.clone()).ok(); + if let Ok(ci) = serde_json::from_value(ci_val.clone()) { + state.ci = Some(ci); + } } if let Some(cr_val) = result.get("coderabbit") { - state.coderabbit = serde_json::from_value(cr_val.clone()).ok(); + if let Ok(cr) = serde_json::from_value(cr_val.clone()) { + state.coderabbit = Some(cr); + } } if let Some(findings_val) = result.get("findings") { if let Ok(findings) = serde_json::from_value::>(findings_val.clone()) { @@ -248,6 +252,34 @@ mod tests { assert!(state.ci.is_none()); } + #[test] + fn update_state_invalid_ci_preserves_existing() { + let mut state = PrMonitorState::new(Some(1), None, "t".into()); + state.ci = Some(CiState { + overall: "success".into(), + runs: vec![], + }); + // "ci" キーは存在するが不正な型 (文字列) → デシリアライズ失敗 + let result = serde_json::json!({ "ci": "invalid" }); + update_state_from_check_result(&mut state, &result); + // 既存の ci が保持されること + assert_eq!(state.ci.as_ref().unwrap().overall, "success"); + } + + #[test] + fn update_state_invalid_coderabbit_preserves_existing() { + let mut state = PrMonitorState::new(Some(1), None, "t".into()); + state.coderabbit = Some(CodeRabbitState { + review_state: "approved".into(), + new_comments: 0, + actionable_comments: None, + unresolved_threads: None, + }); + let result = serde_json::json!({ "coderabbit": 42 }); + update_state_from_check_result(&mut state, &result); + assert_eq!(state.coderabbit.as_ref().unwrap().review_state, "approved"); + } + #[test] fn mark_notified_updates_flag() { let tmp =