Skip to content
This repository was archived by the owner on Sep 7, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions programs/wordcel/src/instructions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::*;
use invite::program::Invite as InvitationProgram;
use invite::Invite;

#[derive(Accounts)]
#[instruction(random_hash: [u8;32])]
Expand All @@ -16,20 +14,9 @@ pub struct Initialize<'info> {
space = Profile::LEN
)]
pub profile: Account<'info, Profile>,
#[account(
owner = invitation_program.key(),
seeds = [
Invite::PREFIX.as_bytes().as_ref(),
user.key().as_ref()
],
seeds::program = invitation_program.key(),
bump = invitation.bump
)]
pub invitation: Account<'info, Invite>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
pub invitation_program: Program<'info, InvitationProgram>,
}

#[derive(Accounts)]
Expand Down
284 changes: 153 additions & 131 deletions tests/invite.spec.ts
Original file line number Diff line number Diff line change
@@ -1,137 +1,159 @@
import * as anchor from '@project-serum/anchor';
import {Program, AnchorError} from '@project-serum/anchor';
import {Invite} from '../target/types/invite';
import {expect} from 'chai';
import {PublicKey} from '@solana/web3.js';
import {getInviteAccount, sendInvite} from "./utils/invite";
import {airdrop} from './utils';

const {SystemProgram} = anchor.web3;
import * as anchor from "@project-serum/anchor";
import { Program, AnchorError } from "@project-serum/anchor";
import { Invite } from "../target/types/invite";
import { expect } from "chai";
import { PublicKey } from "@solana/web3.js";
import { getInviteAccount, sendInvite } from "./utils/invite";
import { airdrop } from "./utils";

const { SystemProgram } = anchor.web3;
const provider = anchor.getProvider();

const program = anchor.workspace.Invite as Program<Invite>;
const user = provider.wallet.publicKey;


