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