178 lines
5.6 KiB
Rust
178 lines
5.6 KiB
Rust
/// Integration test: resolve() calls update_stats() via CPI when the resolver
|
|
/// has a registered entry in the Resolver Registry.
|
|
mod common;
|
|
use common::*;
|
|
use anchor_lang::InstructionData;
|
|
use anchor_lang::ToAccountMetas;
|
|
use anchor_lang::solana_program::{instruction::Instruction, system_program};
|
|
use descro_ext_resolvers::{ResolverType, ResolverEntry};
|
|
use anchor_lang::AccountDeserialize;
|
|
use litesvm::LiteSVM;
|
|
use solana_keypair::Keypair;
|
|
use solana_signer::Signer;
|
|
|
|
fn setup_both_programs() -> (LiteSVM, Keypair, Keypair, Keypair) {
|
|
let mut svm = LiteSVM::new();
|
|
|
|
let escrow_bytes = include_bytes!("../../../target/deploy/descro.so");
|
|
svm.add_program(descro::id(), escrow_bytes).unwrap();
|
|
|
|
let registry_bytes = include_bytes!("../../../target/deploy/descro_ext_resolvers.so");
|
|
svm.add_program(descro_ext_resolvers::id(), registry_bytes).unwrap();
|
|
|
|
let seller = Keypair::new();
|
|
let buyer = Keypair::new();
|
|
let resolver = Keypair::new();
|
|
|
|
svm.airdrop(&seller.pubkey(), 10_000_000_000).unwrap();
|
|
svm.airdrop(&buyer.pubkey(), 10_000_000_000).unwrap();
|
|
svm.airdrop(&resolver.pubkey(), 5_000_000_000).unwrap();
|
|
|
|
(svm, seller, buyer, resolver)
|
|
}
|
|
|
|
fn ix_register_resolver(authority: &Pubkey) -> Instruction {
|
|
let entry = resolver_entry_pda(authority);
|
|
Instruction::new_with_bytes(
|
|
descro_ext_resolvers::id(),
|
|
&descro_ext_resolvers::instruction::RegisterResolver {
|
|
resolver_type: ResolverType::CentralAuthority,
|
|
name: "Test Resolver".to_string(),
|
|
description: "Integration test resolver".to_string(),
|
|
fee_bps: 100,
|
|
fee_recipient: *authority,
|
|
metadata_uri: "ipfs://test".to_string(),
|
|
}
|
|
.data(),
|
|
descro_ext_resolvers::accounts::RegisterResolver {
|
|
authority: *authority,
|
|
resolver_entry: entry,
|
|
system_program: system_program::ID,
|
|
}
|
|
.to_account_metas(None),
|
|
)
|
|
}
|
|
|
|
fn read_resolver_entry(svm: &LiteSVM, authority: &Pubkey) -> ResolverEntry {
|
|
let pda = resolver_entry_pda(authority);
|
|
let account = svm.get_account(&pda).expect("resolver entry not found");
|
|
ResolverEntry::try_deserialize(&mut account.data.as_slice()).unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn resolve_updates_stats_when_resolver_registered() {
|
|
let (mut svm, seller, buyer, resolver) = setup_both_programs();
|
|
|
|
// Register the resolver in the Registry
|
|
send(&mut svm, ix_register_resolver(&resolver.pubkey()), &resolver);
|
|
|
|
// Full escrow flow
|
|
send(
|
|
&mut svm,
|
|
ix_create_escrow(
|
|
&seller.pubkey(),
|
|
&buyer.pubkey(),
|
|
AMOUNT,
|
|
Some(resolver.pubkey()),
|
|
ESCROW_ID,
|
|
),
|
|
&seller,
|
|
);
|
|
send(&mut svm, ix_deposit(&buyer.pubkey(), &seller.pubkey(), ESCROW_ID), &buyer);
|
|
send(&mut svm, ix_dispute(&buyer.pubkey(), &seller.pubkey(), ESCROW_ID), &buyer);
|
|
|
|
// Resolve with registry program provided
|
|
send(
|
|
&mut svm,
|
|
ix_resolve(
|
|
&resolver.pubkey(),
|
|
&seller.pubkey(),
|
|
&seller.pubkey(),
|
|
ESCROW_ID,
|
|
EscrowWinner::Seller,
|
|
descro_ext_resolvers::id(), // pass registry program → triggers CPI
|
|
),
|
|
&resolver,
|
|
);
|
|
|
|
let entry = read_resolver_entry(&svm, &resolver.pubkey());
|
|
assert_eq!(entry.total_resolved, 1);
|
|
assert_eq!(entry.ruled_for_seller, 1);
|
|
assert_eq!(entry.ruled_for_buyer, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn resolve_skips_stats_when_resolver_not_registered() {
|
|
let (mut svm, seller, buyer, resolver) = setup_both_programs();
|
|
|
|
// Do NOT register resolver — entry does not exist
|
|
send(
|
|
&mut svm,
|
|
ix_create_escrow(
|
|
&seller.pubkey(),
|
|
&buyer.pubkey(),
|
|
AMOUNT,
|
|
Some(resolver.pubkey()),
|
|
ESCROW_ID,
|
|
),
|
|
&seller,
|
|
);
|
|
send(&mut svm, ix_deposit(&buyer.pubkey(), &seller.pubkey(), ESCROW_ID), &buyer);
|
|
send(&mut svm, ix_dispute(&buyer.pubkey(), &seller.pubkey(), ESCROW_ID), &buyer);
|
|
|
|
// Resolve without passing registry program — CPI skipped
|
|
send(
|
|
&mut svm,
|
|
ix_resolve(
|
|
&resolver.pubkey(),
|
|
&seller.pubkey(),
|
|
&seller.pubkey(),
|
|
ESCROW_ID,
|
|
EscrowWinner::Seller,
|
|
system_program::ID, // no registry → CPI skipped
|
|
),
|
|
&resolver,
|
|
);
|
|
|
|
// Escrow closed, resolver entry still absent
|
|
assert!(svm.get_account(&escrow_pda(&seller.pubkey(), ESCROW_ID)).is_none());
|
|
assert!(svm.get_account(&resolver_entry_pda(&resolver.pubkey())).is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn resolve_buyer_wins_increments_ruled_for_buyer() {
|
|
let (mut svm, seller, buyer, resolver) = setup_both_programs();
|
|
|
|
send(&mut svm, ix_register_resolver(&resolver.pubkey()), &resolver);
|
|
send(
|
|
&mut svm,
|
|
ix_create_escrow(
|
|
&seller.pubkey(),
|
|
&buyer.pubkey(),
|
|
AMOUNT,
|
|
Some(resolver.pubkey()),
|
|
ESCROW_ID,
|
|
),
|
|
&seller,
|
|
);
|
|
send(&mut svm, ix_deposit(&buyer.pubkey(), &seller.pubkey(), ESCROW_ID), &buyer);
|
|
send(&mut svm, ix_dispute(&buyer.pubkey(), &seller.pubkey(), ESCROW_ID), &buyer);
|
|
send(
|
|
&mut svm,
|
|
ix_resolve(
|
|
&resolver.pubkey(),
|
|
&buyer.pubkey(),
|
|
&seller.pubkey(),
|
|
ESCROW_ID,
|
|
EscrowWinner::Buyer,
|
|
descro_ext_resolvers::id(),
|
|
),
|
|
&resolver,
|
|
);
|
|
|
|
let entry = read_resolver_entry(&svm, &resolver.pubkey());
|
|
assert_eq!(entry.total_resolved, 1);
|
|
assert_eq!(entry.ruled_for_buyer, 1);
|
|
assert_eq!(entry.ruled_for_seller, 0);
|
|
}
|