favorites-bankrun.test.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import { describe, it } from 'node:test';
  2. import * as anchor from '@coral-xyz/anchor';
  3. import { PublicKey } from '@solana/web3.js';
  4. import { BankrunProvider } from 'anchor-bankrun';
  5. import { assert } from 'chai';
  6. import { startAnchor } from 'solana-bankrun';
  7. import type { FavoritesProgram } from '../target/types/favorites_program';
  8. const web3 = anchor.web3;
  9. const IDL = require('../target/idl/favorites_program.json');
  10. const PROGRAM_ID = new PublicKey(IDL.address);
  11. describe('Favorites Bankrun', async () => {
  12. // Use the cluster and the keypair from Anchor.toml
  13. // Load programs into anchor-bankrun
  14. const context = await startAnchor('', [{ name: 'favorites_program', programId: PROGRAM_ID }], []);
  15. const provider = new BankrunProvider(context);
  16. anchor.setProvider(provider);
  17. const user = (provider.wallet as anchor.Wallet).payer;
  18. const someRandomGuy = anchor.web3.Keypair.generate();
  19. const program = new anchor.Program<FavoritesProgram>(IDL, provider);
  20. // Here"s what we want to write to the blockchain
  21. const favoriteNumber = new anchor.BN(23);
  22. const favoriteColor = 'purple';
  23. const favoriteHobbies = ['skiing', 'skydiving', 'biking'];
  24. // We don"t need to airdrop if we"re using the local cluster
  25. // because the local cluster gives us 1,000,000 SOL
  26. const balance = await context.banksClient.getBalance(user.publicKey);
  27. const balanceInSOL = balance / BigInt(web3.LAMPORTS_PER_SOL);
  28. const formattedBalance = new Intl.NumberFormat().format(balanceInSOL);
  29. console.log(`Balance: ${formattedBalance} SOL`);
  30. it('Writes our favorites to the blockchain', async () => {
  31. await program.methods
  32. // set_favourites in Rust becomes setFavorites in TypeScript
  33. .setFavorites(favoriteNumber, favoriteColor, favoriteHobbies)
  34. // Sign the transaction
  35. .signers([user])
  36. // Send the transaction to the cluster or RPC
  37. .rpc();
  38. // Find the PDA for the user"s favorites
  39. const favoritesPdaAndBump = web3.PublicKey.findProgramAddressSync([Buffer.from('favorites'), user.publicKey.toBuffer()], program.programId);
  40. const favoritesPda = favoritesPdaAndBump[0];
  41. const dataFromPda = await program.account.favorites.fetch(favoritesPda);
  42. // And make sure it matches!
  43. assert.equal(dataFromPda.color, favoriteColor);
  44. // A little extra work to make sure the BNs are equal
  45. assert.equal(dataFromPda.number.toString(), favoriteNumber.toString());
  46. // And check the hobbies too
  47. assert.deepEqual(dataFromPda.hobbies, favoriteHobbies);
  48. });
  49. it('Updates the favorites', async () => {
  50. const newFavoriteHobbies = ['skiing', 'skydiving', 'biking', 'swimming'];
  51. try {
  52. await program.methods.setFavorites(favoriteNumber, favoriteColor, newFavoriteHobbies).signers([user]).rpc();
  53. } catch (error) {
  54. const errorMessage = (error as Error).message;
  55. assert.isTrue(errorMessage.includes('SendTransactionError'));
  56. }
  57. });
  58. it('Rejects transactions from unauthorized signers', async () => {
  59. try {
  60. await program.methods
  61. // set_favourites in Rust becomes setFavorites in TypeScript
  62. .setFavorites(favoriteNumber, favoriteColor, favoriteHobbies)
  63. // Sign the transaction
  64. .signers([someRandomGuy])
  65. // Send the transaction to the cluster or RPC
  66. .rpc();
  67. } catch (error) {
  68. const errorMessage = (error as Error).message;
  69. assert.isTrue(errorMessage.includes('unknown signer'));
  70. }
  71. });
  72. });