From 846171675da5c12440f6628cd63769772a0641c3 Mon Sep 17 00:00:00 2001 From: YoussefAWasfy Date: Tue, 24 Sep 2024 18:32:25 +0200 Subject: [PATCH 1/5] tests: add request queue unit tests --- .../src/networking/request_queue.rs | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs index b803663..9b0aeaa 100644 --- a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs +++ b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs @@ -136,3 +136,202 @@ impl RequestList { self.list_full } } +#[cfg(test)] +mod tests { + + use std::collections::HashMap; + + use blake2::{Blake2s256, Digest}; + use rand::{distributions::Alphanumeric, Rng}; + use rayon::range; + use ssi::dids::DID; + use tokio::sync::oneshot::{self, Receiver, Sender}; + + use crate::{ + config, + networking::{network::WSCommands, request_queue::RequestList}, + }; + const DID_KEY: &str = "did:key:z6MkiToqovww7vYtxm1xNM15u9JzqzUFZ1k7s7MazYJUyAxv"; + const DID_KEY_2: &str = "did:key:z6Mkp89diy1PZkbUBDTpiqZBotddb1VV7JnY8qiZMGErUbFe"; + + #[tokio::test] + async fn new_works() { + let config = config::ClientConfigBuilder::default().build(); + let request_list = RequestList::new(&config); + assert_eq!(request_list.list_full, false); + assert_eq!(request_list.total_count, 0); + } + + #[tokio::test] + async fn insert_works_returns_true() { + let config = config::ClientConfigBuilder::default().build(); + let mut request_list = RequestList::new(&config); + + let (tx, _) = oneshot::channel::(); + + let unique_id: String = _unique_id(); + let did_hash = _hash_did(&DID_KEY); + + let insert_result = request_list.insert(did_hash.clone(), &unique_id, tx); + + assert!(insert_result); + } + + #[tokio::test] + async fn insert_works_returns_false_duplicates() { + let config = config::ClientConfigBuilder::default().build(); + let mut request_list = RequestList::new(&config); + + let (tx, _) = oneshot::channel::(); + let (tx2, _) = oneshot::channel::(); + + let unique_id: String = _unique_id(); + let did_hash = _hash_did(DID_KEY); + + let insert_result = request_list.insert(did_hash.clone(), &unique_id, tx); + let insert_result2 = request_list.insert(did_hash.clone(), &unique_id, tx2); + + assert!(insert_result); + assert_eq!(insert_result2, false); + } + + #[tokio::test] + async fn insert_list_becomes_full() { + let config = config::ClientConfigBuilder::default() + .with_network_cache_limit_count(1) + .build(); + let mut request_list = RequestList::new(&config); + + let (tx, _) = oneshot::channel::(); + let (tx2, _) = oneshot::channel::(); + + let unique_id: String = _unique_id(); + let unique_id_2: String = _unique_id(); + + let did_hash = _hash_did(DID_KEY); + let did_hash_2 = _hash_did(DID_KEY_2); + + let insert_result = request_list.insert(did_hash.clone(), &unique_id, tx); + let insert_result2 = request_list.insert(did_hash_2.clone(), &unique_id_2, tx2); + + assert!(insert_result); + assert!(insert_result2); + assert!(request_list.list_full); + + assert_eq!(request_list.total_count, 2); + } + #[should_panic] + #[tokio::test] + async fn remove_key_not_found() { + let config = config::ClientConfigBuilder::default().build(); + let mut request_list = RequestList::new(&config); + request_list.remove(&_hash_did(DID_KEY), None).unwrap(); + } + + #[should_panic] + #[tokio::test] + async fn remove_key_not_found_passing_uuid() { + let config = config::ClientConfigBuilder::default().build(); + let mut request_list = RequestList::new(&config); + request_list + .remove(&_hash_did(DID_KEY), Some("".to_string())) + .unwrap(); + } + + #[should_panic] + #[tokio::test] + async fn remove_key_not_found_passing_uuid_wrong_did() { + let config = config::ClientConfigBuilder::default().build(); + let mut request_list = RequestList::new(&config); + request_list + .remove(&_hash_did("wrongdid"), Some("".to_string())) + .unwrap(); + } + + #[tokio::test] + async fn remove_passing_uuid_works() { + let (mut request_list, did_to_uuid) = _fill_request_list([DID_KEY].to_vec(), true, Some(1)); + let num_of_channels_before_remove = + request_list.list.get(&_hash_did(DID_KEY)).unwrap().len(); + let total_count_before_remove = request_list.total_count; + let ids = did_to_uuid.get(DID_KEY).unwrap(); + request_list + .remove(&_hash_did(DID_KEY), ids.first().cloned()) + .unwrap(); + + assert_eq!( + num_of_channels_before_remove - 1, + request_list.list.get(&_hash_did(DID_KEY)).unwrap().len() + ); + assert_eq!(total_count_before_remove, request_list.total_count); + } + + #[tokio::test] + async fn remove_without_passing_uuid_to_remove_all_works() { + let (mut request_list, _) = _fill_request_list([DID_KEY].to_vec(), true, Some(4)); + + let total_count_before_remove = request_list.total_count; + let num_of_channels_before_remove = + request_list.list.get(&_hash_did(DID_KEY)).unwrap().len(); + + let removed_list = request_list.remove(&_hash_did(DID_KEY), None).unwrap(); + + assert_eq!(request_list.total_count, 0); + } + + #[tokio::test] + async fn remove_works() { + let (mut request_list, _) = _fill_request_list([DID_KEY].to_vec(), false, None); + let removed_list = request_list.remove(&_hash_did(DID_KEY), None).unwrap(); + } + + fn _hash_did(did: &str) -> String { + let mut hasher = Blake2s256::new(); + hasher.update(did); + format!("{:x}", hasher.clone().finalize()) + } + fn _unique_id() -> String { + rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(8) + .map(char::from) + .collect() + } + + fn _fill_request_list( + dids: Vec<&str>, + fill_channels_for_key: bool, + fill_channels_for_key_number: Option, + ) -> (RequestList, HashMap>) { + fn get_hash_and_id(did: &str) -> (String, String, Sender) { + ( + _unique_id(), + _hash_did(&did), + oneshot::channel::().0, + ) + } + let nested_channels_num = if let Some(nested_channels) = fill_channels_for_key_number { + nested_channels // This returns the u8 + } else { + 0 // Handle None case by returning 0 or some other u8 value + }; + let mut did_to_uuid_map: HashMap> = HashMap::new(); + let config = config::ClientConfigBuilder::default().build(); + let mut request_list = RequestList::new(&config); + for did in dids { + let (unique_id, did_hash, tx) = get_hash_and_id(did); + let mut uuids_arr: Vec = [unique_id.clone()].to_vec(); + let insert_result = request_list.insert(did_hash.clone(), &unique_id, tx); + if insert_result && fill_channels_for_key { + for _i in 0..nested_channels_num { + let (unique_id, did_hash, tx) = get_hash_and_id(did); + uuids_arr.push(unique_id.clone()); + request_list.insert(did_hash.clone(), &unique_id, tx); + } + } + did_to_uuid_map.insert(did.to_string(), uuids_arr); + } + + (request_list, did_to_uuid_map) + } +} From 2d7fc1181463d1ccf40463549d108ff27d6d5352 Mon Sep 17 00:00:00 2001 From: YoussefAWasfy Date: Wed, 25 Sep 2024 11:52:25 +0200 Subject: [PATCH 2/5] test: local resolver --- .../src/resolver/mod.rs | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/affinidi-did-resolver-cache-sdk/src/resolver/mod.rs b/affinidi-did-resolver-cache-sdk/src/resolver/mod.rs index c73d2ee..fdc9c6b 100644 --- a/affinidi-did-resolver-cache-sdk/src/resolver/mod.rs +++ b/affinidi-did-resolver-cache-sdk/src/resolver/mod.rs @@ -87,3 +87,139 @@ impl DIDCacheClient { } } } + +#[cfg(test)] +mod tests { + use crate::{config, DIDCacheClient}; + + const DID_ETHR: &str = "did:ethr:0x1:0xb9c5714089478a327f09197987f16f9e5d936e8a"; + const DID_JWK: &str= "did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9"; + const DID_KEY: &str = "did:key:z6MkiToqovww7vYtxm1xNM15u9JzqzUFZ1k7s7MazYJUyAxv"; + const DID_PEER: &str = "did:peer:2.Vz6MkiToqovww7vYtxm1xNM15u9JzqzUFZ1k7s7MazYJUyAxv.EzQ3shQLqRUza6AMJFbPuMdvFRFWm1wKviQRnQSC1fScovJN4s.SeyJ0IjoiRElEQ29tbU1lc3NhZ2luZyIsInMiOnsidXJpIjoiaHR0cHM6Ly8xMjcuMC4wLjE6NzAzNyIsImEiOlsiZGlkY29tbS92MiJdLCJyIjpbXX19"; + const DID_PKH: &str = "did:pkh:solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ:CKg5d12Jhpej1JqtmxLJgaFqqeYjxgPqToJ4LBdvG9Ev"; + + #[tokio::test] + async fn local_resolve_ethr() { + let config = config::ClientConfigBuilder::default().build(); + let client = DIDCacheClient::new(config).await.unwrap(); + + let parts: Vec<&str> = DID_ETHR.split(':').collect(); + let did_document = client.local_resolve(DID_ETHR, &parts).await.unwrap(); + let verification_relationships = did_document.verification_relationships; + + assert_eq!(did_document.id, DID_ETHR); + + assert_eq!(verification_relationships.authentication.len(), 2); + assert_eq!(verification_relationships.assertion_method.len(), 2); + + assert_eq!(did_document.verification_method.len(), 2,); + } + + #[tokio::test] + async fn local_resolve_jwk() { + let config = config::ClientConfigBuilder::default().build(); + let client = DIDCacheClient::new(config).await.unwrap(); + + let parts: Vec<&str> = DID_JWK.split(':').collect(); + let did_document = client.local_resolve(DID_JWK, &parts).await.unwrap(); + let verification_relationships = did_document.verification_relationships; + + assert_eq!(did_document.id, DID_JWK); + + assert_eq!(verification_relationships.authentication.len(), 1); + assert_eq!(verification_relationships.assertion_method.len(), 1); + assert_eq!(verification_relationships.key_agreement.len(), 1); + assert_eq!(verification_relationships.capability_invocation.len(), 1); + assert_eq!(verification_relationships.capability_delegation.len(), 1); + + assert_eq!(did_document.verification_method.len(), 1); + assert_eq!( + did_document.verification_method.first().unwrap().properties["publicKeyMultibase"], + "zDnaepnC2eBkx4oZkNLGDnVK8ofKzoGk1Yui8fzC6FLoV1F1e" + ); + } + + #[tokio::test] + async fn local_resolve_key() { + let config = config::ClientConfigBuilder::default().build(); + let client = DIDCacheClient::new(config).await.unwrap(); + + let parts: Vec<&str> = DID_KEY.split(':').collect(); + let did_document = client.local_resolve(DID_KEY, &parts).await.unwrap(); + let verification_relationships = did_document.verification_relationships; + + assert_eq!(did_document.id, DID_KEY); + + assert_eq!(verification_relationships.authentication.len(), 1); + assert_eq!(verification_relationships.assertion_method.len(), 1); + + assert_eq!(did_document.verification_method.len(), 1); + assert_eq!( + did_document.verification_method.first().unwrap().properties["publicKeyMultibase"], + parts.last().unwrap().to_string() + ); + } + #[tokio::test] + async fn local_resolve_peer() { + let config = config::ClientConfigBuilder::default().build(); + let client = DIDCacheClient::new(config).await.unwrap(); + + let parts: Vec<&str> = DID_PEER.split(':').collect(); + let did_document = client.local_resolve(DID_PEER, &parts).await.unwrap(); + let verification_relationships = did_document.verification_relationships; + let verification_method = did_document.verification_method; + let service = did_document.service; + + assert_eq!(did_document.id, DID_PEER); + + assert_eq!(verification_relationships.authentication.len(), 1); + assert_eq!(verification_relationships.assertion_method.len(), 1); + assert_eq!(verification_relationships.key_agreement.len(), 1); + + assert_eq!(verification_method.len(), 2); + assert_eq!( + verification_method.first().unwrap().properties["publicKeyMultibase"], + "z6MkiToqovww7vYtxm1xNM15u9JzqzUFZ1k7s7MazYJUyAxv" + ); + assert_eq!( + verification_method.last().unwrap().properties["publicKeyMultibase"], + "zQ3shQLqRUza6AMJFbPuMdvFRFWm1wKviQRnQSC1fScovJN4s" + ); + + assert_eq!(service.len(), 1); + assert_eq!(service.first().unwrap().id, "did:peer:#service"); + } + + #[tokio::test] + async fn local_resolve_pkh() { + let config = config::ClientConfigBuilder::default().build(); + let client = DIDCacheClient::new(config).await.unwrap(); + let parts: Vec<&str> = DID_PKH.split(':').collect(); + + let did_document = client.local_resolve(DID_PKH, &parts).await.unwrap(); + let verification_relationships = did_document.verification_relationships; + let verification_method = did_document.verification_method; + let vm_properties_first = verification_method.first().unwrap().properties.clone(); + let vm_properties_last = verification_method.last().unwrap().properties.clone(); + + assert_eq!(did_document.id, DID_PKH); + + assert_eq!(verification_relationships.authentication.len(), 2); + assert_eq!(verification_relationships.assertion_method.len(), 2); + + assert_eq!(verification_method.len(), 2); + assert_eq!( + vm_properties_first["publicKeyBase58"], + parts.last().unwrap().to_string() + ); + assert_eq!( + vm_properties_first["blockchainAccountId"], + parts[2..parts.len()].join(":") + ); + assert_eq!( + vm_properties_last["blockchainAccountId"], + parts[2..parts.len()].join(":") + ); + assert!(vm_properties_last["publicKeyJwk"].is_object(),); + } +} From 0a8d441797187547e4875e575df7850351596d2f Mon Sep 17 00:00:00 2001 From: YoussefAWasfy Date: Wed, 25 Sep 2024 12:01:46 +0200 Subject: [PATCH 3/5] chore: remove unused imports --- .../src/networking/request_queue.rs | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs index 9b0aeaa..3d421ca 100644 --- a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs +++ b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs @@ -143,9 +143,7 @@ mod tests { use blake2::{Blake2s256, Digest}; use rand::{distributions::Alphanumeric, Rng}; - use rayon::range; - use ssi::dids::DID; - use tokio::sync::oneshot::{self, Receiver, Sender}; + use tokio::sync::oneshot::{self, Sender}; use crate::{ config, @@ -158,6 +156,7 @@ mod tests { async fn new_works() { let config = config::ClientConfigBuilder::default().build(); let request_list = RequestList::new(&config); + assert_eq!(request_list.list_full, false); assert_eq!(request_list.total_count, 0); } @@ -225,6 +224,7 @@ mod tests { async fn remove_key_not_found() { let config = config::ClientConfigBuilder::default().build(); let mut request_list = RequestList::new(&config); + request_list.remove(&_hash_did(DID_KEY), None).unwrap(); } @@ -251,10 +251,12 @@ mod tests { #[tokio::test] async fn remove_passing_uuid_works() { let (mut request_list, did_to_uuid) = _fill_request_list([DID_KEY].to_vec(), true, Some(1)); + let num_of_channels_before_remove = request_list.list.get(&_hash_did(DID_KEY)).unwrap().len(); let total_count_before_remove = request_list.total_count; let ids = did_to_uuid.get(DID_KEY).unwrap(); + request_list .remove(&_hash_did(DID_KEY), ids.first().cloned()) .unwrap(); @@ -270,11 +272,7 @@ mod tests { async fn remove_without_passing_uuid_to_remove_all_works() { let (mut request_list, _) = _fill_request_list([DID_KEY].to_vec(), true, Some(4)); - let total_count_before_remove = request_list.total_count; - let num_of_channels_before_remove = - request_list.list.get(&_hash_did(DID_KEY)).unwrap().len(); - - let removed_list = request_list.remove(&_hash_did(DID_KEY), None).unwrap(); + request_list.remove(&_hash_did(DID_KEY), None).unwrap(); assert_eq!(request_list.total_count, 0); } @@ -282,7 +280,8 @@ mod tests { #[tokio::test] async fn remove_works() { let (mut request_list, _) = _fill_request_list([DID_KEY].to_vec(), false, None); - let removed_list = request_list.remove(&_hash_did(DID_KEY), None).unwrap(); + + request_list.remove(&_hash_did(DID_KEY), None).unwrap(); } fn _hash_did(did: &str) -> String { @@ -290,6 +289,7 @@ mod tests { hasher.update(did); format!("{:x}", hasher.clone().finalize()) } + fn _unique_id() -> String { rand::thread_rng() .sample_iter(&Alphanumeric) @@ -310,14 +310,18 @@ mod tests { oneshot::channel::().0, ) } + let nested_channels_num = if let Some(nested_channels) = fill_channels_for_key_number { nested_channels // This returns the u8 } else { 0 // Handle None case by returning 0 or some other u8 value }; + let mut did_to_uuid_map: HashMap> = HashMap::new(); + let config = config::ClientConfigBuilder::default().build(); let mut request_list = RequestList::new(&config); + for did in dids { let (unique_id, did_hash, tx) = get_hash_and_id(did); let mut uuids_arr: Vec = [unique_id.clone()].to_vec(); From 4cba7963f5ae91d4c5d7c272ea2a0f9da88e34d8 Mon Sep 17 00:00:00 2001 From: YoussefAWasfy Date: Wed, 25 Sep 2024 12:53:01 +0200 Subject: [PATCH 4/5] test: add extra check for panicking --- .../src/networking/request_queue.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs index 3d421ca..f36b062 100644 --- a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs +++ b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs @@ -225,7 +225,9 @@ mod tests { let config = config::ClientConfigBuilder::default().build(); let mut request_list = RequestList::new(&config); - request_list.remove(&_hash_did(DID_KEY), None).unwrap(); + let result = request_list.remove(&_hash_did(DID_KEY), None); + assert!(result.is_none()); + result.unwrap(); } #[should_panic] @@ -233,9 +235,9 @@ mod tests { async fn remove_key_not_found_passing_uuid() { let config = config::ClientConfigBuilder::default().build(); let mut request_list = RequestList::new(&config); - request_list - .remove(&_hash_did(DID_KEY), Some("".to_string())) - .unwrap(); + let result = request_list.remove(&_hash_did(DID_KEY), Some("".to_string())); + assert!(result.is_none()); + result.unwrap(); } #[should_panic] @@ -243,9 +245,10 @@ mod tests { async fn remove_key_not_found_passing_uuid_wrong_did() { let config = config::ClientConfigBuilder::default().build(); let mut request_list = RequestList::new(&config); - request_list - .remove(&_hash_did("wrongdid"), Some("".to_string())) - .unwrap(); + let result = request_list.remove(&_hash_did("wrongdid"), Some("".to_string())); + + assert!(result.is_none()); + result.unwrap(); } #[tokio::test] From a384804779cf179153f3cb8732b9bd1c93f042aa Mon Sep 17 00:00:00 2001 From: YoussefAWasfy Date: Wed, 25 Sep 2024 13:07:25 +0200 Subject: [PATCH 5/5] test: remove should panic macros --- .../src/networking/request_queue.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs index f36b062..989d35a 100644 --- a/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs +++ b/affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs @@ -219,7 +219,7 @@ mod tests { assert_eq!(request_list.total_count, 2); } - #[should_panic] + #[tokio::test] async fn remove_key_not_found() { let config = config::ClientConfigBuilder::default().build(); @@ -227,28 +227,24 @@ mod tests { let result = request_list.remove(&_hash_did(DID_KEY), None); assert!(result.is_none()); - result.unwrap(); } - #[should_panic] #[tokio::test] async fn remove_key_not_found_passing_uuid() { let config = config::ClientConfigBuilder::default().build(); let mut request_list = RequestList::new(&config); + let result = request_list.remove(&_hash_did(DID_KEY), Some("".to_string())); assert!(result.is_none()); - result.unwrap(); } - #[should_panic] #[tokio::test] async fn remove_key_not_found_passing_uuid_wrong_did() { let config = config::ClientConfigBuilder::default().build(); let mut request_list = RequestList::new(&config); - let result = request_list.remove(&_hash_did("wrongdid"), Some("".to_string())); + let result = request_list.remove(&_hash_did("wrongdid"), Some("".to_string())); assert!(result.is_none()); - result.unwrap(); } #[tokio::test]