From 58e8420005042733c90e998d6e84fc659c8da317 Mon Sep 17 00:00:00 2001 From: Danny Browning Date: Wed, 31 Jan 2024 14:28:05 -0700 Subject: [PATCH] feat: wasi and tests --- Cargo.toml | 11 ++-- src/lib.rs | 108 +++++++++++++++++++++++++++++++++++++++- src/model_definition.rs | 1 + 3 files changed, 115 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 006b551..b2fc27a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,20 +13,23 @@ publish = false [dependencies] anyhow = "1" -ceramic-event = { git = "https://github.com/3box/rust-ceramic", branch = "main" } -json-patch = { version = "1.0.0", features = ["diff"] } +#ceramic-event = { git = "https://github.com/ceramicnetwork/rust-ceramic", branch = "main" } +#ceramic-event = { path = "/Users/dbrowning/code/3box/rust-ceramic/event", default-features = false } +ceramic-event = { git = "https://github.com/ceramicnetwork/rust-ceramic", branch = "feat/wasi" } +json-patch = { version = "1.2.0", features = ["diff"] } reqwest = { version = "0.11.14", features = ["json"], optional = true } schemars = "0.8.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -ssi = { version = "0.7", features = ["ed25519"] } -url = { version = "2.2.2", optional = true } +#ssi = { version = "0.7", features = ["ed25519"] } +url = { version = "2.5.0", optional = true } [features] default = ["remote"] remote = ["reqwest", "url"] [dev-dependencies] +rand = "0.8.5" test-log = { version = "0.2", default-features = false, features = ["trace"] } tokio = { version = "1", default-features = false, features = ["macros", "rt"] } tracing = "0.1" diff --git a/src/lib.rs b/src/lib.rs index 8e3c233..64c5b7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -795,5 +795,111 @@ pub mod tests { .await .unwrap(); assert_eq!(res.edges.len(), 1); + let node = &res.edges[0].node; + let result: Ball = serde_json::from_value(node.content.clone()).unwrap(); + assert_eq!(result.blue, 5); } -} + + #[tokio::test] + async fn should_query_models_after_update() { + let ceramic = CeramicRemoteHttpClient::new(signer().await, ceramic_url()); + let model = create_model(&ceramic).await; + ceramic.index_model(&model).await.unwrap(); + let _instance1 = ceramic + .create_list_instance( + &model, + &Ball { + creator: ceramic.client().signer().id().id.clone(), + radius: 1, + red: 2, + green: 3, + blue: 4, + }, + ) + .await + .unwrap(); + + let instance2 = ceramic + .create_list_instance( + &model, + &Ball { + creator: ceramic.client().signer().id().id.clone(), + radius: 2, + red: 3, + green: 4, + blue: 5, + }, + ) + .await + .unwrap(); + + //give anchor time to complete + tokio::time::sleep(Duration::from_secs(1)).await; + + let replace = Ball { + creator: ceramic.client().signer().id().id.clone(), + radius: 1, + red: 0, + green: 3, + blue: 10, + }; + let post_resp = ceramic.replace(&model, &instance2, &replace).await.unwrap(); + assert_eq!(post_resp.stream_id, instance2); + + //give anchor time to complete + tokio::time::sleep(Duration::from_secs(1)).await; + + let mut where_filter = HashMap::new(); + where_filter.insert("blue".to_string(), OperationFilter::EqualTo(10.into())); + let filter = FilterQuery::Where(where_filter); + let res = ceramic + .query(&model, Some(filter), Pagination::default()) + .await + .unwrap(); + assert_eq!(res.edges.len(), 1); + let node = &res.edges[0].node; + let result: Ball = serde_json::from_value(node.content.clone()).unwrap(); + assert_eq!(result.blue, 10); + } + + #[tokio::test] + async fn should_create_and_repeatedly_update_list() { + let ceramic = CeramicRemoteHttpClient::new(signer().await, ceramic_url()); + let model = create_model(&ceramic).await; + let stream_id = ceramic + .create_list_instance( + &model, + &Ball { + creator: ceramic.client().signer().id().id.clone(), + radius: 1, + red: 2, + green: 3, + blue: 4, + }, + ) + .await + .unwrap(); + + for i in 0..100 { + //give anchor time to complete + tokio::time::sleep(Duration::from_millis(100)).await; + + let replace_value = rand::random::() % 10i32; + let patch = json_patch::Patch(vec![json_patch::PatchOperation::Replace( + ReplaceOperation { + path: "/red".to_string(), + value: serde_json::json!(replace_value), + }, + )]); + let post_resp = ceramic.update(&model, &stream_id, patch).await.unwrap(); + assert_eq!(post_resp.stream_id, stream_id); + let post_resp: Ball = serde_json::from_value(post_resp.state.unwrap().content).unwrap(); + assert_eq!(post_resp.red, replace_value, "Failed to return expected value on iteration {}", i); + + let get_resp: Ball = ceramic.get_as(&stream_id).await.unwrap(); + assert_eq!(get_resp.red, replace_value); + assert_eq!(get_resp.blue, 4); + assert_eq!(get_resp, post_resp, "Failed to retrieve expected value on iteration {}", i); + } + } +} \ No newline at end of file diff --git a/src/model_definition.rs b/src/model_definition.rs index b35047a..a4a6b1c 100644 --- a/src/model_definition.rs +++ b/src/model_definition.rs @@ -90,6 +90,7 @@ impl ModelDefinition { Self::new_for_value(name, account_relation, schema) } + /// Create a new definition from schema that is already json pub fn new_for_value( name: &str, account_relation: ModelAccountRelation,