favorites.ts 3.2 KB

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