#![cfg(feature = "test-sbf")]
pub mod setup;
use borsh::BorshDeserialize;
use mpl_distro::{accounts::Distribution, instructions::CreateDistributionBuilder, types::Key, ID};
pub use setup::*;
use solana_program::{program_pack::Pack, pubkey::Pubkey, system_instruction};
use solana_program_test::tokio;
use solana_sdk::{
signature::{Keypair, Signer},
transaction::Transaction,
};
use spl_token::{
instruction as token_instruction,
state::{Account as TokenAccount, Mint},
};
async fn create_mint(
context: &mut solana_program_test::ProgramTestContext,
decimals: u8,
) -> (Keypair, Pubkey) {
let mint_account = Keypair::new();
let mint_authority = context.payer.pubkey();
let rent = context.banks_client.get_rent().await.unwrap();
let mint_rent = rent.minimum_balance(Mint::LEN);
let instructions = [
system_instruction::create_account(
&context.payer.pubkey(),
&mint_account.pubkey(),
mint_rent,
Mint::LEN as u64,
&spl_token::id(),
),
token_instruction::initialize_mint(
&spl_token::id(),
&mint_account.pubkey(),
&mint_authority,
None,
decimals,
)
.unwrap(),
];
let tx = Transaction::new_signed_with_payer(
&instructions,
Some(&context.payer.pubkey()),
&[&context.payer, &mint_account],
context.last_blockhash,
);
context.banks_client.process_transaction(tx).await.unwrap();
(mint_account, mint_authority)
}
async fn create_token_account(
context: &mut solana_program_test::ProgramTestContext,
mint: &Pubkey,
owner: &Pubkey,
) -> Keypair {
let token_account = Keypair::new();
let rent = context.banks_client.get_rent().await.unwrap();
let token_rent = rent.minimum_balance(TokenAccount::LEN);
let instructions = [
system_instruction::create_account(
&context.payer.pubkey(),
&token_account.pubkey(),
token_rent,
TokenAccount::LEN as u64,
&spl_token::id(),
),
token_instruction::initialize_account(
&spl_token::id(),
&token_account.pubkey(),
mint,
owner,
)
.unwrap(),
];
let tx = Transaction::new_signed_with_payer(
&instructions,
Some(&context.payer.pubkey()),
&[&context.payer, &token_account],
context.last_blockhash,
);
context.banks_client.process_transaction(tx).await.unwrap();
token_account
}
#[tokio::test]
async fn test_create_distribution() {
let mut context = program_test().start_with_context().await;
let (mint_account, _) = create_mint(&mut context, 0).await;
let mint = mint_account.pubkey();
let seed = Keypair::new();
let distribution_account = Distribution::find_pda(&mint, &seed.pubkey()).0;
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
let start_time = now;
let end_time = now + 60;
let merkle_root = [0u8; 32];
let total_claimants = 1u64;
let name = "Test Distribution";
let ix = CreateDistributionBuilder::new()
.distribution(distribution_account)
.mint(mint)
.payer(context.payer.pubkey())
.authority(Some(context.payer.pubkey()))
.merkle_root(merkle_root)
.start_time(start_time)
.end_time(end_time)
.total_claimants(total_claimants)
.seed(seed.pubkey())
.name(name.to_string())
.instruction();
let tx = Transaction::new_signed_with_payer(
&[ix],
Some(&context.payer.pubkey()),
&[&context.payer, &seed],
context.last_blockhash,
);
context.banks_client.process_transaction(tx).await.unwrap();
let distribution = context
.banks_client
.get_account(distribution_account)
.await
.unwrap()
.unwrap();
let mut account_data = distribution.data.as_ref();
let distribution = Distribution::deserialize(&mut account_data).unwrap();
assert_eq!(distribution.key, Key::Distribution);
assert_eq!(distribution.authority, context.payer.pubkey());
assert_eq!(distribution.mint, mint);
assert_eq!(distribution.merkle_root, merkle_root);
assert_eq!(distribution.start_time, start_time);
assert_eq!(distribution.end_time, end_time);
assert_eq!(distribution.total_claimants, total_claimants);
assert_eq!(distribution.total_amount, 0);
assert_eq!(distribution.claim_count, 0);
assert_eq!(distribution.claim_amount, 0);
}