diff --git a/Cargo.lock b/Cargo.lock index d4da9cde..733c26e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3223,6 +3223,7 @@ dependencies = [ "regex", "serde", "serde_json", + "serde_yml", "tempfile", "thiserror", "time", diff --git a/ssg-metadata/Cargo.toml b/ssg-metadata/Cargo.toml index 1d5a284a..68f8a72d 100644 --- a/ssg-metadata/Cargo.toml +++ b/ssg-metadata/Cargo.toml @@ -36,6 +36,7 @@ thiserror = "1.0" tokio = { version = "1.0", features = ["full"] } time = "0.3" regex = "1.10" +serde_yml = "0.0.12" quick-xml = "0.36" [build-dependencies] diff --git a/ssg-metadata/src/error.rs b/ssg-metadata/src/error.rs index 92c8a722..fe4801d5 100644 --- a/ssg-metadata/src/error.rs +++ b/ssg-metadata/src/error.rs @@ -1,3 +1,4 @@ +use serde_yml::Error as SerdeYmlError; use thiserror::Error; /// Custom error types for the ssg-metadata library @@ -25,7 +26,7 @@ pub enum MetadataError { /// YAML parsing error #[error("YAML parsing error: {0}")] - YamlError(#[from] yaml_rust2::ScanError), + YamlError(#[from] SerdeYmlError), /// JSON parsing error #[error("JSON parsing error: {0}")] diff --git a/ssg-metadata/tests/test_error.rs b/ssg-metadata/tests/test_error.rs index ab955f6a..ae3c4dac 100644 --- a/ssg-metadata/tests/test_error.rs +++ b/ssg-metadata/tests/test_error.rs @@ -5,8 +5,11 @@ #[cfg(test)] mod tests { + use serde_json::Error as JsonError; + use serde_yml::Error as YamlError; use ssg_metadata::error::MetadataError; use std::io; + use toml::de::Error as TomlError; /// Test `ExtractionError` construction. /// @@ -72,4 +75,65 @@ mod tests { let error = MetadataError::from(io_error); assert_eq!(error.to_string(), "I/O error: File not found"); } + + /// Test `YamlError` conversion. + /// + /// This test ensures that a `serde_yml::Error` is correctly converted into the `YamlError` variant. + #[test] + fn test_yaml_error() { + // Malformed YAML content + let invalid_yaml = "invalid: yaml: data"; + + // Try to parse the invalid YAML, which will trigger a `serde_yml::Error` + let yaml_error: Result = + serde_yml::from_str(invalid_yaml); + + if let Err(yaml_error) = yaml_error { + // Convert the `serde_yml::Error` into `MetadataError` + let error = MetadataError::from(yaml_error); + + // Check that the error message is correctly formatted + assert!(error.to_string().contains("YAML parsing error")); + } else { + panic!("Expected YAML parsing error, but got Ok"); + } + } + + /// Test `JsonError` conversion. + /// + /// This test ensures that a `serde_json::Error` is correctly converted into the `JsonError` variant. + #[test] + fn test_json_error() { + let invalid_json = "{ invalid json }"; // Malformed JSON + let json_error: Result = + serde_json::from_str(invalid_json); + + if let Err(json_error) = json_error { + let error = MetadataError::from(json_error); + // Check if the error message contains the correct phrase + assert!( + error.to_string().contains("JSON parsing error"), + "Error message should contain 'JSON parsing error'" + ); + } else { + panic!("Expected JSON parsing error, but got Ok"); + } + } + + /// Test `TomlError` conversion. + /// + /// This test ensures that a `toml::de::Error` is correctly converted into the `TomlError` variant. + #[test] + fn test_toml_error() { + let invalid_toml = "invalid = toml"; // Malformed TOML + let toml_error: Result = + toml::from_str(invalid_toml); + + if let Err(toml_error) = toml_error { + let error = MetadataError::from(toml_error); + assert!(error.to_string().contains("TOML parsing error")); + } else { + panic!("Expected TOML parsing error, but got Ok"); + } + } } diff --git a/ssg-metadata/tests/test_metatags.rs b/ssg-metadata/tests/test_metatags.rs index 5dddf15f..0608400f 100644 --- a/ssg-metadata/tests/test_metatags.rs +++ b/ssg-metadata/tests/test_metatags.rs @@ -5,6 +5,8 @@ #[cfg(test)] mod tests { use regex::Regex; + use ssg_metadata::generate_metatags; + use ssg_metadata::MetaTagGroups; use std::collections::HashMap; /// Parses meta tags from an HTML string and returns a HashMap. @@ -48,4 +50,99 @@ mod tests { "Empty meta tags should not be parsed" ); } + + /// Test adding a custom primary meta tag. + #[test] + fn test_add_custom_primary_tag() { + let mut meta_tags = MetaTagGroups::default(); + meta_tags.add_custom_tag("custom-tag", "custom value"); + + assert!(meta_tags.primary.contains("custom-tag")); + assert!(meta_tags.primary.contains("custom value")); + } + + /// Test adding a custom OpenGraph (og) meta tag. + #[test] + fn test_add_custom_og_tag() { + let mut meta_tags = MetaTagGroups::default(); + meta_tags.add_custom_tag("og:custom", "custom og value"); + + assert!(meta_tags.og.contains("og:custom")); + assert!(meta_tags.og.contains("custom og value")); + } + + /// Test adding a custom Twitter meta tag. + #[test] + fn test_add_custom_twitter_tag() { + let mut meta_tags = MetaTagGroups::default(); + meta_tags + .add_custom_tag("twitter:custom", "custom twitter value"); + + assert!(meta_tags.twitter.contains("twitter:custom")); + assert!(meta_tags.twitter.contains("custom twitter value")); + } + + /// Test adding a custom Apple meta tag. + #[test] + fn test_add_custom_apple_tag() { + let mut meta_tags = MetaTagGroups::default(); + meta_tags.add_custom_tag( + "apple-mobile-web-app-custom", + "custom apple value", + ); + + assert!(meta_tags + .apple + .contains("apple-mobile-web-app-custom")); + assert!(meta_tags.apple.contains("custom apple value")); + } + + /// Test adding a custom Microsoft meta tag. + #[test] + fn test_add_custom_ms_tag() { + let mut meta_tags = MetaTagGroups::default(); + meta_tags + .add_custom_tag("msapplication-custom", "custom ms value"); + + assert!(meta_tags.ms.contains("msapplication-custom")); + assert!(meta_tags.ms.contains("custom ms value")); + } + + /// Test adding multiple custom tags of different types. + #[test] + fn test_add_multiple_custom_tags() { + let mut meta_tags = MetaTagGroups::default(); + meta_tags.add_custom_tag("custom-primary", "primary value"); + meta_tags.add_custom_tag("og:custom", "og value"); + meta_tags.add_custom_tag("twitter:custom", "twitter value"); + meta_tags.add_custom_tag( + "apple-mobile-web-app-custom", + "apple value", + ); + meta_tags.add_custom_tag("msapplication-custom", "ms value"); + + // Check primary meta tags + assert!(meta_tags.primary.contains(""), + "Primary meta tag should contain 'custom-primary'"); + + // Check Open Graph (og) meta tags + assert!( + meta_tags.og.contains( + "" + ), + "OG meta tag should contain 'og:custom'" + ); + + // Check Twitter meta tags + assert!(meta_tags.twitter.contains(""), + "Twitter meta tag should contain 'twitter:custom'"); + + // Check Apple meta tags + assert!(meta_tags.apple.contains(""), + "Apple meta tag should contain 'apple-mobile-web-app-custom'"); + + // Check Microsoft meta tags + assert!(meta_tags.ms.contains(""), + "MS meta tag should contain 'msapplication-custom'"); + } }