From a5ffb3f709aad78a190e1ca2c6ede097e2e134e0 Mon Sep 17 00:00:00 2001 From: febo Date: Sat, 30 Aug 2025 01:30:03 +0100 Subject: [PATCH] Add more tests --- p-token/tests/initialize_immutable_owner.rs | 63 ++++++++++++++ p-token/tests/sync_native.rs | 93 +++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 p-token/tests/initialize_immutable_owner.rs create mode 100644 p-token/tests/sync_native.rs diff --git a/p-token/tests/initialize_immutable_owner.rs b/p-token/tests/initialize_immutable_owner.rs new file mode 100644 index 00000000..f6b9c468 --- /dev/null +++ b/p-token/tests/initialize_immutable_owner.rs @@ -0,0 +1,63 @@ +mod setup; + +use { + setup::TOKEN_PROGRAM_ID, + solana_keypair::Keypair, + solana_program_pack::Pack, + solana_program_test::{tokio, ProgramTest}, + solana_signer::Signer, + solana_system_interface::instruction::create_account, + solana_transaction::Transaction, + spl_token::state::AccountState, +}; + +#[tokio::test] +async fn initialize_immutable_owner() { + let context = ProgramTest::new("pinocchio_token_program", TOKEN_PROGRAM_ID, None) + .start_with_context() + .await; + + // Given an uninitialize account. + + let account = Keypair::new(); + + let account_size = 165; + let rent = context.banks_client.get_rent().await.unwrap(); + + // When we execute the initialize_immutable_owner instruction. + + let instructions = vec![ + create_account( + &context.payer.pubkey(), + &account.pubkey(), + rent.minimum_balance(account_size), + account_size as u64, + &TOKEN_PROGRAM_ID, + ), + spl_token::instruction::initialize_immutable_owner(&TOKEN_PROGRAM_ID, &account.pubkey()) + .unwrap(), + ]; + + let tx = Transaction::new_signed_with_payer( + &instructions, + Some(&context.payer.pubkey()), + &[&context.payer, &account], + context.last_blockhash, + ); + context.banks_client.process_transaction(tx).await.unwrap(); + + // Then the instruction should succeed. + + let account = context + .banks_client + .get_account(account.pubkey()) + .await + .unwrap(); + + assert!(account.is_some()); + + let account = account.unwrap(); + let account = spl_token::state::Account::unpack_unchecked(&account.data).unwrap(); + + assert_eq!(account.state, AccountState::Uninitialized); +} diff --git a/p-token/tests/sync_native.rs b/p-token/tests/sync_native.rs new file mode 100644 index 00000000..ea8fff0c --- /dev/null +++ b/p-token/tests/sync_native.rs @@ -0,0 +1,93 @@ +mod setup; + +use { + crate::setup::TOKEN_PROGRAM_ID, + mollusk_svm::{result::Check, Mollusk}, + pinocchio_token_interface::{ + native_mint, + state::{ + account::Account as TokenAccount, account_state::AccountState, load_mut_unchecked, + }, + }, + solana_account::Account, + solana_program_pack::Pack, + solana_program_test::tokio, + solana_pubkey::Pubkey, + solana_rent::Rent, + solana_sdk_ids::bpf_loader_upgradeable, +}; + +fn create_token_account( + mint: &Pubkey, + owner: &Pubkey, + is_native: bool, + amount: u64, + program_owner: &Pubkey, +) -> Account { + let space = size_of::(); + let mut lamports = Rent::default().minimum_balance(space); + + let mut data: Vec = vec![0u8; space]; + let token = unsafe { load_mut_unchecked::(data.as_mut_slice()).unwrap() }; + token.set_account_state(AccountState::Initialized); + token.mint = *mint.as_array(); + token.owner = *owner.as_array(); + token.set_amount(amount); + token.set_native(is_native); + + if is_native { + token.set_native_amount(lamports); + lamports = lamports.saturating_add(amount); + } + + Account { + lamports, + data, + owner: *program_owner, + executable: false, + ..Default::default() + } +} + +/// Creates a Mollusk instance with the default feature set, excluding the +/// `bpf_account_data_direct_mapping` feature. +fn mollusk() -> Mollusk { + let mut mollusk = Mollusk::default(); + mollusk.add_program( + &TOKEN_PROGRAM_ID, + "pinocchio_token_program", + &bpf_loader_upgradeable::id(), + ); + mollusk +} + +#[tokio::test] +async fn sync_native() { + let native_mint = Pubkey::new_from_array(native_mint::ID); + let authority_key = Pubkey::new_unique(); + + // native account + // - amount: 1_000_000_000 + // - lamports: 2_000_000_000 + let source_account_key = Pubkey::new_unique(); + let mut source_account = + create_token_account(&native_mint, &authority_key, true, 0, &TOKEN_PROGRAM_ID); + source_account.lamports += 2_000_000_000; + + let instruction = + spl_token::instruction::sync_native(&TOKEN_PROGRAM_ID, &source_account_key).unwrap(); + + // Executes the sync_native instruction. + + let result = mollusk().process_and_validate_instruction_chain( + &[(&instruction, &[Check::success()])], + &[(source_account_key, source_account)], + ); + + result.resulting_accounts.iter().for_each(|(key, account)| { + if *key == source_account_key { + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); + assert_eq!(token_account.amount, 2_000_000_000); + } + }); +}