Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
robertohuertasm committed Oct 21, 2024
1 parent 465c575 commit c22d54e
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 15 deletions.
33 changes: 18 additions & 15 deletions basics/program-derived-addresses/steel/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
# ProgramDerivedAddresses
# Program Derived Addresses

**ProgramDerivedAddresses** is a ...

## API
- [`Consts`](api/src/consts.rs) – Program constants.
- [`Error`](api/src/error.rs) – Custom program errors.
- [`Event`](api/src/event.rs) – Custom program events.
- [`Instruction`](api/src/instruction.rs) – Declared instructions.
This program demonstrates how to derive addresses. It will use a PDA to store a counter of visits and increment it.

## Instructions
- [`Hello`](program/src/hello.rs) – Hello ...
## Building

## State
- [`User`](api/src/state/user.rs) – User ...
```sh
cargo build-sbf

```
## Tests

To run the test suit, use the Solana toolchain:
```
cargo test-sbf
This project includes both:
- Rust tests: [`program/tests`](/program/tests) directory.
- Node.js tests using [Bankrun](https://kevinheavey.github.io/solana-bankrun/): [`tests`](/tests) directory.

```sh
# rust tests
cargo test-sbf

# node tests
pnpm build-and-test # this will also build the program
#or
pnpm test # if you have already built the program
```
1 change: 1 addition & 0 deletions basics/program-derived-addresses/steel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@types/chai": "^4.3.7",
"@types/mocha": "10.0.9",
"@types/node": "^22.7.4",
"borsh": "^2.0.0",
"chai": "^4.3.7",
"mocha": "10.7.3",
"solana-bankrun": "0.4.0",
Expand Down
8 changes: 8 additions & 0 deletions basics/program-derived-addresses/steel/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

154 changes: 154 additions & 0 deletions basics/program-derived-addresses/steel/tests/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { Keypair, PublicKey, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js';
import * as borsh from 'borsh';
import { assert } from 'chai';
import { describe, it } from 'mocha';
import { BanksClient, ProgramTestContext, start } from 'solana-bankrun';

type PageVisits = {
page_visits: number;
bump: number;
};

const pageVisitsSchema: borsh.Schema = {
struct: {
discriminator: 'u64',
page_visits: 'u32',
bump: 'u8',
},
};

const createPageVisitsBuffer = (data: PageVisits): Buffer => {
const pageVisits = Buffer.alloc(4);
pageVisits.writeUInt32LE(data.page_visits, 0);
const bump = Buffer.alloc(1);
bump.writeUInt8(data.bump, 0);
return Buffer.concat([pageVisits, bump]);
};

describe('program derived addresses program', async () => {
const PROGRAM_ID = new PublicKey('z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35');

let context: ProgramTestContext;
let client: BanksClient;
let payer: Keypair;

const testUser = Keypair.generate();

const instructionDiscriminators = {
create: Buffer.from([0]),
increment: Buffer.from([1]),
};

const derivePageVisitsPDA = async (user: PublicKey) => {
const seed = Buffer.from('program-derived-addresses');
return PublicKey.findProgramAddressSync([seed, user.toBuffer()], PROGRAM_ID);
};

before(async () => {
context = await start([{ name: 'program_derived_addresses_program', programId: PROGRAM_ID }], []);
client = context.banksClient;
payer = context.payer;
});

it('should create a page visits tracking PDA', async () => {
const [pageVisitsPDA] = await derivePageVisitsPDA(testUser.publicKey);

// create the page visits data
const pageVisits: PageVisits = { page_visits: 0, bump: 0 };
const pageVisitsBuffer = createPageVisitsBuffer(pageVisits);
const data = Buffer.concat([instructionDiscriminators.create, pageVisitsBuffer]);

// create the create instruction
const createIx = new TransactionInstruction({
programId: PROGRAM_ID,
keys: [
{ pubkey: payer.publicKey, isSigner: true, isWritable: true },
{ pubkey: testUser.publicKey, isSigner: false, isWritable: false },
{ pubkey: pageVisitsPDA, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
],
data,
});

// send the create transaction
const createTx = new Transaction();
createTx.recentBlockhash = context.lastBlockhash;
createTx.add(createIx).sign(payer);

// process the transaction
await client.processTransaction(createTx);

// fetch the counter account data
const pageVisitsInfo = await client.getAccount(pageVisitsPDA);
assert(pageVisitsInfo !== null, 'account should exist');
});

it('should visit the page and get 1 visit!', async () => {
const [pageVisitsPDA] = await derivePageVisitsPDA(testUser.publicKey);

// create the increment instruction
const incrementIx = new TransactionInstruction({
programId: PROGRAM_ID,
keys: [{ pubkey: pageVisitsPDA, isSigner: false, isWritable: true }],
data: instructionDiscriminators.increment,
});

// send the increment transaction
const incrementTx = new Transaction();
incrementTx.recentBlockhash = context.lastBlockhash;
incrementTx.add(incrementIx).sign(payer);

// process the transaction
await client.processTransaction(incrementTx);

// fetch the account data
const pageVisitsInfo = await client.getAccount(pageVisitsPDA);
assert(pageVisitsInfo !== null, 'account should exist');

const data = borsh.deserialize(pageVisitsSchema, pageVisitsInfo?.data) as PageVisits;

assert(data.page_visits === 1, 'page visits should be 1');
});

it('should visit the page and get 2 visits!', async () => {
const [pageVisitsPDA] = await derivePageVisitsPDA(testUser.publicKey);

// create the increment instruction
const incrementIx = new TransactionInstruction({
programId: PROGRAM_ID,
keys: [{ pubkey: pageVisitsPDA, isSigner: false, isWritable: true }],
data: instructionDiscriminators.increment,
});

// get last blockhash
const [blockhash, _block_height] = await client.getLatestBlockhash();

// send the increment transaction
const incrementTx = new Transaction();
incrementTx.recentBlockhash = blockhash;
incrementTx.add(incrementIx).sign(payer);

// process the transaction
await client.processTransaction(incrementTx);

// fetch the account data
const pageVisitsInfo = await client.getAccount(pageVisitsPDA);
assert(pageVisitsInfo !== null, 'account should exist');

const data = borsh.deserialize(pageVisitsSchema, pageVisitsInfo?.data) as PageVisits;

assert(data.page_visits === 2, 'page visits should be 2');
});

it('should read all the visits of the page', async () => {
const [pageVisitsPDA] = await derivePageVisitsPDA(testUser.publicKey);

// fetch the account data
const pageVisitsInfo = await client.getAccount(pageVisitsPDA);
assert(pageVisitsInfo !== null, 'account should exist');

const data = borsh.deserialize(pageVisitsSchema, pageVisitsInfo?.data) as PageVisits;

assert(data.page_visits === 2, 'page visits should be 2');
});
});

0 comments on commit c22d54e

Please sign in to comment.