describe('Invitation', async () => {
// Prepare test user.
const testUser = anchor.web3.Keypair.generate();
let oneInviteAccount: PublicKey;

before(async () => {
await airdrop(testUser.publicKey);
oneInviteAccount = await getInviteAccount(testUser.publicKey);
});


it("should initialize", async () => {

await program.methods.initialize()
.accounts({
inviteAccount: oneInviteAccount,
authority: testUser.publicKey,
payer: user,
systemProgram: SystemProgram.programId
})
.rpc();
const data = await program.account.invite.fetch(oneInviteAccount);
expect(data.authority.toString()).to.equal(testUser.publicKey.toString());
});

it("should send invite to others", async () => {
const randomUser = anchor.web3.Keypair.generate();
const [inviter, invited] = await sendInvite(testUser, randomUser.publicKey, user)
const data = await program.account.invite.fetch(inviter);
expect(data.invitesLeft).to.equal(1);
expect(data.invitesSent).to.equal(1);
const toInviteData = await program.account.invite.fetch(invited);
expect(toInviteData.invitedBy.toString()).to.equal(testUser.publicKey.toString());
expect(toInviteData.authority.toString()).to.equal(randomUser.publicKey.toString());
});

it("should not be able to send more than 2 invites", async () => {
// Set up new user
const newUser = anchor.web3.Keypair.generate();
await airdrop(newUser.publicKey);
const inviteAccount = await getInviteAccount(newUser.publicKey);
await program.methods.initialize()
.accounts({
inviteAccount: inviteAccount,
authority: newUser.publicKey,
payer: user,
systemProgram: SystemProgram.programId
})
.rpc();

//First Invite
const randomUser = anchor.web3.Keypair.generate();
await sendInvite(newUser, randomUser.publicKey, user);

//Second Invite
const randomUser1 = anchor.web3.Keypair.generate();
await sendInvite(newUser, randomUser1.publicKey, user);

// Third Invite
const randomUser2 = anchor.web3.Keypair.generate();
try {
await sendInvite(newUser, randomUser2.publicKey, user);
} catch (error) {
const anchorError = AnchorError.parse(error.logs);
expect(anchorError.error.errorCode.code).to.equal('NoInvitesLeft');
}
});


it("should not allow random user to initialize", async () => {
const randomUser = anchor.web3.Keypair.generate();
const seed = [Buffer.from("invite"), randomUser.publicKey.toBuffer()];
const [account, _] = await anchor.web3.PublicKey.findProgramAddress(seed, program.programId);
const tx = await program.methods.initialize()
.accounts({
inviteAccount: account,
authority: randomUser.publicKey,
payer: testUser.publicKey,
systemProgram: SystemProgram.programId
})
.transaction();
tx.feePayer = user;
tx.recentBlockhash = (await provider.connection.getRecentBlockhash()).blockhash;
tx.sign(testUser);
try {
await provider.sendAndConfirm(tx)
} catch (error) {
const anchorError = AnchorError.parse(error.logs);
expect(anchorError.error.errorCode.code).to.equal('UnAuthorizedInitialization');
}
});

it("should allow admin to initialize as many accounts as required", async () => {
for (let index = 0; index < 5; index++) {
const randomUser = anchor.web3.Keypair.generate();
const seed = [Buffer.from("invite"), randomUser.publicKey.toBuffer()];
const [account, _] = await anchor.web3.PublicKey.findProgramAddress(seed, program.programId);
await program.methods.initialize()
.accounts({
inviteAccount: account,
authority: randomUser.publicKey,
payer: user,
systemProgram: SystemProgram.programId
})
.rpc();
const data = await program.account.invite.fetch(account);
expect(data.authority.toString()).to.equal(randomUser.publicKey.toString());
}
});

it("should not allow uninitialized invite account to send an invite", async () => {
const randomUser = anchor.web3.Keypair.generate();
const randomUser1 = anchor.web3.Keypair.generate();
await airdrop(randomUser1.publicKey);
try {
await sendInvite(randomUser, randomUser1.publicKey, user)
} catch (error) {
const anchorError = AnchorError.parse(error.logs);
expect(anchorError.error.errorCode.code).to.equal('AccountNotInitialized');
}
});
describe("Invitation", async () => {
// Prepare test user.
const testUser = anchor.web3.Keypair.generate();
let oneInviteAccount: PublicKey;

before(async () => {
await airdrop(testUser.publicKey);
oneInviteAccount = await getInviteAccount(testUser.publicKey);
});

it("should initialize", async () => {
await program.methods
.initialize()
.accounts({
inviteAccount: oneInviteAccount,
authority: testUser.publicKey,
payer: user,
systemProgram: SystemProgram.programId,
})
.rpc();
const data = await program.account.invite.fetch(oneInviteAccount);
expect(data.authority.toString()).to.equal(testUser.publicKey.toString());
});

it("should send invite to others", async () => {
const randomUser = anchor.web3.Keypair.generate();
const [inviter, invited] = await sendInvite(
testUser,
randomUser.publicKey,
user
);
const data = await program.account.invite.fetch(inviter);
expect(data.invitesLeft).to.equal(1);
expect(data.invitesSent).to.equal(1);
const toInviteData = await program.account.invite.fetch(invited);
expect(toInviteData.invitedBy.toString()).to.equal(
testUser.publicKey.toString()
);
expect(toInviteData.authority.toString()).to.equal(
randomUser.publicKey.toString()
);
});

it("should not be able to send more than 2 invites", async () => {
// Set up new user
const newUser = anchor.web3.Keypair.generate();
await airdrop(newUser.publicKey);
const inviteAccount = await getInviteAccount(newUser.publicKey);
await program.methods
.initialize()
.accounts({
inviteAccount: inviteAccount,
authority: newUser.publicKey,
payer: user,
systemProgram: SystemProgram.programId,
})
.rpc();

//First Invite
const randomUser = anchor.web3.Keypair.generate();
await sendInvite(newUser, randomUser.publicKey, user);

//Second Invite
const randomUser1 = anchor.web3.Keypair.generate();
await sendInvite(newUser, randomUser1.publicKey, user);

// Third Invite
const randomUser2 = anchor.web3.Keypair.generate();
try {
await sendInvite(newUser, randomUser2.publicKey, user);
} catch (error) {
const anchorError = AnchorError.parse(error.logs);
expect(anchorError.error.errorCode.code).to.equal("NoInvitesLeft");
}
});

it("should not allow random user to initialize", async () => {
const randomUser = anchor.web3.Keypair.generate();
const seed = [Buffer.from("invite"), randomUser.publicKey.toBuffer()];
const [account, _] = await anchor.web3.PublicKey.findProgramAddress(
seed,
program.programId
);
const tx = await program.methods
.initialize()
.accounts({
inviteAccount: account,
authority: randomUser.publicKey,
payer: testUser.publicKey,
systemProgram: SystemProgram.programId,
})
.transaction();
tx.feePayer = user;
tx.recentBlockhash = (
await provider.connection.getRecentBlockhash()
).blockhash;
tx.sign(testUser);
try {
await provider.sendAndConfirm(tx);
} catch (error) {
const anchorError = AnchorError.parse(error.logs);
expect(anchorError.error.errorCode.code).to.equal(
"UnAuthorizedInitialization"
);
}
});

it("should allow admin to initialize as many accounts as required", async () => {
for (let index = 0; index < 5; index++) {
const randomUser = anchor.web3.Keypair.generate();
const seed = [Buffer.from("invite"), randomUser.publicKey.toBuffer()];
const [account, _] = await anchor.web3.PublicKey.findProgramAddress(
seed,
program.programId
);
await program.methods
.initialize()
.accounts({
inviteAccount: account,
authority: randomUser.publicKey,
payer: user,
systemProgram: SystemProgram.programId,
})
.rpc();
const data = await program.account.invite.fetch(account);
expect(data.authority.toString()).to.equal(
randomUser.publicKey.toString()
);
}
});

it("should not allow uninitialized invite account to send an invite", async () => {
const randomUser = anchor.web3.Keypair.generate();
const randomUser1 = anchor.web3.Keypair.generate();
await airdrop(randomUser1.publicKey);
try {
await sendInvite(randomUser, randomUser1.publicKey, user);
} catch (error) {
const anchorError = AnchorError.parse(error.logs);
expect(anchorError.error.errorCode.code).to.equal(
"AccountNotInitialized"
);
}
});
});
19 changes: 0 additions & 19 deletions tests/wordcel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Wordcel } from "../target/types/wordcel";
import { expect } from "chai";
import { PublicKey } from "@solana/web3.js";
import randombytes from "randombytes";
import { getInviteAccount, invitationProgram } from "./utils/invite";
import { airdrop } from "./utils";
const { SystemProgram } = anchor.web3;
const provider = anchor.getProvider();
Expand All @@ -20,29 +19,14 @@ describe("wordcel", async () => {
program.programId
);
let onePostAccount: PublicKey;
let inviteAccount: PublicKey;

describe("Profile", async () => {
it("should initialize", async () => {
// Initialize Invitation Account
inviteAccount = await getInviteAccount(user);
await invitationProgram.methods
.initialize()
.accounts({
inviteAccount: inviteAccount,
authority: user,
payer: user,
systemProgram: SystemProgram.programId,
})
.rpc();

await program.methods
.initialize(randomHash)
.accounts({
profile: profileAccount,
user: user,
invitation: inviteAccount,
invitationProgram: invitationProgram.programId,
systemProgram: SystemProgram.programId,
})
.rpc();
Expand Down Expand Up @@ -111,14 +95,11 @@ describe("wordcel", async () => {
profileSeed,
program.programId
);
// Initialize Invitation Account
await program.methods
.initialize(randomHash)
.accounts({
profile: newProfileAccount,
user: user,
invitation: inviteAccount,
invitationProgram: invitationProgram.programId,
systemProgram: SystemProgram.programId,
})
.rpc();
Expand Down