gridcraft/crates/ui-egui/tests/protect_password.rs

71 lines
2.6 KiB
Rust

//! Protect Sheet / Unprotect Sheet mask the password as it's typed (issue #347).
use egui::accesskit::Role;
use egui_kittest::kittest::Queryable as _;
use gridcraft_engine::Session;
use gridcraft_ui_egui::SheetApp;
use serde_json::json;
const SECRET: &str = "s3cret";
fn harness() -> egui_kittest::Harness<'static, SheetApp> {
let mut session = Session::new();
session.new_workbook();
let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_ui_state(
|ui, app: &mut SheetApp| {
let ctx = ui.ctx().clone();
app.logic(&ctx);
app.ui(ui);
},
SheetApp::new(session, Default::default()),
);
h.run_steps(4);
h
}
fn type_password(h: &mut egui_kittest::Harness<'static, SheetApp>) {
h.get_by_role(Role::PasswordInput).click();
h.run_steps(2);
h.input_mut().events.push(egui::Event::Text(SECRET.into()));
h.run_steps(2);
}
fn secret_on_screen(h: &egui_kittest::Harness<'static, SheetApp>) -> bool {
h.query_all_by(|n| n.value().is_some_and(|v| v.contains(SECRET)) || n.label().is_some_and(|l| l.contains(SECRET))).next().is_some()
}
#[test]
fn protect_and_unprotect_sheet_mask_the_password() {
let mut h = harness();
h.state_mut().open_dialog("protectSheet", json!({}));
h.run_steps(3);
type_password(&mut h);
assert_eq!(h.state().dialog.as_ref().and_then(|d| d.values.get("password")), Some(&json!(SECRET)));
assert!(!secret_on_screen(&h), "the typed password must not be readable");
assert!(h.get_by_role(Role::PasswordInput).value().is_some_and(|v| !v.is_empty() && !v.contains(SECRET)));
// Show password reveals it on purpose; unticking masks it again.
h.get_by_label("Show password").click();
h.run_steps(3);
assert!(h.query_by_role(Role::PasswordInput).is_none());
assert!(secret_on_screen(&h));
h.get_by_label("Show password").click();
h.run_steps(3);
assert!(h.query_by_role(Role::PasswordInput).is_some());
assert!(!secret_on_screen(&h));
h.get_by_label(" OK ").click();
h.run_steps(3);
assert!(h.state().dialog.is_none());
assert!(h.state().session.active().unwrap().wb.active().unwrap().protection.as_ref().is_some_and(|p| p.password.is_some()));
// Unprotect asks for the password with a masked field too, and it starts hidden again.
h.state_mut().open_dialog("unprotectSheet", json!({}));
h.run_steps(3);
type_password(&mut h);
assert!(!secret_on_screen(&h), "the typed password must not be readable");
h.get_by_label(" OK ").click();
h.run_steps(3);
assert!(h.state().session.active().unwrap().wb.active().unwrap().protection.is_none());
}