Skip to content

Commit

Permalink
feat(ssg): ✨ Improve sitemap creation and unit tests
Browse files Browse the repository at this point in the history
Refactor sitemap tests by adding descriptive test names, segmenting by functionality, expanding coverage, incorporating data integrity checks, and adding explanatory comments
  • Loading branch information
sebastienrousseau committed Feb 21, 2024
1 parent 4dfce6c commit c33caf0
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 46 deletions.
6 changes: 3 additions & 3 deletions content/post.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ generator: "Shokunin 🦀 (version 0.0.24)"
item_description: RSS feed for the site
item_guid: https://kaishi.one/rss.xml
item_link: https://kaishi.one/rss.xml
item_pub_date: "Tue, 20 Feb 2024 15:15:15 GMT"
item_pub_date: "Mon, 19 Feb 2024 15:15:15 GMT"
item_title: "RSS"
last_build_date: "Tue, 20 Feb 2024 15:15:15 GMT"
last_build_date: "Mon, 19 Feb 2024 15:15:15 GMT"
managing_editor: jane.doe@kaishi.one (Jane Doe)
pub_date: "Tue, 20 Feb 2024 15:15:15 GMT"
pub_date: "Mon, 19 Feb 2024 15:15:15 GMT"
ttl: "60"
type: "website"
webmaster: jane.doe@kaishi.one
Expand Down
6 changes: 3 additions & 3 deletions content/privacy.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ generator: "Shokunin 🦀 (version 0.0.24)"
item_description: RSS feed for the site
item_guid: https://kaishi.one/rss.xml
item_link: https://kaishi.one/rss.xml
item_pub_date: "Tue, 20 Feb 2024 15:15:15 GMT"
item_pub_date: "Sun, 18 Feb 2024 15:15:15 GMT"
item_title: "RSS"
last_build_date: "Tue, 20 Feb 2024 15:15:15 GMT"
last_build_date: "Sun, 18 Feb 2024 15:15:15 GMT"
managing_editor: jane.doe@kaishi.one (Jane Doe)
pub_date: "Tue, 20 Feb 2024 15:15:15 GMT"
pub_date: "Sun, 18 Feb 2024 15:15:15 GMT"
ttl: "60"
type: "website"
webmaster: jane.doe@kaishi.one
Expand Down
78 changes: 54 additions & 24 deletions src/modules/sitemap.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,64 @@
// Copyright © 2024 Shokunin Static Site Generator. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 OR MIT

// Import models::data::SiteMapData
use crate::models::data::SiteMapData;
use crate::models::data::SiteMapData; // Import the SiteMapData model from the local crate.
use std::collections::HashMap; // Standard library import for using HashMap.
use regex::Regex; // Ensure the regex crate is imported for regular expression functionality.

// Import std::collections::HashMap
use std::collections::HashMap;

