#[cfg(test)]
mod tests {
use rialo_s_sdk::signature::{Keypair, Signer};
use crate::{
program::{
FileProgramDataSource, ProgramDeployment, ProgramDeploymentBuilder, ProgramInvocation,
ProgramInvocationBuilder,
},
rpc::types::Pubkey,
};
#[test]
fn test_program_deployment_creation() {
let deployment = ProgramDeployment::new(FileProgramDataSource::from("/path/to/program.so"));
assert_eq!(
deployment.data_source_description(),
"file:/path/to/program.so"
);
assert!(deployment.program_keypair.pubkey() != Pubkey::default());
assert!(deployment.authority.is_none());
}
#[test]
fn test_program_deployment_builder() {
let program_keypair = Keypair::new();
let program_id = program_keypair.pubkey();
let authority = Pubkey::new_unique();
let deployment: ProgramDeployment<FileProgramDataSource> =
ProgramDeploymentBuilder::new(FileProgramDataSource::from("/path/to/program.so"))
.with_program_keypair(program_keypair)
.with_authority(authority)
.build();
assert_eq!(
deployment.data_source_description(),
"file:/path/to/program.so"
);
assert_eq!(deployment.program_keypair.pubkey(), program_id);
assert_eq!(deployment.authority, Some(authority));
}
#[test]
fn test_program_invocation_creation() {
let program_id = Pubkey::new_unique();
let invocation = ProgramInvocation::new(program_id);
assert_eq!(invocation.program_id, program_id);
assert!(invocation.accounts.is_empty());
assert!(invocation.data.is_empty());
}
#[test]
fn test_program_invocation_add_accounts() {
let program_id = Pubkey::new_unique();
let account1 = Pubkey::new_unique();
let account2 = Pubkey::new_unique();
let account3 = Pubkey::new_unique();
let invocation = ProgramInvocation::new(program_id)
.add_readonly_account(account1)
.add_writable_account(account2)
.add_signer_account(account3, true);
assert_eq!(invocation.accounts.len(), 3);
assert_eq!(invocation.accounts[0].pubkey, account1);
assert!(!invocation.accounts[0].is_signer);
assert!(!invocation.accounts[0].is_writable);
assert_eq!(invocation.accounts[1].pubkey, account2);
assert!(!invocation.accounts[1].is_signer);
assert!(invocation.accounts[1].is_writable);
assert_eq!(invocation.accounts[2].pubkey, account3);
assert!(invocation.accounts[2].is_signer);
assert!(invocation.accounts[2].is_writable);
}
#[test]
fn test_program_invocation_with_data() {
let program_id = Pubkey::new_unique();
let test_data = vec![1, 2, 3, 4, 5];
let invocation = ProgramInvocation::new(program_id).with_data(test_data.clone());
assert_eq!(invocation.data, test_data);
}
#[test]
fn test_program_invocation_builder() {
let program_id = Pubkey::new_unique();
let account = Pubkey::new_unique();
let test_data = vec![1, 2, 3];
let invocation = ProgramInvocationBuilder::new(program_id)
.add_signer_account(account, true)
.with_data(test_data.clone())
.build();
assert_eq!(invocation.program_id, program_id);
assert_eq!(invocation.accounts.len(), 1);
assert_eq!(invocation.accounts[0].pubkey, account);
assert!(invocation.accounts[0].is_signer);
assert!(invocation.accounts[0].is_writable);
assert_eq!(invocation.data, test_data);
}
#[test]
fn test_program_invocation_helper_functions() {
let program_id = Pubkey::new_unique();
let from = Pubkey::new_unique();
let to = Pubkey::new_unique();
let data = vec![1, 2, 3];
let transfer_invocation =
ProgramInvocation::transfer_like(program_id, from, to, data.clone());
assert_eq!(transfer_invocation.program_id, program_id);
assert_eq!(transfer_invocation.accounts.len(), 2);
assert_eq!(transfer_invocation.accounts[0].pubkey, from);
assert!(transfer_invocation.accounts[0].is_signer);
assert!(transfer_invocation.accounts[0].is_writable);
assert_eq!(transfer_invocation.accounts[1].pubkey, to);
assert!(!transfer_invocation.accounts[1].is_signer);
assert!(transfer_invocation.accounts[1].is_writable);
assert_eq!(transfer_invocation.data, data);
let initializer = Pubkey::new_unique();
let account_to_init = Pubkey::new_unique();
let init_invocation =
ProgramInvocation::initialize(program_id, initializer, account_to_init, data.clone());
assert_eq!(init_invocation.program_id, program_id);
assert_eq!(init_invocation.accounts.len(), 2);
assert_eq!(init_invocation.accounts[0].pubkey, initializer);
assert!(init_invocation.accounts[0].is_signer);
assert!(init_invocation.accounts[0].is_writable);
assert_eq!(init_invocation.accounts[1].pubkey, account_to_init);
assert!(!init_invocation.accounts[1].is_signer);
assert!(init_invocation.accounts[1].is_writable);
let authority = Pubkey::new_unique();
let account_to_close = Pubkey::new_unique();
let rent_recipient = Pubkey::new_unique();
let close_invocation = ProgramInvocation::close_account(
program_id,
authority,
account_to_close,
rent_recipient,
);
assert_eq!(close_invocation.program_id, program_id);
assert_eq!(close_invocation.accounts.len(), 3);
assert_eq!(close_invocation.accounts[0].pubkey, authority);
assert!(close_invocation.accounts[0].is_signer);
assert!(!close_invocation.accounts[0].is_writable);
assert_eq!(close_invocation.accounts[1].pubkey, account_to_close);
assert!(close_invocation.accounts[1].is_writable);
assert_eq!(close_invocation.accounts[2].pubkey, rent_recipient);
assert!(close_invocation.accounts[2].is_writable);
assert!(close_invocation.data.is_empty());
}
#[test]
fn test_instruction_conversion() {
let program_id = Pubkey::new_unique();
let account = Pubkey::new_unique();
let data = vec![1, 2, 3, 4];
let invocation = ProgramInvocation::new(program_id)
.add_signer_account(account, true)
.with_data(data.clone());
let instruction = invocation.into_instruction();
assert_eq!(instruction.program_id, program_id);
assert_eq!(instruction.accounts.len(), 1);
assert_eq!(instruction.accounts[0].pubkey, account);
assert!(instruction.accounts[0].is_signer);
assert!(instruction.accounts[0].is_writable);
assert_eq!(instruction.data, data);
}
#[cfg(feature = "borsh")]
#[test]
fn test_program_invocation_with_borsh_data() {
use borsh::{BorshDeserialize, BorshSerialize};
#[derive(PartialEq, Debug)]
struct TestInstruction {
value: u64,
name: String,
}
impl BorshSerialize for TestInstruction {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
self.value.serialize(writer)?;
self.name.serialize(writer)
}
}
impl BorshDeserialize for TestInstruction {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
Ok(Self {
value: BorshDeserialize::deserialize_reader(reader)?,
name: BorshDeserialize::deserialize_reader(reader)?,
})
}
}
let program_id = Pubkey::new_unique();
let test_instruction = TestInstruction {
value: 42,
name: "test".to_string(),
};
let invocation = ProgramInvocation::new(program_id)
.with_borsh_data(&test_instruction)
.expect("Failed to serialize with borsh");
let deserialized: TestInstruction =
TestInstruction::try_from_slice(&invocation.data).expect("Failed to deserialize");
assert_eq!(deserialized, test_instruction);
}
}