Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(FTL-17137): add affinidi-did-resolver-cache-sdk unit tests #31

Merged
merged 5 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(),);
}
}
Loading