From 7b065c11756c1372a082d300cb853a773f063e26 Mon Sep 17 00:00:00 2001 From: LunarEclipse Date: Thu, 25 Apr 2024 16:21:28 +0200 Subject: [PATCH] Added a test for feed config backwards-compat, fixed bugs - Fixed language config merge bug found by a test - Adjusted two existing tests to fully check stuff related to multiple feeds - Added a new test for backwards-compatibility of the changes - Fixed bugs found by the newly added test --- components/config/src/config/languages.rs | 7 +- components/config/src/config/mod.rs | 93 +++++++++++--------- components/templates/src/global_fns/files.rs | 27 +++--- 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/components/config/src/config/languages.rs b/components/config/src/config/languages.rs index 6bc72488a3..b6588bee7f 100644 --- a/components/config/src/config/languages.rs +++ b/components/config/src/config/languages.rs @@ -4,9 +4,9 @@ use errors::{bail, Result}; use libs::unic_langid::LanguageIdentifier; use serde::{Deserialize, Serialize}; +use crate::config::might_be_single; use crate::config::search; use crate::config::taxonomies; -use crate::config::might_be_single; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] @@ -20,7 +20,7 @@ pub struct LanguageOptions { pub generate_feeds: bool, /// The filenames to use for feeds. Used to find the templates, too. /// Defaults to ["atom.xml"], with "rss.xml" also having a template provided out of the box. - #[serde(deserialize_with = "might_be_single")] + #[serde(alias = "feed_filename", deserialize_with = "might_be_single")] pub feed_filenames: Vec, pub taxonomies: Vec, /// Whether to generate search index for that language, defaults to `false` @@ -69,7 +69,8 @@ impl LanguageOptions { merge_field!(self.title, other.title, "title"); merge_field!(self.description, other.description, "description"); merge_field!( - self.feed_filenames.is_empty(), + self.feed_filenames.is_empty() + || self.feed_filenames == LanguageOptions::default().feed_filenames, self.feed_filenames, other.feed_filenames, "feed_filename" diff --git a/components/config/src/config/mod.rs b/components/config/src/config/mod.rs index bf73eb8987..334bb945ed 100644 --- a/components/config/src/config/mod.rs +++ b/components/config/src/config/mod.rs @@ -57,7 +57,7 @@ pub struct Config { pub feed_limit: Option, /// The filenames to use for feeds. Used to find the templates, too. /// Defaults to ["atom.xml"], with "rss.xml" also having a template provided out of the box. - #[serde(deserialize_with = "might_be_single")] + #[serde(alias = "feed_filename", deserialize_with = "might_be_single")] pub feed_filenames: Vec, /// If set, files from static/ will be hardlinked instead of copied to the output dir. pub hard_link_static: bool, @@ -400,6 +400,48 @@ impl Default for Config { } } +/// Used for deserializing values that can be either a single value or a vec of values +pub(crate) fn might_be_single<'de, T, D>(deserializer: D) -> Result, D::Error> +where + T: DeserializeOwned, + D: Deserializer<'de>, +{ + let v = MightBeSingle::deserialize(deserializer)?; + Ok(v.into()) +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +#[serde(untagged)] +pub(crate) enum MightBeSingle { + Multiple(Vec), + One(T), + None, +} + +impl From> for Vec { + fn from(x: MightBeSingle) -> Vec { + use MightBeSingle::*; + + match x { + Multiple(v) => v, + One(v) => vec![v], + None => vec![], + } + } +} + +impl From> for MightBeSingle { + fn from(value: Vec) -> Self { + Self::Multiple(value) + } +} + +impl Default for MightBeSingle { + fn default() -> Self { + Self::None + } +} + #[cfg(test)] mod tests { use super::*; @@ -981,46 +1023,17 @@ author = "person@example.com (Some Person)" let config = Config::parse(config).unwrap(); assert_eq!(config.author, Some("person@example.com (Some Person)".to_owned())) } -} - -/// Used for deserializing values that can be either a single value or a vec of values -pub(crate) fn might_be_single<'de, T, D>(deserializer: D) -> Result, D::Error> -where - T: DeserializeOwned, - D: Deserializer<'de>, -{ - let v = MightBeSingle::deserialize(deserializer)?; - Ok(v.into()) -} - -#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] -#[serde(untagged)] -pub(crate) enum MightBeSingle { - Multiple(Vec), - One(T), - None, -} - -impl From> for Vec { - fn from(x: MightBeSingle) -> Vec { - use MightBeSingle::*; - - match x { - Multiple(v) => v, - One(v) => vec![v], - None => vec![], - } - } -} -impl From> for MightBeSingle { - fn from(value: Vec) -> Self { - Self::Multiple(value) - } -} + #[test] + fn test_backwards_compatibility_for_feeds() { + let config = r#" +base_url = "example.com" +generate_feed = true +feed_filename = "test.xml" + "#; -impl Default for MightBeSingle { - fn default() -> Self { - Self::None + let config = Config::parse(config).unwrap(); + assert_eq!(config.generate_feeds, true); + assert_eq!(config.feed_filenames, vec!["test.xml".to_owned()]); } } diff --git a/components/templates/src/global_fns/files.rs b/components/templates/src/global_fns/files.rs index 263c9415fd..eaad1231d5 100644 --- a/components/templates/src/global_fns/files.rs +++ b/components/templates/src/global_fns/files.rs @@ -461,27 +461,34 @@ title = "A title" } #[test] - fn can_get_feed_url_with_default_language() { + fn can_get_feed_urls_with_default_language() { let config = Config::parse(CONFIG_DATA).unwrap(); let dir = create_temp_dir(); let static_fn = GetUrl::new(dir.path().to_path_buf(), config.clone(), HashMap::new(), PathBuf::new()); - let mut args = HashMap::new(); - args.insert("path".to_string(), to_value(config.feed_filenames).unwrap()); - args.insert("lang".to_string(), to_value("fr").unwrap()); - assert_eq!(static_fn.call(&args).unwrap(), "https://remplace-par-ton-url.fr/atom.xml"); + for feed_filename in &config.feed_filenames { + let mut args = HashMap::new(); + args.insert("path".to_string(), to_value(feed_filename).unwrap()); + args.insert("lang".to_string(), to_value("fr").unwrap()); + assert_eq!(static_fn.call(&args).unwrap(), "https://remplace-par-ton-url.fr/atom.xml"); + } } #[test] - fn can_get_feed_url_with_other_language() { + fn can_get_feed_urls_with_other_language() { let config = Config::parse(CONFIG_DATA).unwrap(); let dir = create_temp_dir(); let static_fn = GetUrl::new(dir.path().to_path_buf(), config.clone(), HashMap::new(), PathBuf::new()); - let mut args = HashMap::new(); - args.insert("path".to_string(), to_value(config.feed_filenames).unwrap()); - args.insert("lang".to_string(), to_value("en").unwrap()); - assert_eq!(static_fn.call(&args).unwrap(), "https://remplace-par-ton-url.fr/en/atom.xml"); + for feed_filename in &config.feed_filenames { + let mut args = HashMap::new(); + args.insert("path".to_string(), to_value(feed_filename).unwrap()); + args.insert("lang".to_string(), to_value("en").unwrap()); + assert_eq!( + static_fn.call(&args).unwrap(), + "https://remplace-par-ton-url.fr/en/atom.xml" + ); + } } #[test]