aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/metadata.rs65
-rw-r--r--src/utils.rs48
2 files changed, 113 insertions, 0 deletions
diff --git a/src/metadata.rs b/src/metadata.rs
index fe657e4..d6b3d6a 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -13,6 +13,11 @@ pub struct Metadata {
}
impl Metadata {
+ /// Reads `Metadata` from a file or creates a new one.
+ ///
+ /// This method will create new metadata if it can't read the file,
+ /// whether it's because of malformed JSON, UTF-8 or because the file
+ /// is not readable.
pub fn read_or_create(file_path: &PathBuf) -> Metadata {
if let Some(metadata) = Metadata::read_metadata_file(file_path) {
metadata
@@ -28,6 +33,7 @@ impl Metadata {
}
}
+ /// Returns the metadata `created_on` as an RFC-2822 string.
pub fn created_on_utc(&self) -> Option<String> {
let date =
OffsetDateTime::from_unix_timestamp_nanos((self.created_on * 1_000_000).into()).ok()?;
@@ -41,3 +47,62 @@ impl Metadata {
serde_json::from_str(&contents).ok()
}
}
+
+#[cfg(test)]
+mod tests {
+ use std::fs::write;
+
+ use super::*;
+
+ use test_utilities::*;
+
+ #[test]
+ fn test_reads_metadata_if_file_exists() {
+ let test_dir = setup_test_dir();
+ create_test_file(
+ &test_dir.join("metadata.json"),
+ "\
+{
+ \"id\": \"cool\",
+ \"created_on\": 1736105008957
+}",
+ );
+
+ let metadata = Metadata::read_or_create(&test_dir.join("metadata.json"));
+
+ assert_eq!(metadata.id, "cool");
+ assert_eq!(metadata.created_on, 1736105008957);
+ }
+
+ #[test]
+ fn test_creates_metadata_if_file_does_not_exist() {
+ let test_dir = setup_test_dir();
+
+ assert!(!test_dir.join("metadata.json").exists());
+ let metadata = Metadata::read_or_create(&test_dir.join("metadata.json"));
+ assert_eq!(metadata.created_on.to_string(), metadata.id);
+ }
+
+ #[test]
+ fn test_creates_metadata_if_file_is_malformed() {
+ let test_dir = setup_test_dir();
+ write(&test_dir.join("metadata.json"), vec![0xFF, 0xFF]).expect("Failed to write file");
+
+ let metadata = Metadata::read_or_create(&test_dir.join("metadata.json"));
+ assert_eq!(metadata.created_on.to_string(), metadata.id);
+ }
+
+ #[test]
+ fn test_it_returns_created_on_as_rfc_2822_utc() {
+ let metadata = Metadata {
+ id: "cool".to_string(),
+ created_on: 1736035200000,
+ };
+
+ if let Some(created_on_utc) = metadata.created_on_utc() {
+ assert_eq!(created_on_utc, "Sun, 05 Jan 2025 00:00:00 +0000");
+ } else {
+ panic!("Could not generate RFC-2822 string");
+ }
+ }
+}
diff --git a/src/utils.rs b/src/utils.rs
index 4522f4c..01b6cdf 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -2,6 +2,7 @@ use std::fs::{copy, create_dir_all, read_dir};
use std::io::Result;
use std::path::Path;
+/// Recursively copies the contents of a directory.
pub fn recursively_copy(source: &Path, target: &Path) -> Result<()> {
let entries = read_dir(source)?;
for entry in entries {
@@ -21,3 +22,50 @@ pub fn recursively_copy(source: &Path, target: &Path) -> Result<()> {
Ok(())
}
+
+#[cfg(test)]
+mod tests {
+ use std::fs::create_dir_all;
+
+ use super::*;
+
+ use test_utilities::*;
+
+ #[test]
+ fn test_recursively_copies_directories() {
+ let test_dir = setup_test_dir();
+ let source_dir = test_dir.join("source");
+ let target_dir = test_dir.join("target");
+ let nested_dir = source_dir.join("nested");
+ let hidden_dir = source_dir.join(".hidden");
+ create_dir_all(&target_dir).expect("Could not create target test directory");
+ create_dir_all(&nested_dir).expect("Could not create nested test directory");
+ create_dir_all(&hidden_dir).expect("Could not create hidden test directory");
+ create_test_file(&source_dir.join("image.png"), "A beautiful pencil");
+ create_test_file(&nested_dir.join("hello.txt"), "I am here");
+ create_test_file(&nested_dir.join(".hidden"), "I am not here?");
+ create_test_file(&hidden_dir.join("in_plain_sight.mkv"), "Almost");
+ create_test_file(&hidden_dir.join(".hidden"), "I'm double hidden");
+
+ recursively_copy(&source_dir, &target_dir).expect("Copy failed on test directory");
+
+ assert_file_contents(&target_dir.join("image.png"), "A beautiful pencil");
+ assert_file_contents(&target_dir.join("nested/hello.txt"), "I am here");
+ assert_file_contents(&target_dir.join("nested/.hidden"), "I am not here?");
+ assert_file_contents(&target_dir.join(".hidden/in_plain_sight.mkv"), "Almost");
+ assert_file_contents(&target_dir.join(".hidden/.hidden"), "I'm double hidden");
+ }
+
+ #[test]
+ fn test_empty_directory() {
+ let test_dir = setup_test_dir();
+ let source_dir = test_dir.join("source");
+ let target_dir = test_dir.join("target");
+ create_dir_all(&source_dir).expect("Could not create source test directory");
+ create_dir_all(&target_dir).expect("Could not create target test directory");
+
+ recursively_copy(&source_dir, &target_dir).expect("Copy failed on empty test directory");
+
+ assert_eq!(target_dir.read_dir().unwrap().count(), 0);
+ }
+}