/// Function to create SiteMapData
/// Generates `SiteMapData` from metadata.
///
/// The `metadata` parameter is a map of metadata strings.
/// # Arguments
/// * `metadata` - A hashmap containing page metadata, including last build date, change frequency, and page location.
///
/// Returns a `SiteMapData` object.
pub fn create_site_map_data(
metadata: &HashMap<String, String>,
) -> SiteMapData {
/// # Returns
/// A `SiteMapData` object populated with values from the metadata.
pub fn create_site_map_data(metadata: &HashMap<String, String>) -> SiteMapData {
// Convert the last build date from metadata to the desired format.
let lastmod = convert_date_format(metadata.get("last_build_date").unwrap_or(&"".to_string()));

// Construct and return SiteMapData with converted and extracted metadata values.
SiteMapData {
// The change frequency of the website.
changefreq: metadata
.get("changefreq")
.cloned()
.unwrap_or_default(),

// The last modified date of the website.
lastmod: metadata
.get("last_build_date")
.cloned()
.unwrap_or_default(),

// The base URL of the website.
changefreq: metadata.get("changefreq").cloned().unwrap_or_default(),
lastmod,
loc: metadata.get("permalink").cloned().unwrap_or_default(),
}
}

/// Converts date strings from various formats to "YYYY-MM-DD".
///
/// Supports conversion from "DD MMM YYYY" format and checks if input is already in target format.
///
/// # Arguments
/// * `input` - A string slice representing the input date.
///
/// # Returns
/// A string representing the date in "YYYY-MM-DD" format, or the original input if conversion is not applicable.
fn convert_date_format(input: &str) -> String {
// Define a regex to identify dates in the "DD MMM YYYY" format.
let re = Regex::new(r"\d{2} \w{3} \d{4}").unwrap();

// Check if input matches the expected date format.
if let Some(date_match) = re.find(input) {
let date_str = date_match.as_str();
let parts: Vec<&str> = date_str.split_whitespace().collect();

// Proceed with conversion if input format matches.
if parts.len() == 3 {
let day = parts[0];
let month = match parts[1] {
"Jan" => "01", "Feb" => "02", "Mar" => "03",
"Apr" => "04", "May" => "05", "Jun" => "06",
"Jul" => "07", "Aug" => "08", "Sep" => "09",
"Oct" => "10", "Nov" => "11", "Dec" => "12",
_ => return input.to_string(), // Return original input for unrecognized months.
};
let year = parts[2];

// Return the formatted date string.
return format!("{}-{}-{}", year, month, day);
}
}

// Return the original input if it's already in the correct format or doesn't match "DD MMM YYYY".
input.to_string()
}
60 changes: 44 additions & 16 deletions tests/test_sitemap.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,64 @@
#[cfg(test)]
mod tests {
use serde_json;

Check failure on line 3 in tests/test_sitemap.rs

View workflow job for this annotation

GitHub Actions / Lint

this import is redundant
use ssg::models::data::SiteMapData;
use ssg::modules::sitemap::create_site_map_data;
use std::collections::HashMap;

/// Tests the creation of SiteMapData with all expected fields provided.
#[test]
fn test_create_site_map_data_with_all_fields() {
fn create_site_map_data_with_complete_metadata() {
let mut metadata = HashMap::new();
metadata.insert("changefreq".to_string(), "daily".to_string());
metadata.insert(
"last_build_date".to_string(),
"2023-01-01".to_string(),
);
metadata.insert(
"permalink".to_string(),
"https://example.com".to_string(),
);
metadata.insert("last_build_date".to_string(), "2024-02-20".to_string());
metadata.insert("permalink".to_string(), "https://example.com".to_string());

let site_map_data = create_site_map_data(&metadata);

assert_eq!(site_map_data.changefreq, "daily");
assert_eq!(site_map_data.lastmod, "2023-01-01");
assert_eq!(site_map_data.loc, "https://example.com");
assert_eq!("daily", site_map_data.changefreq);
assert_eq!("2024-02-20", site_map_data.lastmod);
assert_eq!("https://example.com", site_map_data.loc);
}

/// Verifies that missing metadata fields result in default SiteMapData values.
#[test]
fn test_create_site_map_data_with_missing_fields() {
fn create_site_map_data_with_incomplete_metadata() {
let metadata = HashMap::new(); // Empty metadata

let site_map_data = create_site_map_data(&metadata);

assert_eq!(site_map_data.changefreq, "");
assert_eq!(site_map_data.lastmod, "");
assert_eq!(site_map_data.loc, "");
assert_eq!("", site_map_data.changefreq);
assert_eq!("", site_map_data.lastmod);
assert_eq!("", site_map_data.loc);
}

/// Checks handling of metadata when only the changefreq is provided.
#[test]
fn create_site_map_data_with_only_changefreq() {
let mut metadata = HashMap::new();
metadata.insert("changefreq".to_string(), "daily".to_string());

let site_map_data = create_site_map_data(&metadata);

assert_eq!("daily", site_map_data.changefreq);
assert_eq!("", site_map_data.lastmod); // Expected default value
assert_eq!("", site_map_data.loc); // Expected default value
}

/// Tests serialization and deserialization of SiteMapData for data integrity.
#[test]
fn serialize_and_deserialize_site_map_data() {
let mut metadata = HashMap::new();
metadata.insert("changefreq".to_string(), "daily".to_string());
metadata.insert("last_build_date".to_string(), "2023-01-01".to_string());
metadata.insert("permalink".to_string(), "https://example.com".to_string());

let original = create_site_map_data(&metadata);
let serialized = serde_json::to_string(&original).expect("Serialization failed");
let deserialized: SiteMapData = serde_json::from_str(&serialized).expect("Deserialization failed");

assert_eq!(original.changefreq, deserialized.changefreq);
assert_eq!(original.lastmod, deserialized.lastmod);
assert_eq!(original.loc, deserialized.loc);
}
}

0 comments on commit c33caf0

Please sign in to comment.