use std::ops::Deref; use std::str::FromStr; use std::sync::LazyLock; use wfassoc::lowlevel::*; use wfassoc::win32::concept; mod common; static EXT: LazyLock = LazyLock::new(|| concept::Ext::from_str(".pacfg").unwrap()); static APP_FILE: LazyLock = LazyLock::new(|| concept::FileName::from_str("passoc.exe").unwrap()); static PROG_ID: LazyLock = LazyLock::new(|| "Passoc.Pacfg".into()); static ICON: LazyLock = LazyLock::new(|| r"%SystemRoot%\System32\imageres.dll,-72".into()); static VERB: LazyLock = LazyLock::new(|| { let verb = concept::Verb::from_str("open").unwrap(); let cmdline = concept::CmdLine::from_str("notepad.exe %1").unwrap(); ShellVerb::new(verb, cmdline) }); // region: ExtKey #[test] fn test_ext_key() { common::check_sandbox(); fn tester(scope: Scope, view: View) { let mut key = ExtKey::new(EXT.clone()); // delete and ensure let rv = key.delete(scope); assert!(rv.is_ok()); let rv = key.is_exist(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.is_exist(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); // get/set default let rv = key.set_default(scope, Some(&PROG_ID)); assert!(rv.is_ok()); let rv = key.get_default(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(PROG_ID.clone())); let rv = key.set_default(scope, None); assert!(rv.is_ok()); let rv = key.get_default(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // test open with progids let rv = key.is_in_open_with_progids(view, &PROG_ID); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); let rv = key.add_into_open_with_progids(scope, &PROG_ID); assert!(rv.is_ok()); let rv = key.is_in_open_with_progids(view, &PROG_ID); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.get_open_with_progids(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(vec![PROG_ID.clone()])); let rv = key.remove_from_open_with_progids(scope, &PROG_ID); assert!(rv.is_ok()); let rv = key.is_in_open_with_progids(view, &PROG_ID); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); // clean up let rv = key.delete(scope); assert!(rv.is_ok()); } tester(Scope::User, View::User); tester(Scope::System, View::System); } // endregion // region: ProgIdKey #[test] fn test_prog_id_key() { common::check_sandbox(); static LEGACY_NAME: LazyLock = LazyLock::new(|| "Passoc Pacfg File".into()); static FRIENDLY_TYPE_NAME: LazyLock = LazyLock::new(|| "Passoc Pacfg File Type".into()); fn tester(scope: Scope, view: View) { let mut key = ProgIdKey::new(PROG_ID.clone()); // delete and ensure let rv = key.delete(scope); assert!(rv.is_ok()); let rv = key.is_exist(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.is_exist(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); // get/set default (friendly name, legacy) let rv = key.set_default(scope, Some(&LEGACY_NAME)); assert!(rv.is_ok()); let rv = key.get_default(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(LEGACY_NAME.clone())); let rv = key.set_default(scope, None); assert!(rv.is_ok()); let rv = key.get_default(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // get/set friendly type name let rv = key.set_friendly_type_name(scope, Some(&FRIENDLY_TYPE_NAME)); assert!(rv.is_ok()); let rv = key.get_friendly_type_name(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(FRIENDLY_TYPE_NAME.clone())); let rv = key.set_friendly_type_name(scope, None); assert!(rv.is_ok()); let rv = key.get_friendly_type_name(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // get/set shell verb let rv = key.set_shell_verb(scope, Some(&VERB)); assert!(rv.is_ok()); let rv = key.get_shell_verb(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(VERB.clone())); let rv = key.set_shell_verb(scope, None); assert!(rv.is_ok()); let rv = key.get_shell_verb(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // get/set default icon let rv = key.set_default_icon(scope, Some(&ICON)); assert!(rv.is_ok()); let rv = key.get_default_icon(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(ICON.clone())); let rv = key.set_default_icon(scope, None); assert!(rv.is_ok()); let rv = key.get_default_icon(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // clean up let rv = key.delete(scope); assert!(rv.is_ok()); } tester(Scope::User, View::User); tester(Scope::System, View::System); } // endregion // region: AppPathsKey #[test] fn test_app_paths_key() { common::check_sandbox(); static APP_PATH: &str = r"C:\Program Files\Passoc\passoc.exe"; static APP_DIR: &str = r"C:\Program Files\Passoc"; fn tester(scope: Scope) { let mut key = AppPathsKey::new(APP_FILE.clone()); // delete and ensure let rv = key.delete(scope); assert!(rv.is_ok()); let rv = key.is_exist(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.is_exist(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); // get/set default let rv = key.set_default(scope, APP_PATH); assert!(rv.is_ok()); let rv = key.get_default(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), APP_PATH); // get/set path let rv = key.set_path(scope, APP_DIR); assert!(rv.is_ok()); let rv = key.get_path(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), APP_DIR); // clean up let rv = key.delete(scope); assert!(rv.is_ok()); } tester(Scope::User); tester(Scope::System); } // endregion // region: ApplicationsKey #[test] fn test_applications_key() { common::check_sandbox(); static FRIENDLY_APP_NAME: LazyLock = LazyLock::new(|| "Passoc Application".into()); fn tester(scope: Scope, view: View) { let mut key = ApplicationsKey::new(APP_FILE.clone()); // delete and ensure let rv = key.delete(scope); assert!(rv.is_ok()); let rv = key.is_exist(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.is_exist(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.ensure(scope); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); // get/set shell verb let rv = key.set_shell_verb(scope, Some(&VERB)); assert!(rv.is_ok()); let rv = key.get_shell_verb(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(VERB.clone())); let rv = key.set_shell_verb(scope, None); assert!(rv.is_ok()); let rv = key.get_shell_verb(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // get/set default icon let rv = key.set_default_icon(scope, Some(&ICON)); assert!(rv.is_ok()); let rv = key.get_default_icon(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(ICON.clone())); let rv = key.set_default_icon(scope, None); assert!(rv.is_ok()); let rv = key.get_default_icon(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // get/set friendly app name let rv = key.set_friendly_app_name(scope, Some(&FRIENDLY_APP_NAME)); assert!(rv.is_ok()); let rv = key.get_friendly_app_name(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(FRIENDLY_APP_NAME.clone())); let rv = key.set_friendly_app_name(scope, None); assert!(rv.is_ok()); let rv = key.get_friendly_app_name(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // get/set supported types let rv = key.set_supported_types(scope, Some(&vec![EXT.deref()])); assert!(rv.is_ok()); let rv = key.get_supported_types(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), Some(vec![EXT.clone()])); let rv = key.set_supported_types(scope, None); assert!(rv.is_ok()); let rv = key.get_supported_types(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), None); // get/set no open with let rv = key.get_no_open_with(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); let rv = key.set_no_open_with(scope, true); assert!(rv.is_ok()); let rv = key.get_no_open_with(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), true); let rv = key.set_no_open_with(scope, false); assert!(rv.is_ok()); let rv = key.get_no_open_with(view); assert!(rv.is_ok()); assert_eq!(rv.unwrap(), false); // clean up let rv = key.delete(scope); assert!(rv.is_ok()); } tester(Scope::User, View::User); tester(Scope::System, View::System); } // endregion