use aingle_cortex::prelude::*;
use aingle_cortex::proofs::{ProofMetadata, SubmitProofRequest};
#[tokio::test]
async fn test_proof_store_lifecycle() {
let store = ProofStore::new();
let request = SubmitProofRequest {
proof_type: ProofType::Schnorr,
proof_data: serde_json::json!({
"commitment": vec![0u8; 32],
"challenge": vec![1u8; 32],
"response": vec![2u8; 32],
}),
metadata: None,
};
let proof_id = store.submit(request).await.expect("Failed to submit proof");
assert!(!proof_id.is_empty());
let proof = store.get(&proof_id).await.expect("Proof not found");
assert_eq!(proof.proof_type, ProofType::Schnorr);
assert!(!proof.verified);
let count = store.count().await;
assert_eq!(count, 1);
let deleted = store.delete(&proof_id).await;
assert!(deleted);
let count_after = store.count().await;
assert_eq!(count_after, 0);
}
#[tokio::test]
async fn test_proof_verification() {
let store = ProofStore::new();
let commitment = aingle_zk::HashCommitment::commit(b"test data");
let zk_proof = aingle_zk::ZkProof::hash_opening(&commitment);
let proof_json = serde_json::to_value(&zk_proof).expect("Failed to serialize");
let request = SubmitProofRequest {
proof_type: ProofType::HashOpening,
proof_data: proof_json,
metadata: None,
};
let proof_id = store.submit(request).await.expect("Failed to submit");
let result = store.verify(&proof_id).await.expect("Verification failed");
assert!(result.valid, "Proof should be valid");
assert!(result.verification_time_us > 0);
}
#[tokio::test]
async fn test_batch_proof_submission() {
let store = ProofStore::new();
let requests = vec![
SubmitProofRequest {
proof_type: ProofType::Knowledge,
proof_data: serde_json::json!({"id": 1}),
metadata: None,
},
SubmitProofRequest {
proof_type: ProofType::Equality,
proof_data: serde_json::json!({"id": 2}),
metadata: None,
},
SubmitProofRequest {
proof_type: ProofType::Membership,
proof_data: serde_json::json!({"id": 3}),
metadata: None,
},
];
let results = store.submit_batch(requests).await;
assert_eq!(results.len(), 3);
let successful = results.iter().filter(|r| r.is_ok()).count();
assert_eq!(successful, 3);
let count = store.count().await;
assert_eq!(count, 3);
}
#[tokio::test]
async fn test_batch_proof_verification() {
let store = ProofStore::new();
let mut proof_ids = Vec::new();
for i in 0..3 {
let commitment = aingle_zk::HashCommitment::commit(format!("data {}", i).as_bytes());
let zk_proof = aingle_zk::ZkProof::hash_opening(&commitment);
let proof_json = serde_json::to_value(&zk_proof).unwrap();
let request = SubmitProofRequest {
proof_type: ProofType::HashOpening,
proof_data: proof_json,
metadata: None,
};
let proof_id = store.submit(request).await.unwrap();
proof_ids.push(proof_id);
}
let results = store.batch_verify(&proof_ids).await;
assert_eq!(results.len(), 3);
let all_valid = results
.iter()
.all(|r| r.as_ref().map(|v| v.valid).unwrap_or(false));
assert!(all_valid, "All proofs should be valid");
}
#[tokio::test]
async fn test_proof_filtering_by_type() {
let store = ProofStore::new();
for i in 0..5 {
let proof_type = if i % 2 == 0 {
ProofType::Schnorr
} else {
ProofType::Equality
};
let request = SubmitProofRequest {
proof_type,
proof_data: serde_json::json!({"index": i}),
metadata: None,
};
store.submit(request).await.unwrap();
}
let all_proofs = store.list(None).await;
assert_eq!(all_proofs.len(), 5);
let schnorr_proofs = store.list(Some(ProofType::Schnorr)).await;
assert_eq!(schnorr_proofs.len(), 3);
let equality_proofs = store.list(Some(ProofType::Equality)).await;
assert_eq!(equality_proofs.len(), 2);
}
#[tokio::test]
async fn test_proof_metadata() {
let store = ProofStore::new();
let metadata = ProofMetadata {
submitter: Some("user123".to_string()),
tags: vec!["important".to_string(), "verified".to_string()],
extra: {
let mut map = std::collections::HashMap::new();
map.insert("source".to_string(), serde_json::json!("api"));
map.insert("version".to_string(), serde_json::json!("1.0"));
map
},
};
let request = SubmitProofRequest {
proof_type: ProofType::Knowledge,
proof_data: serde_json::json!({"test": "data"}),
metadata: Some(metadata.clone()),
};
let proof_id = store.submit(request).await.unwrap();
let proof = store.get(&proof_id).await.unwrap();
assert_eq!(proof.metadata.submitter, Some("user123".to_string()));
assert_eq!(proof.metadata.tags.len(), 2);
assert!(proof.metadata.tags.contains(&"important".to_string()));
assert_eq!(
proof.metadata.extra.get("source"),
Some(&serde_json::json!("api"))
);
}
#[tokio::test]
async fn test_verification_cache() {
let store = ProofStore::new();
let commitment = aingle_zk::HashCommitment::commit(b"cached test");
let zk_proof = aingle_zk::ZkProof::hash_opening(&commitment);
let proof_json = serde_json::to_value(&zk_proof).unwrap();
let request = SubmitProofRequest {
proof_type: ProofType::HashOpening,
proof_data: proof_json,
metadata: None,
};
let proof_id = store.submit(request).await.unwrap();
let stats_before = store.stats().await;
let cache_misses_before = stats_before.cache_misses;
store.verify(&proof_id).await.unwrap();
let stats_after_first = store.stats().await;
assert_eq!(stats_after_first.cache_misses, cache_misses_before + 1);
let cache_hits_before = stats_after_first.cache_hits;
store.verify(&proof_id).await.unwrap();
let stats_after_second = store.stats().await;
assert_eq!(stats_after_second.cache_hits, cache_hits_before + 1);
}
#[tokio::test]
async fn test_proof_statistics() {
let store = ProofStore::new();
for i in 0..10 {
let proof_type = match i % 3 {
0 => ProofType::Schnorr,
1 => ProofType::Equality,
_ => ProofType::Membership,
};
let request = SubmitProofRequest {
proof_type,
proof_data: serde_json::json!({"index": i}),
metadata: None,
};
store.submit(request).await.unwrap();
}
let stats = store.stats().await;
assert_eq!(stats.total_proofs, 10);
assert!(stats.proofs_by_type.len() >= 3);
assert!(stats.total_size_bytes > 0);
}
#[tokio::test]
async fn test_proof_verification_with_merkle_tree() {
let store = ProofStore::new();
let leaves: Vec<&[u8]> = vec![b"alice", b"bob", b"charlie"];
let tree = aingle_zk::MerkleTree::new(&leaves).expect("Failed to create tree");
let merkle_proof = tree.prove_data(b"bob").expect("Failed to create proof");
let zk_proof = aingle_zk::ZkProof::membership(tree.root(), merkle_proof);
let proof_json = serde_json::to_value(&zk_proof).unwrap();
let request = SubmitProofRequest {
proof_type: ProofType::Membership,
proof_data: proof_json,
metadata: None,
};
let proof_id = store.submit(request).await.unwrap();
let result = store.verify(&proof_id).await.unwrap();
assert!(result.valid, "Merkle proof should be valid");
}
#[tokio::test]
async fn test_schnorr_proof_verification() {
let store = ProofStore::new();
let commitment = aingle_zk::HashCommitment::commit(b"schnorr test data");
let zk_proof = aingle_zk::ZkProof::hash_opening(&commitment);
let proof_json = serde_json::to_value(&zk_proof).unwrap();
let request = SubmitProofRequest {
proof_type: ProofType::Knowledge,
proof_data: proof_json,
metadata: None,
};
let proof_id = store.submit(request).await.unwrap();
let result = store.verify(&proof_id).await;
assert!(result.is_ok());
assert!(result.unwrap().valid);
}
#[tokio::test]
async fn test_app_state_integration() {
let state = AppState::new().unwrap();
let count = state.proof_store.count().await;
assert_eq!(count, 0);
let commitment = aingle_zk::HashCommitment::commit(b"integration test");
let zk_proof = aingle_zk::ZkProof::hash_opening(&commitment);
let proof_json = serde_json::to_value(&zk_proof).unwrap();
let request = SubmitProofRequest {
proof_type: ProofType::HashOpening,
proof_data: proof_json,
metadata: None,
};
let proof_id = state.proof_store.submit(request).await.unwrap();
let result = state.proof_store.verify(&proof_id).await.unwrap();
assert!(result.valid);
let count_after = state.proof_store.count().await;
assert_eq!(count_after, 1);
}
#[tokio::test]
async fn test_clear_all_proofs() {
let store = ProofStore::new();
for i in 0..5 {
let request = SubmitProofRequest {
proof_type: ProofType::Knowledge,
proof_data: serde_json::json!({"index": i}),
metadata: None,
};
store.submit(request).await.unwrap();
}
assert_eq!(store.count().await, 5);
store.clear().await;
assert_eq!(store.count().await, 0);
let stats = store.stats().await;
assert_eq!(stats.total_proofs, 0);
assert_eq!(stats.total_size_bytes, 0);
}
#[tokio::test]
async fn test_concurrent_proof_operations() {
use tokio::task::JoinSet;
let store = ProofStore::new();
let store = std::sync::Arc::new(store);
let mut join_set = JoinSet::new();
for i in 0..10 {
let store_clone = store.clone();
join_set.spawn(async move {
let request = SubmitProofRequest {
proof_type: ProofType::Knowledge,
proof_data: serde_json::json!({"task": i}),
metadata: None,
};
store_clone.submit(request).await
});
}
let mut results = Vec::new();
while let Some(result) = join_set.join_next().await {
results.push(result.unwrap());
}
assert_eq!(results.len(), 10);
assert!(results.iter().all(|r| r.is_ok()));
let count = store.count().await;
assert_eq!(count, 10);
}
#[tokio::test]
async fn test_proof_type_display() {
assert_eq!(ProofType::Schnorr.to_string(), "schnorr");
assert_eq!(ProofType::Equality.to_string(), "equality");
assert_eq!(ProofType::Membership.to_string(), "membership");
assert_eq!(ProofType::NonMembership.to_string(), "non-membership");
assert_eq!(ProofType::Range.to_string(), "range");
assert_eq!(ProofType::HashOpening.to_string(), "hash-opening");
assert_eq!(ProofType::Knowledge.to_string(), "knowledge");
}