Skip to content

Commit

Permalink
tag sanitation and validation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tipogi committed Dec 6, 2024
1 parent 21acfca commit 1e0018c
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 13 deletions.
85 changes: 84 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ url = "2.5.4"
base32 = "0.5.1"
blake3 = "1.5.4"
chrono = "0.4.38"

[dev-dependencies]
tokio = { version = "1", features = ["macros", "rt"] }
125 changes: 113 additions & 12 deletions src/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const MAX_TAG_LABEL_LENGTH: usize = 20;
/// `/pub/pubky.app/tags/FPB0AM9S93Q3M1GFY1KV09GMQM`
///
/// Where tag_id is Crockford-base32(Blake3("{uri_tagged}:{label}")[:half])
#[derive(Serialize, Deserialize, Default)]
#[derive(Serialize, Deserialize, Default, Debug)]
pub struct PubkyAppTag {
pub uri: String,
pub label: String,
Expand All @@ -33,11 +33,17 @@ impl HashId for PubkyAppTag {
#[async_trait]
impl Validatable for PubkyAppTag {
async fn sanitize(self) -> Result<Self, DynError> {
// Remove spaces from the tag and keep it as one word
let mut label = self
.label
.chars()
.filter(|c| !c.is_whitespace())
.collect::<String>();
// Convert label to lowercase and trim
let label = self.label.trim().to_lowercase();
label = label.trim().to_lowercase();

// Enforce maximum label length safely
let label = label.chars().take(MAX_TAG_LABEL_LENGTH).collect::<String>();
label = label.chars().take(MAX_TAG_LABEL_LENGTH).collect::<String>();

// Sanitize URI
let uri = match Url::parse(&self.uri) {
Expand Down Expand Up @@ -66,14 +72,109 @@ impl Validatable for PubkyAppTag {
}
}

#[test]
fn test_create_id() {
let tag = PubkyAppTag {
uri: "user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: "cool".to_string(),
};
#[cfg(test)]
mod tests {
use super::*;
use tokio;

let tag_id = tag.create_id();
println!("Generated Tag ID: {}", tag_id);
#[test]
fn test_label_id() {
// Precomputed earlier
let tag_id = "CBYS8P6VJPHC5XXT4WDW26662W";
// Create new tag
let tag = PubkyAppTag {
uri: "pubky://user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: "cool".to_string(),
};
// Check if the tag ID is correct
assert_eq!(
tag.create_id(),
tag_id
);

let wrong_tag = PubkyAppTag {
uri: "pubky://user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: "co0l".to_string(),
};

// Assure that the new tag has wrong ID
assert_ne!(
wrong_tag.create_id(),
tag_id
);
}

#[tokio::test]
async fn test_incorrect_label() -> Result<(), DynError> {
let tag = PubkyAppTag {
uri: "user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: "cool".to_string(),
};

match tag.sanitize().await {
Err(e) => assert_eq!(e.to_string(), "Invalid URI in tag".to_string(), "The error message is not related URI or the message description is wrong"),
_ => ()
};

let tag = PubkyAppTag {
uri: "pubky://user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: "coolc00lcolaca0g00llooll".to_string(),
};

// Precomputed earlier
let label_id = "8WXXXXHK028RH8AWBZZNHJYDN4";

match tag.validate(label_id).await {
Err(e) => assert_eq!(e.to_string(), "Tag label exceeds maximum length".to_string(), "The error message is not related tag length or the message description is wrong"),
_ => ()
};

Ok(())


}

#[tokio::test]
async fn test_white_space_tag() -> Result<(), DynError> {
// All the tags has to be that label after sanitation
let label = "cool";

let leading_whitespace = PubkyAppTag {
uri: "pubky://user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: " cool".to_string(),
};
let mut sanitazed_label = leading_whitespace.sanitize().await?;
assert_eq!(sanitazed_label.label, label);

let trailing_whitespace = PubkyAppTag {
uri: "pubky://user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: " cool".to_string(),
};
sanitazed_label = trailing_whitespace.sanitize().await?;
assert_eq!(sanitazed_label.label, label);

let space_between = PubkyAppTag {
uri: "pubky://user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: "co ol".to_string(),
};
sanitazed_label = space_between.sanitize().await?;
assert_eq!(sanitazed_label.label, label);

let space_between = PubkyAppTag {
uri: "pubky://user_id/pub/pubky.app/posts/post_id".to_string(),
created_at: 1627849723,
label: " co ol ".to_string(),
};
sanitazed_label = space_between.sanitize().await?;
assert_eq!(sanitazed_label.label, label);

Ok(())
}
}

0 comments on commit 1e0018c

Please sign in to comment.