use serde_json::{json, Value}; use std::sync::Arc; use crate::database::Database; use crate::error::AppError; use crate::services::provider::ProviderService; use crate::settings; use crate::store::AppState; pub(crate) fn run_post_import_sync(db: Arc) -> Result<(), AppError> { let app_state = AppState::new(db); ProviderService::sync_current_to_live(&app_state)?; settings::reload_settings()?; Ok(()) } fn post_sync_warning(err: E) -> String { AppError::localized( "sync.post_operation_sync_failed", format!("后置同步状态失败: {err}"), format!("Post-operation synchronization failed: {err}"), ) .to_string() } pub(crate) fn post_sync_warning_from_result( result: Result, String>, ) -> Option { match result { Ok(Ok(())) => None, Ok(Err(err)) => Some(post_sync_warning(err)), Err(err) => Some(post_sync_warning(err)), } } pub(crate) fn attach_warning(mut value: Value, warning: Option) -> Value { if let Some(message) = warning { if let Some(obj) = value.as_object_mut() { obj.insert("warning".to_string(), Value::String(message)); } } value } pub(crate) fn success_payload_with_warning(backup_id: String, warning: Option) -> Value { attach_warning( json!({ "success": true, "message": "SQL imported successfully", "backupId": backup_id }), warning, ) } #[cfg(test)] mod tests { use super::{attach_warning, post_sync_warning_from_result}; use serde_json::json; #[test] fn post_sync_warning_from_result_returns_none_on_success() { let warning = post_sync_warning_from_result(Ok(Ok(()))); assert!(warning.is_none()); } #[test] fn post_sync_warning_from_result_returns_some_on_sync_error() { let warning = post_sync_warning_from_result(Ok(Err(crate::error::AppError::Config("boom".into())))); assert!(warning.is_some()); } #[tokio::test] async fn post_sync_warning_from_result_returns_some_on_join_error() { let handle = tokio::spawn(async move { panic!("forced join error"); }); let join_err = handle.await.expect_err("task should panic"); let warning = post_sync_warning_from_result(Err(join_err.to_string())); assert!(warning.is_some()); } #[test] fn attach_warning_adds_warning_without_dropping_existing_fields() { let payload = json!({ "status": "downloaded" }); let updated = attach_warning(payload, Some("post sync warning".to_string())); assert_eq!( updated.get("status").and_then(|v| v.as_str()), Some("downloaded") ); assert_eq!( updated.get("warning").and_then(|v| v.as_str()), Some("post sync warning") ); } }