Files
openhuman/app/src-tauri/src/lib.rs
T
Mega MindandGitHub 52b59f62d7 test: add cross-stack coverage for core and tauri flows (#130)
* Add unit tests for Mnemonic page

- Introduced comprehensive tests for the Mnemonic page, covering initial render, copy to clipboard functionality, confirmation checkbox behavior, and mode switching between generate and import.
- Validated user interactions, including input handling and button states, ensuring robust functionality and user experience.
- Enhanced test coverage for various scenarios, including validation of mnemonic phrases and loading states during operations.

* test: add cross-stack test coverage for core and tauri flows

Add focused Rust and frontend tests for core process startup behavior, CLI argument parsing, JSON-RPC error handling, and Tauri command/RPC mapping paths to improve confidence for issue #57.

Closes #57

Made-with: Cursor

* refactor(tests): streamline test code and improve readability

Consolidate mock imports and simplify function calls in coreRpcClient tests. Adjust formatting in Rust core_process and CLI tests for better clarity. Update mnemonic test assertions for improved accuracy.

Made-with: Cursor
2026-04-01 00:25:04 +05:30

173 lines
5.7 KiB
Rust

#[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
compile_error!("src-tauri host is desktop-only. Non-desktop targets are not supported.");
mod core_process;
use tauri::{
menu::{Menu, MenuItem},
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
AppHandle, Manager, RunEvent,
};
#[cfg(any(windows, target_os = "linux"))]
use tauri_plugin_deep_link::DeepLinkExt;
#[tauri::command]
fn core_rpc_url() -> String {
std::env::var("OPENHUMAN_CORE_RPC_URL")
.unwrap_or_else(|_| "http://127.0.0.1:7788/rpc".to_string())
}
fn is_daemon_mode() -> bool {
std::env::args().any(|arg| arg == "daemon" || arg == "--daemon")
}
fn show_main_window(app: &AppHandle) {
if let Some(window) = app.get_webview_window("main") {
if let Err(err) = window.show() {
log::error!("[tray] failed to show main window: {err}");
}
if let Err(err) = window.unminimize() {
log::error!("[tray] failed to unminimize main window: {err}");
}
if let Err(err) = window.set_focus() {
log::error!("[tray] failed to focus main window: {err}");
}
} else {
log::error!("[tray] main window not found");
}
}
fn setup_tray(app: &AppHandle) -> tauri::Result<()> {
log::info!("[tray] setting up tray icon");
let show_item = MenuItem::with_id(
app,
"tray_show_window",
"Open OpenHuman",
true,
None::<&str>,
)?;
let quit_item = MenuItem::with_id(app, "tray_quit", "Quit", true, None::<&str>)?;
let menu = Menu::with_items(app, &[&show_item, &quit_item])?;
let icon = app
.default_window_icon()
.cloned()
.ok_or_else(|| tauri::Error::AssetNotFound("default window icon".to_string()))?;
TrayIconBuilder::with_id("openhuman-tray")
.icon(icon)
.menu(&menu)
.on_menu_event(|app, event| match event.id().as_ref() {
"tray_show_window" => {
log::info!("[tray] action=show_window source=menu");
show_main_window(app);
}
"tray_quit" => {
log::info!("[tray] action=quit source=menu");
app.exit(0);
}
_ => {}
})
.on_tray_icon_event(|tray, event| {
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
..
} = event
{
log::info!("[tray] action=show_window source=left_click");
show_main_window(tray.app_handle());
}
})
.build(app)?;
log::info!("[tray] tray icon ready");
Ok(())
}
pub fn run() {
let daemon_mode = is_daemon_mode();
let default_filter = std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
let _ = env_logger::Builder::new()
.parse_filters(&default_filter)
.try_init();
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_deep_link::init())
.setup(move |app| {
#[cfg(any(windows, target_os = "linux"))]
{
app.deep_link().register_all()?;
}
let core_run_mode = core_process::default_core_run_mode(daemon_mode);
let core_bin = if matches!(core_run_mode, core_process::CoreRunMode::ChildProcess) {
core_process::default_core_bin()
} else {
None
};
let core_handle = core_process::CoreProcessHandle::new(
core_process::default_core_port(),
core_bin,
core_run_mode,
);
std::env::set_var("OPENHUMAN_CORE_RPC_URL", core_handle.rpc_url());
app.manage(core_handle.clone());
tauri::async_runtime::spawn(async move {
if let Err(err) = core_handle.ensure_running().await {
log::error!("[core] failed to start core process: {err}");
} else {
log::info!("[core] core process ready");
}
});
if daemon_mode {
if let Some(window) = app.get_webview_window("main") {
let _ = window.hide();
log::info!("[tray] daemon_mode=true window_hidden_on_startup");
}
}
if let Err(err) = setup_tray(app.handle()) {
log::error!("[tray] failed to setup tray icon: {err}");
}
Ok(())
})
.invoke_handler(tauri::generate_handler![core_rpc_url])
.build(tauri::generate_context!())
.expect("error while building tauri application")
.run(move |app_handle, event| match event {
#[cfg(target_os = "macos")]
RunEvent::Reopen { .. } => {
show_main_window(app_handle);
}
RunEvent::Exit => {
if let Some(core) = app_handle.try_state::<core_process::CoreProcessHandle>() {
let core = core.inner().clone();
tauri::async_runtime::block_on(async move {
core.shutdown().await;
});
}
}
_ => {}
});
}
pub fn run_core_from_args(args: &[String]) -> Result<(), String> {
let core_bin = crate::core_process::default_core_bin()
.ok_or_else(|| "openhuman-core binary not found".to_string())?;
let status = std::process::Command::new(core_bin)
.args(args)
.status()
.map_err(|e| format!("failed to execute core binary: {e}"))?;
if !status.success() {
return Err(format!("core binary exited with status {status}"));
}
Ok(())
}