Skip to content

Commit

Permalink
test(FTL-17137): add affinidi-did-resolver-cache-sdk unit tests (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
YoussefAWasfy authored Sep 26, 2024
1 parent 61428d6 commit c22af1f
Show file tree
Hide file tree
Showing 2 changed files with 338 additions and 0 deletions.
202 changes: 202 additions & 0 deletions affinidi-did-resolver-cache-sdk/src/networking/request_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,205 @@ impl RequestList {
self.list_full
}
}
#[cfg(test)]
mod tests {

use std::collections::HashMap;

use blake2::{Blake2s256, Digest};
use rand::{distributions::Alphanumeric, Rng};
use tokio::sync::oneshot::{self, 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::<WSCommands>();

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::<WSCommands>();
let (tx2, _) = oneshot::channel::<WSCommands>();

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::<WSCommands>();
let (tx2, _) = oneshot::channel::<WSCommands>();

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);
}

#[tokio::test]
async fn remove_key_not_found() {
let config = config::ClientConfigBuilder::default().build();
let mut request_list = RequestList::new(&config);

let result = request_list.remove(&_hash_did(DID_KEY), None);
assert!(result.is_none());
}

#[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());
}

#[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()));
assert!(result.is_none());
}

#[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));

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);

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<u8>,
) -> (RequestList, HashMap<String, Vec<String>>) {
fn get_hash_and_id(did: &str) -> (String, String, Sender<WSCommands>) {
(
_unique_id(),
_hash_did(&did),
oneshot::channel::<WSCommands>().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<String, Vec<String>> = 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<String> = [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)
}
}
136 changes: 136 additions & 0 deletions affinidi-did-resolver-cache-sdk/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),);
}
}

0 comments on commit c22af1f

Please sign in to comment.