create_idempotent.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. use {
  2. mollusk_svm::result::Check,
  3. solana_program_error::ProgramError,
  4. solana_pubkey::Pubkey,
  5. spl_associated_token_account_mollusk_harness::{
  6. build_create_ata_instruction, token_2022_immutable_owner_account_len,
  7. token_2022_immutable_owner_rent_exempt_balance, AtaTestHarness, CreateAtaInstructionType,
  8. },
  9. };
  10. #[test]
  11. fn success_account_exists() {
  12. let mut harness =
  13. AtaTestHarness::new(&spl_token_2022_interface::id()).with_wallet_and_mint(1_000_000, 6);
  14. // CreateIdempotent will create the ATA if it doesn't exist
  15. let ata_address = harness.create_ata(CreateAtaInstructionType::CreateIdempotent { bump: None });
  16. let associated_account = harness
  17. .ctx
  18. .account_store
  19. .borrow()
  20. .get(&ata_address)
  21. .cloned()
  22. .unwrap();
  23. // Failure case: try to Create when ATA already exists as token account
  24. harness
  25. .ctx
  26. .account_store
  27. .borrow_mut()
  28. .insert(ata_address, associated_account.clone());
  29. let instruction = build_create_ata_instruction(
  30. spl_associated_token_account::id(),
  31. harness.payer,
  32. ata_address,
  33. harness.wallet.unwrap(),
  34. harness.mint.unwrap(),
  35. spl_token_2022_interface::id(),
  36. CreateAtaInstructionType::default(),
  37. );
  38. harness
  39. .ctx
  40. .process_and_validate_instruction(&instruction, &[Check::err(ProgramError::IllegalOwner)]);
  41. // But CreateIdempotent should succeed when account exists
  42. let instruction = build_create_ata_instruction(
  43. spl_associated_token_account::id(),
  44. harness.payer,
  45. ata_address,
  46. harness.wallet.unwrap(),
  47. harness.mint.unwrap(),
  48. spl_token_2022_interface::id(),
  49. CreateAtaInstructionType::CreateIdempotent { bump: None },
  50. );
  51. harness.ctx.process_and_validate_instruction(
  52. &instruction,
  53. &[
  54. Check::success(),
  55. Check::account(&ata_address)
  56. .space(token_2022_immutable_owner_account_len())
  57. .owner(&spl_token_2022_interface::id())
  58. .lamports(token_2022_immutable_owner_rent_exempt_balance())
  59. .build(),
  60. ],
  61. );
  62. }
  63. #[test]
  64. fn fail_account_exists_with_wrong_owner() {
  65. let harness =
  66. AtaTestHarness::new(&spl_token_2022_interface::id()).with_wallet_and_mint(1_000_000, 6);
  67. let wrong_owner = Pubkey::new_unique();
  68. let ata_address = harness.insert_wrong_owner_token_account(wrong_owner);
  69. let instruction = build_create_ata_instruction(
  70. spl_associated_token_account::id(),
  71. harness.payer,
  72. ata_address,
  73. harness.wallet.unwrap(),
  74. harness.mint.unwrap(),
  75. spl_token_2022_interface::id(),
  76. CreateAtaInstructionType::CreateIdempotent { bump: None },
  77. );
  78. harness.ctx.process_and_validate_instruction(
  79. &instruction,
  80. &[Check::err(ProgramError::Custom(
  81. spl_associated_token_account::error::AssociatedTokenAccountError::InvalidOwner as u32,
  82. ))],
  83. );
  84. }
  85. #[test]
  86. fn fail_non_ata() {
  87. let harness =
  88. AtaTestHarness::new(&spl_token_2022_interface::id()).with_wallet_and_mint(1_000_000, 6);
  89. let wrong_account = Pubkey::new_unique();
  90. harness.execute_with_wrong_account_address(wrong_account, ProgramError::InvalidSeeds);
  91. }