Skip to content

Commit 58c5c45

Browse files
committed
feat: add LiteSVM tests for favorites anchor program
- Implement tests for writing, updating, and validating favorite data on the blockchain. - Ensure unauthorized transactions are rejected correctly. - Utilize LiteSVM for transaction simulation and account state verification.
1 parent 020ebe7 commit 58c5c45

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import anchor from "@coral-xyz/anchor";
2+
import {
3+
Keypair,
4+
PublicKey,
5+
SystemProgram,
6+
Transaction,
7+
TransactionInstruction,
8+
} from "@solana/web3.js";
9+
import { assert } from "chai";
10+
import { LiteSVM } from "litesvm";
11+
12+
import IDL from "../target/idl/favorites.json" with { type: "json" };
13+
14+
describe("LiteSVM: Favorites", () => {
15+
const svm = new LiteSVM();
16+
const programId = new PublicKey(IDL.address);
17+
const coder = new anchor.BorshCoder(IDL as anchor.Idl); //For serialization and deserialization
18+
const payer = Keypair.generate();
19+
svm.airdrop(payer.publicKey, BigInt(1000000000));
20+
21+
const programPath = new URL("../target/deploy/favorites.so", import.meta.url)
22+
.pathname;
23+
svm.addProgramFromFile(programId, programPath);
24+
25+
const [favPdaAccount] = PublicKey.findProgramAddressSync(
26+
[Buffer.from("favorites"), payer.publicKey.toBuffer()],
27+
programId,
28+
);
29+
/**
30+
* Here's what we want to write to the blockchain
31+
*/
32+
const favoriteNumber = new anchor.BN(23);
33+
const favoriteColor = "purple";
34+
const favoriteHobbies = ["skiing", "skydiving", "biking"];
35+
36+
it("Writes our favorites to the blockchain", () => {
37+
const ixArgs = {
38+
number: favoriteNumber,
39+
color: favoriteColor,
40+
hobbies: favoriteHobbies,
41+
};
42+
43+
const data = coder.instruction.encode("set_favorites", ixArgs);
44+
const ix = new TransactionInstruction({
45+
keys: [
46+
{ pubkey: payer.publicKey, isSigner: true, isWritable: true },
47+
{ pubkey: favPdaAccount, isSigner: false, isWritable: true },
48+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
49+
],
50+
programId,
51+
data,
52+
});
53+
54+
const tx = new Transaction().add(ix);
55+
tx.feePayer = payer.publicKey;
56+
tx.recentBlockhash = svm.latestBlockhash();
57+
tx.sign(payer);
58+
svm.sendTransaction(tx);
59+
60+
/**
61+
* Fetch the account and check its favorites
62+
*/
63+
const favAccountInfo = svm.getAccount(favPdaAccount);
64+
const favAccount = coder.accounts.decode(
65+
"Favorites",
66+
Buffer.from(favAccountInfo.data),
67+
);
68+
69+
assert.equal(favAccount.number.toNumber(), favoriteNumber.toNumber());
70+
assert.equal(favAccount.color, favoriteColor);
71+
assert.deepStrictEqual(favAccount.hobbies, favoriteHobbies);
72+
});
73+
74+
it("Updates the favorites", () => {
75+
const newFavoriteHobbies = ["coding", "reading", "biking", "swimming"];
76+
const ixArgs = {
77+
number: favoriteNumber,
78+
color: favoriteColor,
79+
hobbies: newFavoriteHobbies,
80+
};
81+
82+
const data = coder.instruction.encode("set_favorites", ixArgs);
83+
const ix = new TransactionInstruction({
84+
keys: [
85+
{ pubkey: payer.publicKey, isSigner: true, isWritable: true },
86+
{ pubkey: favPdaAccount, isSigner: false, isWritable: true },
87+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
88+
],
89+
programId,
90+
data,
91+
});
92+
93+
const tx = new Transaction().add(ix);
94+
tx.feePayer = payer.publicKey;
95+
tx.recentBlockhash = svm.latestBlockhash();
96+
tx.sign(payer);
97+
svm.sendTransaction(tx);
98+
99+
/**
100+
* Fetch the account and check its favorites
101+
*/
102+
const favAccountInfo = svm.getAccount(favPdaAccount);
103+
const favAccount = coder.accounts.decode(
104+
"Favorites",
105+
Buffer.from(favAccountInfo.data),
106+
);
107+
108+
assert.equal(favAccount.number.toNumber(), favoriteNumber.toNumber());
109+
assert.equal(favAccount.color, favoriteColor);
110+
assert.deepStrictEqual(favAccount.hobbies, newFavoriteHobbies);
111+
});
112+
113+
it("Rejects transactions from unauthorized signers", () => {
114+
const newFavoriteHobbies = ["coding", "reading", "biking"];
115+
const someRandomGuy = Keypair.generate();
116+
117+
const ixArgs = {
118+
number: favoriteNumber,
119+
color: favoriteColor,
120+
hobbies: newFavoriteHobbies,
121+
};
122+
123+
const data = coder.instruction.encode("set_favorites", ixArgs);
124+
const ix = new TransactionInstruction({
125+
keys: [
126+
{ pubkey: payer.publicKey, isSigner: true, isWritable: true },
127+
{ pubkey: favPdaAccount, isSigner: false, isWritable: true },
128+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
129+
],
130+
programId,
131+
data,
132+
});
133+
134+
const tx = new Transaction().add(ix);
135+
tx.feePayer = payer.publicKey;
136+
tx.recentBlockhash = svm.latestBlockhash();
137+
138+
assert.Throw(() => {
139+
tx.sign(someRandomGuy);
140+
svm.sendTransaction(tx);
141+
}, "unknown signer");
142+
});
143+
});

0 commit comments

Comments
 (0)