use std::{error::Error, io}; use ely_domain::{ DomainError, PluginContributionPoint, PluginManifest, PluginPermission, PluginPermissionRisk, PluginSignatureAlgorithm, }; #[test] fn parses_signed_plugin_manifest() -> Result<(), Box> { let manifest = PluginManifest::from_toml(valid_manifest().as_str())?; assert_eq!(manifest.id().as_str(), "com.elydora.reader"); assert_eq!(manifest.name(), "Reader Exporter"); assert_eq!(manifest.homepage(), "https://elydora.com/plugins/reader"); assert_eq!( manifest.permissions(), &[PluginPermission::PageMetadata, PluginPermission::UiCommand] ); assert_eq!( manifest.contributes(), &[PluginContributionPoint::CommandBarCommand, PluginContributionPoint::ReadingModeExporter] ); assert_eq!(manifest.min_ely_build().to_string(), "0.1.0"); assert_eq!( manifest.checksum(), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); assert_eq!(manifest.signature().algorithm(), &PluginSignatureAlgorithm::Ed25519); assert_eq!(manifest.signature().key_id(), "elydora-alpha-plugins"); assert_eq!( manifest.signature().public_key(), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); assert_eq!( manifest.signature().value(), "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ); Ok(()) } #[test] fn classifies_plugin_permission_risk_for_separate_confirmation() -> Result<(), Box> { let manifest = PluginManifest::from_toml(valid_manifest().as_str())?; let high_risk_permissions = manifest.high_risk_permissions().collect::>(); assert!(high_risk_permissions.is_empty()); assert_eq!(PluginPermission::PageMetadata.risk(), PluginPermissionRisk::Standard); assert_eq!(PluginPermission::UiCommand.risk(), PluginPermissionRisk::Standard); assert_eq!(PluginPermission::HistoryRead.risk(), PluginPermissionRisk::High); assert!(PluginPermission::PageScript.requires_separate_confirmation()); assert!(PluginPermission::FilesystemWrite.requires_separate_confirmation()); Ok(()) } #[test] fn rejects_unknown_plugin_permission() -> Result<(), Box> { let manifest = valid_manifest().replace("page:metadata", "tabs:admin"); let error = parse_error(manifest.as_str())?; assert!(matches!( error, DomainError::InvalidPluginPermission { value } if value == "tabs:admin" )); Ok(()) } #[test] fn rejects_duplicate_plugin_permission() -> Result<(), Box> { let manifest = valid_manifest() .replace("[\"page:metadata\", \"ui:command\"]", "[\"page:metadata\", \"page:metadata\"]"); let error = parse_error(manifest.as_str())?; assert!(matches!( error, DomainError::DuplicatePluginPermission { value } if value == "page:metadata" )); Ok(()) } #[test] fn rejects_unknown_plugin_contribution() -> Result<(), Box> { let manifest = valid_manifest().replace("reading-mode-exporter", "hidden-root-hook"); let error = parse_error(manifest.as_str())?; assert!(matches!( error, DomainError::InvalidPluginContribution { value } if value == "hidden-root-hook" )); Ok(()) } #[test] fn rejects_unsigned_plugin_manifest() -> Result<(), Box> { let manifest = valid_manifest().replace( "value = \"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\"", "value = \"\"", ); let error = parse_error(manifest.as_str())?; assert!(matches!(error, DomainError::EmptyField { field } if field == "signature")); Ok(()) } #[test] fn rejects_invalid_plugin_signature_key_id() -> Result<(), Box> { let manifest = valid_manifest() .replace("key_id = \"elydora-alpha-plugins\"", "key_id = \"Elydora Alpha Plugins\""); let error = parse_error(manifest.as_str())?; assert!(matches!( error, DomainError::InvalidPluginSignatureKeyId { value } if value == "Elydora Alpha Plugins" )); Ok(()) } #[test] fn rejects_invalid_plugin_signature_public_key() -> Result<(), Box> { let manifest = valid_manifest().replace( "public_key = \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"", "public_key = \"abcd\"", ); let error = parse_error(manifest.as_str())?; assert!(matches!( error, DomainError::InvalidPluginSignaturePublicKey { value } if value == "abcd" )); Ok(()) } #[test] fn rejects_mismatched_plugin_checksum() -> Result<(), Box> { let manifest = valid_manifest().replace( "checksum = \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"", "checksum = \"1234\"", ); let error = parse_error(manifest.as_str())?; assert!(matches!( error, DomainError::InvalidPluginChecksum { value } if value == "1234" )); Ok(()) } #[test] fn rejects_non_http_plugin_homepage() -> Result<(), Box> { let manifest = valid_manifest().replace( "homepage = \"https://elydora.com/plugins/reader\"", "homepage = \"file:///tmp/reader\"", ); let error = parse_error(manifest.as_str())?; assert!(matches!( error, DomainError::InvalidPluginHomepage { value } if value == "file:///tmp/reader" )); Ok(()) } #[test] fn rejects_extra_manifest_fields() -> Result<(), Box> { let manifest = valid_manifest().replace("[signature]", "process_escape = true\n\n[signature]"); let error = parse_error(manifest.as_str())?; assert!(matches!(error, DomainError::InvalidPluginManifest { .. })); Ok(()) } fn parse_error(manifest: &str) -> Result> { match PluginManifest::from_toml(manifest) { Ok(_) => Err(io::Error::other("manifest parsed successfully").into()), Err(error) => Ok(error), } } fn valid_manifest() -> String { r#" id = "com.elydora.reader" name = "Reader Exporter" description = "Exports the active reader view." author = "Elydora" homepage = "https://elydora.com/plugins/reader" permissions = ["page:metadata", "ui:command"] contributes = ["command-bar-command", "reading-mode-exporter"] min_ely_build = "0.1.0" checksum = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" [signature] algorithm = "ed25519" key_id = "elydora-alpha-plugins" public_key = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" value = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" "# .to_string() }