favorites.ts 3.2 KB

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