Skip to content

Commit

Permalink
feat: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
remiroyc committed Sep 15, 2023
1 parent 95600d5 commit bc74415
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 159 deletions.
2 changes: 1 addition & 1 deletion crates/ark-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub async fn indexer_main_loop<T: StorageManager>(storage: T) -> Result<()> {
init_tracing();

let rpc_provider = env::var("RPC_PROVIDER").expect("RPC_PROVIDER must be set");
let sn_client = StarknetClientHttp::new(&rpc_provider.clone())?;
let sn_client = StarknetClientHttp::init(&rpc_provider.clone())?;
let block_manager = BlockManager::new(&storage, &sn_client);
let mut event_manager = EventManager::new(&storage, &sn_client);
let mut token_manager = TokenManager::new(&storage, &sn_client);
Expand Down
65 changes: 0 additions & 65 deletions crates/ark-metadata/src/get.rs

This file was deleted.

3 changes: 1 addition & 2 deletions crates/ark-metadata/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
mod cairo_strings;
pub mod metadata_manager;
mod normalize_metadata;
pub mod metadata;
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
use anyhow::{anyhow, Result};
use starknet::core::{types::FieldElement, utils::parse_cairo_short_string};

pub fn parse_cairo_long_string(long_string: Vec<FieldElement>) -> Result<String> {
match long_string.len() {
/// Parse a Cairo "long string" represented as a Vec of FieldElements into a Rust String.
///
/// # Arguments
/// * `field_elements`: A vector of FieldElements representing the Cairo long string.
///
/// # Returns
/// * A `Result` which is either the parsed Rust string or an error.
pub fn parse_cairo_long_string(field_elements: Vec<FieldElement>) -> Result<String> {
match field_elements.len() {
0 => {
return Err(anyhow!("No value found"));

Check warning on line 14 in crates/ark-metadata/src/metadata/cairo_string_parser.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> crates/ark-metadata/src/metadata/cairo_string_parser.rs:14:13 | 14 | return Err(anyhow!("No value found")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 14 - return Err(anyhow!("No value found")); 14 + Err(anyhow!("No value found")) |
}
1 => match long_string.first() {
// If the long_string contains only one FieldElement, try to parse it using the short string parser.
1 => match field_elements.first() {
Some(first_string_field_element) => {
match parse_cairo_short_string(first_string_field_element) {
Ok(value) => {
Expand All @@ -19,11 +27,12 @@ pub fn parse_cairo_long_string(long_string: Vec<FieldElement>) -> Result<String>
}
None => return Err(anyhow!("No value found")),

Check warning on line 28 in crates/ark-metadata/src/metadata/cairo_string_parser.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> crates/ark-metadata/src/metadata/cairo_string_parser.rs:28:21 | 28 | None => return Err(anyhow!("No value found")), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 28 | None => Err(anyhow!("No value found")), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
},
// If the long_string has more than one FieldElement, parse each FieldElement sequentially
// and concatenate their results.
_ => {
// let array_length_field_element = long_string.first().unwrap();
let mut result = String::new();
for i in 1..long_string.len() {
let field_element = long_string[i as usize].clone();
for i in 1..field_elements.len() {
let field_element = field_elements[i as usize].clone();

Check warning on line 35 in crates/ark-metadata/src/metadata/cairo_string_parser.rs

View workflow job for this annotation

GitHub Actions / clippy

casting to the same type is unnecessary (`usize` -> `usize`)

warning: casting to the same type is unnecessary (`usize` -> `usize`) --> crates/ark-metadata/src/metadata/cairo_string_parser.rs:35:52 | 35 | let field_element = field_elements[i as usize].clone(); | ^^^^^^^^^^ help: try: `i` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast = note: `#[warn(clippy::unnecessary_cast)]` on by default

Check warning on line 35 in crates/ark-metadata/src/metadata/cairo_string_parser.rs

View workflow job for this annotation

GitHub Actions / clippy

using `clone` on type `FieldElement` which implements the `Copy` trait

warning: using `clone` on type `FieldElement` which implements the `Copy` trait --> crates/ark-metadata/src/metadata/cairo_string_parser.rs:35:37 | 35 | let field_element = field_elements[i as usize].clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the `clone` call: `field_elements[i as usize]` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy
match parse_cairo_short_string(&field_element) {
Ok(value) => {
result.push_str(&value);
Expand All @@ -43,6 +52,27 @@ mod tests {
use super::parse_cairo_long_string;
use starknet::core::types::FieldElement;

#[test]
fn should_return_error_for_empty_vector() {
let long_string = vec![];

let result = parse_cairo_long_string(long_string);
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "No value found");
}

// This test is hypothetical and may not fit exactly as-is depending on the implementation of `parse_cairo_short_string`
#[test]
fn should_handle_generic_error_from_parse_cairo_short_string() {
let long_string = vec![
// some value that causes `parse_cairo_short_string` to error out
];

let result = parse_cairo_long_string(long_string);
assert!(result.is_err());
// Check the error message or type here
}

#[test]
fn should_parse_field_elements_with_array_length() {
let long_string = vec![
Expand Down
26 changes: 26 additions & 0 deletions crates/ark-metadata/src/metadata/metadata_models.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use serde_derive::{Serialize, Deserialize};
use serde_json::Value;


#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum MetadataAttributeValue {
Str(String),
Int(i64),
Float(f64),
Value(Value),
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct MetadataAttribute {
pub trait_type: String,
pub value: MetadataAttributeValue,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct NormalizedMetadata {
pub description: String,
pub external_url: String,
pub image: String,
pub name: String,
pub attributes: Vec<MetadataAttribute>,
}
3 changes: 3 additions & 0 deletions crates/ark-metadata/src/metadata/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod normalization;
pub mod cairo_string_parser;
pub mod metadata_models;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::{anyhow, Ok, Result};
use log::warn;
use serde_json::Value;

use crate::metadata_manager::{MetadataAttribute, MetadataAttributeValue, NormalizedMetadata};
use super::metadata_models::{NormalizedMetadata, MetadataAttribute, MetadataAttributeValue};

// fn normalize_metadata_attributes_with_eip721_standard(
// metadata_uri: String,
Expand Down Expand Up @@ -35,13 +35,13 @@ use crate::metadata_manager::{MetadataAttribute, MetadataAttributeValue, Normali
// }
// }

struct CommonMetadataProperties {
struct BaseMetadataProperties {
description: String,
image: String,
name: String,
}

fn extract_common_metadata(metadata: &Value) -> CommonMetadataProperties {
fn extract_properties(metadata: &Value) -> BaseMetadataProperties {
let description = match metadata.get("description") {
Some(description) => description.as_str().unwrap().to_string(),
None => String::from(""),
Expand All @@ -57,7 +57,7 @@ fn extract_common_metadata(metadata: &Value) -> CommonMetadataProperties {
None => String::from(""),
};

return CommonMetadataProperties {
return BaseMetadataProperties {
description,
image,
name,
Expand All @@ -77,11 +77,11 @@ pub fn normalize_metadata_attributes_with_opensea_standard(
};

for attribute in items {
let trait_type = attribute
.get("trait_type")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let trait_type = attribute
.get("trait_type")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();

match attribute.get("value") {
Some(attribute_value) => match attribute_value {
Expand All @@ -107,9 +107,7 @@ pub fn normalize_metadata_attributes_with_opensea_standard(
_ => {
attributes.push(MetadataAttribute {
trait_type: String::from(trait_type),

Check warning on line 109 in crates/ark-metadata/src/metadata/normalization.rs

View workflow job for this annotation

GitHub Actions / clippy

useless conversion to the same type: `std::string::String`

warning: useless conversion to the same type: `std::string::String` --> crates/ark-metadata/src/metadata/normalization.rs:109:45 | 109 | ... trait_type: String::from(trait_type), | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `trait_type` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
value: MetadataAttributeValue::Value(
attribute_value.clone(),
),
value: MetadataAttributeValue::Value(attribute_value.clone()),
});
}
},
Expand All @@ -123,7 +121,7 @@ pub fn normalize_metadata_attributes_with_opensea_standard(
None => Vec::new(),
};

let common_properties = extract_common_metadata(raw_metadata);
let common_properties = extract_properties(raw_metadata);
let external_url = match raw_metadata.get("external_url") {
Some(value) => value.as_str().unwrap().to_string(),
None => metadata_uri,
Expand All @@ -142,7 +140,6 @@ pub fn normalize_metadata(
initial_metadata_uri: String,
raw_metadata: Value,
) -> Result<NormalizedMetadata> {

match raw_metadata.get("attributes") {
Some(_attributes) => {
let normalized_metadata = normalize_metadata_attributes_with_opensea_standard(
Expand All @@ -151,22 +148,51 @@ pub fn normalize_metadata(
)?;
return Ok(normalized_metadata);

Check warning on line 149 in crates/ark-metadata/src/metadata/normalization.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> crates/ark-metadata/src/metadata/normalization.rs:149:13 | 149 | return Ok(normalized_metadata); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 149 - return Ok(normalized_metadata); 149 + Ok(normalized_metadata) |
}
None => {
Err(anyhow!("Error with the metadata object"))
},
None => Err(anyhow!("Error with the metadata object")),
}
}

#[cfg(test)]
mod tests {
use crate::{
metadata_manager::MetadataAttributeValue,
normalize_metadata::{
use crate::metadata::{normalization::{
normalize_metadata, normalize_metadata_attributes_with_opensea_standard,
},
};
}, metadata_models::MetadataAttributeValue};
use serde_json::json;

#[test]
fn should_use_metadata_uri_when_external_url_is_missing() {
let starknet_id_raw_metadata = json!({
"name": "test",
"description": "test description",
"image": "test image",
"attributes": [{"trait_type": "Base", "value": "Starfish"}]
});

let metadata_uri = String::from("https://starknet.id/api/identicons/1");
let result = normalize_metadata_attributes_with_opensea_standard(
metadata_uri.clone(),
&starknet_id_raw_metadata,
);
assert!(result.is_ok());
let normalized_metadata = result.unwrap();
assert_eq!(normalized_metadata.external_url, metadata_uri);
}

#[test]
fn should_return_error_when_attributes_missing() {
let metadata = json!({
"name": "test",
"description": "test description",
"image": "test image"
});

let metadata_uri = String::from("https://starknet.id/api/identicons/1");
let result = normalize_metadata(metadata_uri, metadata);
assert!(result.is_err());
}



#[test]
fn should_normalize_metadata() {
let description = "This token represents an identity on StarkNet.";
Expand All @@ -179,21 +205,13 @@ mod tests {
assert!(result.is_ok());

let normalized_metadata = result.unwrap();

println!("\n\n==> normalized_metadata: {:?}", normalized_metadata);

assert!(normalized_metadata.external_url == metadata_uri);
assert!(normalized_metadata.description == description);
assert!(normalized_metadata.image == image);
assert!(normalized_metadata.name == name);

let first_attribute = normalized_metadata.attributes.first().unwrap();

assert!(first_attribute.trait_type == "Subdomain");

// println!("\n\n==> Value: {}", first_attribute.value);
println!("==> Value: {:?}", first_attribute.value);

}

#[test]
Expand Down
Loading

0 comments on commit bc74415

Please sign in to comment.