diff --git a/.gitignore b/.gitignore index 870608d..db011ca 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,5 @@ target **/*.rs.bk node_modules -test_ledger/ +test-ledger/ .goki/ diff --git a/programs/wordcel/src/instructions.rs b/programs/wordcel/src/instructions.rs index 63af5aa..c058b8e 100644 --- a/programs/wordcel/src/instructions.rs +++ b/programs/wordcel/src/instructions.rs @@ -25,8 +25,8 @@ pub struct CreateEditor<'info> { init, seeds = [ b"editor".as_ref(), - host_profile.authority.key().as_ref(), - editor_profile.authority.key().as_ref() + host_profile.key().as_ref(), + editor_profile.key().as_ref() ], bump, payer = authority, @@ -47,8 +47,8 @@ pub struct RemoveEditor<'info> { mut, seeds = [ b"editor".as_ref(), - host_profile.authority.key().as_ref(), - editor_profile.authority.key().as_ref() + host_profile.key().as_ref(), + editor_profile.key().as_ref() ], bump = editor.bump, close = authority, @@ -63,7 +63,7 @@ pub struct RemoveEditor<'info> { } #[derive(Accounts)] -#[instruction(metadata_uri: String)] +#[instruction(metadata_uri: String, random_hash: [u8;32])] pub struct CreatePostAsEditor<'info> { // Checks if the original profile was supplied and if the profile authority is the signer #[account( @@ -76,7 +76,61 @@ pub struct CreatePostAsEditor<'info> { )] pub editor_profile: Account<'info, Profile>, - // Checks if a post was supplied and it is part of the supplied profile. + #[account( + seeds = [ + b"profile".as_ref(), + &host_profile.random_hash + ], + bump = host_profile.bump + )] + pub host_profile: Account<'info, Profile>, + + #[account( + has_one = host_profile, + seeds = [ + b"editor".as_ref(), + host_profile.key().as_ref(), + editor_profile.key().as_ref() + ], + bump = editor.bump + )] + pub editor: Account<'info, Editor>, + + // Initializes a new post account and checks if the signer is the authority + #[account( + init, + constraint = editor_profile.to_account_info().key() == editor.host_profile || editor_profile.to_account_info().key() == editor.editor_profile, + seeds = [ + b"post".as_ref(), + &random_hash + ], + bump, + payer = authority, + space = Post::LEN + )] + pub post: Account<'info, Post>, + + #[account(mut)] + pub authority: Signer<'info>, + + pub system_program: Program<'info, System>, +} + +#[derive(Accounts)] +#[instruction(metadata_uri: String)] +pub struct UpdatePostAsEditor<'info> { + // Checks if the original profile was supplied and if the profile authority is the signer + #[account( + has_one = authority, + seeds = [ + b"profile".as_ref(), + &editor_profile.random_hash + ], + bump = editor_profile.bump + )] + pub editor_profile: Account<'info, Profile>, + + // Mutable Account of Post that has to be updated #[account( mut, constraint = post.profile == editor_profile.to_account_info().key() || post.profile == host_profile.to_account_info().key(), @@ -101,8 +155,8 @@ pub struct CreatePostAsEditor<'info> { has_one = host_profile, seeds = [ b"editor".as_ref(), - host_profile.authority.key().as_ref(), - editor_profile.authority.key().as_ref() + host_profile.key().as_ref(), + editor_profile.key().as_ref() ], bump = editor.bump )] @@ -114,6 +168,57 @@ pub struct CreatePostAsEditor<'info> { pub system_program: Program<'info, System>, } +#[derive(Accounts)] +pub struct DeletePostAsEditor<'info> { + // Checks if the original profile was supplied and if the profile authority is the signer + #[account( + has_one = authority, + seeds = [ + b"profile".as_ref(), + &editor_profile.random_hash + ], + bump = editor_profile.bump + )] + pub editor_profile: Account<'info, Profile>, + + #[account( + seeds = [ + b"profile".as_ref(), + &host_profile.random_hash + ], + bump = host_profile.bump + )] + pub host_profile: Account<'info, Profile>, + + #[account( + has_one = host_profile, + seeds = [ + b"editor".as_ref(), + host_profile.key().as_ref(), + editor_profile.key().as_ref() + ], + bump = editor.bump + )] + pub editor: Account<'info, Editor>, + + // Mutable Account of Post that has to be deleted + #[account( + mut, + seeds = [ + b"post".as_ref(), + &post.random_hash + ], + bump = post.bump, + close = authority + )] + pub post: Account<'info, Post>, + + #[account(mut)] + pub authority: Signer<'info>, + + pub system_program: Program<'info, System>, +} + #[derive(Accounts)] #[instruction(metadata_uri: String, random_hash: [u8;32])] pub struct CreatePost<'info> { diff --git a/programs/wordcel/src/lib.rs b/programs/wordcel/src/lib.rs index 3df149d..a5d5b64 100644 --- a/programs/wordcel/src/lib.rs +++ b/programs/wordcel/src/lib.rs @@ -11,7 +11,7 @@ use instructions::*; use state::*; #[cfg(not(any(feature = "mainnet", feature = "devnet")))] -declare_id!("v4enuof3drNvU2Y3b5m7K62hMq3QUP6qQSV2jjxAhkp"); +declare_id!("6bxpSrHAc9zoWHKLJX3sfudTarFaHZoKQbM2XsyjJpMF"); #[cfg(feature = "devnet")] declare_id!("D9JJgeRf2rKq5LNMHLBMb92g4ZpeMgCyvZkd7QKwSCzg"); @@ -37,7 +37,7 @@ pub mod wordcel { metadata_uri: String, random_hash: [u8; 32], ) -> Result<()> { - require_gt!(metadata_uri.len(), MAX_LEN_URI, PostError::URITooLarge); + require!(metadata_uri.len() < MAX_LEN_URI, PostError::URITooLarge); let post = &mut ctx.accounts.post; post.random_hash = random_hash; @@ -56,7 +56,7 @@ pub mod wordcel { } pub fn update_post(ctx: Context, metadata_uri: String) -> Result<()> { - require_gt!(metadata_uri.len(), MAX_LEN_URI, PostError::URITooLarge); + require!(metadata_uri.len() < MAX_LEN_URI, PostError::URITooLarge); let post = &mut ctx.accounts.post; post.metadata_uri = metadata_uri; @@ -68,7 +68,7 @@ pub mod wordcel { metadata_uri: String, random_hash: [u8; 32], ) -> Result<()> { - require_gt!(metadata_uri.len(), MAX_LEN_URI, PostError::URITooLarge); + require!(metadata_uri.len() < MAX_LEN_URI, PostError::URITooLarge); let post = &mut ctx.accounts.post; post.random_hash = random_hash; @@ -122,11 +122,27 @@ pub mod wordcel { Ok(()) } - pub fn update_post_as_editor(ctx: Context, metadata_uri: String) -> Result<()> { - require_gt!(metadata_uri.len(), MAX_LEN_URI, PostError::URITooLarge); + + pub fn create_post_as_editor(ctx: Context, metadata_uri: String, random_hash: [u8; 32]) -> Result<()> { + require!(metadata_uri.len() < MAX_LEN_URI, PostError::URITooLarge); let post = &mut ctx.accounts.post; + post.random_hash = random_hash; + post.bump = *ctx.bumps.get("post").unwrap(); + post.metadata_uri = metadata_uri; post.profile = *ctx.accounts.host_profile.to_account_info().key; Ok(()) } + + pub fn update_post_as_editor(ctx: Context, metadata_uri: String) -> Result<()> { + require!(metadata_uri.len() < MAX_LEN_URI, PostError::URITooLarge); + + let post = &mut ctx.accounts.post; + post.metadata_uri = metadata_uri; + Ok(()) + } + + pub fn delete_post_as_editor(_ctx: Context) -> Result<()> { + Ok(()) + } } diff --git a/tests/editor.spec.ts b/tests/editor.spec.ts new file mode 100644 index 0000000..54e6a6a --- /dev/null +++ b/tests/editor.spec.ts @@ -0,0 +1,420 @@ +import * as anchor from "@project-serum/anchor"; +import { Program } from "@project-serum/anchor"; +import { Wordcel } from "../target/types/wordcel"; +import { expect } from "chai"; +import { PublicKey } from "@solana/web3.js"; +import randombytes from "randombytes"; +import { airdrop, setupProfile } from "./utils"; +const { SystemProgram } = anchor.web3; +const provider = anchor.getProvider(); + +const program = anchor.workspace.Wordcel as Program; + +describe("Editor", async () => { + const host = anchor.web3.Keypair.generate(); + const host_anchor_wallet = new anchor.Wallet(host); + const editor = anchor.web3.Keypair.generate(); + const editor_anchor_wallet = new anchor.Wallet(editor); + + let hostProfileAccount: PublicKey; + let editorProfileAccount: PublicKey; + let editorAccount: PublicKey; + let postAccount: PublicKey; + + before(async () => { + await airdrop(host.publicKey); + await airdrop(editor.publicKey); + + // Set up host profile + const hostProfile = await setupProfile(host.publicKey, program); + hostProfileAccount = hostProfile.profileAccount; + const host_profile_tx = hostProfile.profileTx; + await host_anchor_wallet.signTransaction(host_profile_tx); + await provider.sendAndConfirm(host_profile_tx, [host]); + + // Set up editor profile + await airdrop(editor.publicKey); + const editorProfile = await setupProfile(editor.publicKey, program); + editorProfileAccount = editorProfile.profileAccount; + const editor_profile_tx = editorProfile.profileTx; + await editor_anchor_wallet.signTransaction(editor_profile_tx); + await provider.sendAndConfirm(editor_profile_tx, [editor]); + }); + + it("create editor", async () => { + // Set up Editor + const editorSeed = [ + Buffer.from("editor"), + hostProfileAccount.toBuffer(), + editorProfileAccount.toBuffer(), + ]; + [editorAccount] = await anchor.web3.PublicKey.findProgramAddress( + editorSeed, + program.programId + ); + try { + const editor_tx = await program.methods + .createEditor() + .accounts({ + editor: editorAccount, + hostProfile: hostProfileAccount, + editorProfile: editorProfileAccount, + authority: host.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + editor_tx.feePayer = host.publicKey; + editor_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await host_anchor_wallet.signTransaction(editor_tx); + await provider.sendAndConfirm(editor_tx, [host]); + } catch (error) { + console.log(error); + } + const data = await program.account.editor.fetch(editorAccount); + expect(data.hostProfile.toString()).to.equal(hostProfileAccount.toString()); + expect(data.editorProfile.toString()).to.equal( + editorProfileAccount.toString() + ); + }); + + it("should not allow unauthorized editor creation", async () => { + const editorUser = anchor.web3.Keypair.generate(); + const editorUser_anchor_wallet = new anchor.Wallet(editorUser); + await airdrop(editorUser.publicKey); + + // Set up editorUser profile + const editorUserProfile = await setupProfile(editorUser.publicKey, program); + const editorUserProfileAccount = editorUserProfile.profileAccount; + const editor_profile_tx = editorUserProfile.profileTx; + await editorUser_anchor_wallet.signTransaction(editor_profile_tx); + await provider.sendAndConfirm(editor_profile_tx, [editorUser]); + + const editorSeed = [ + Buffer.from("editor"), + hostProfileAccount.toBuffer(), + editorUserProfileAccount.toBuffer(), + ]; + const [editorUserAccount] = await anchor.web3.PublicKey.findProgramAddress( + editorSeed, + program.programId + ); + try { + const editor_tx = await program.methods + .createEditor() + .accounts({ + editor: editorUserAccount, + hostProfile: hostProfileAccount, + editorProfile: editorUserProfileAccount, + authority: editorUser.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + editor_tx.feePayer = editorUser.publicKey; + editor_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await editorUser_anchor_wallet.signTransaction(editor_tx); + await provider.sendAndConfirm(editor_tx, [editorUser]); + } catch (error) { + expect(error).to.be.an("error"); + expect(error.toString()).to.contain("custom program error: 0x7d1"); + } + }); + + it("should not allow unauthorized post creation as editor", async () => { + const editorUser = anchor.web3.Keypair.generate(); + const editorUser_anchor_wallet = new anchor.Wallet(editorUser); + await airdrop(editorUser.publicKey); + + // Set up editorUser profile + const editorUserProfile = await setupProfile(editorUser.publicKey, program); + const editorUserProfileAccount = editorUserProfile.profileAccount; + const editor_profile_tx = editorUserProfile.profileTx; + await editorUser_anchor_wallet.signTransaction(editor_profile_tx); + await provider.sendAndConfirm(editor_profile_tx, [editorUser]); + + const postRandomHash = randombytes(32); + const metadataUri = + "https://gist.githubusercontent.com/abishekk92/10593977/raw/589238c3d48e654347d6cbc1e29c1e10dadc7cea/monoid.md"; + const postSeed = [ + Buffer.from("post"), + postRandomHash, + ]; + const [postEditorAccount] = await anchor.web3.PublicKey.findProgramAddress( + postSeed, + program.programId + ); + try { + const editor_tx = await program.methods + .createPostAsEditor(metadataUri, postRandomHash) + .accounts({ + post: postEditorAccount, + hostProfile: hostProfileAccount, + editorProfile: editorUserProfileAccount, + editor: editorAccount, + authority: editorUser.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + editor_tx.feePayer = editorUser.publicKey; + editor_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await editorUser_anchor_wallet.signTransaction(editor_tx); + await provider.sendAndConfirm(editor_tx, [editorUser]); + } catch (error) { + expect(error).to.be.an("error"); + expect(error.toString()).to.contain("custom program error: 0x7d3"); + } + }); + + it("create post as editor", async () => { + const postRandomHash = randombytes(32); + const metadataUri = + "https://gist.githubusercontent.com/abishekk92/10593977/raw/589238c3d48e654347d6cbc1e29c1e10dadc7cea/monoid.md"; + const postSeed = [ + Buffer.from("post"), + postRandomHash, + ]; + [postAccount] = await anchor.web3.PublicKey.findProgramAddress( + postSeed, + program.programId + ); + try { + const editor_post_tx = await program.methods + .createPostAsEditor(metadataUri, postRandomHash) + .accounts({ + post: postAccount, + hostProfile: hostProfileAccount, + editorProfile: editorProfileAccount, + editor: editorAccount, + authority: editor.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + editor_post_tx.feePayer = editor.publicKey; + editor_post_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await editor_anchor_wallet.signTransaction(editor_post_tx); + await provider.sendAndConfirm(editor_post_tx, [editor]); + } catch (error) { + console.log(`Error creating post as editor`); + console.log(error); + } + const data = await program.account.post.fetch(postAccount); + expect(data.metadataUri).to.equal(metadataUri); + }); + + it("update post as editor", async () => { + const metadataUri = + "https://gist.githubusercontent.com/abishekk92/10593977/raw/monoid.md"; + try { + const editor_post_tx = await program.methods + .updatePostAsEditor(metadataUri) + .accounts({ + post: postAccount, + hostProfile: hostProfileAccount, + editorProfile: editorProfileAccount, + editor: editorAccount, + authority: editor.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + editor_post_tx.feePayer = editor.publicKey; + editor_post_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await editor_anchor_wallet.signTransaction(editor_post_tx); + await provider.sendAndConfirm(editor_post_tx, [editor]); + } catch (error) { + console.log(`Error updating post as editor`); + console.log(error); + } + const data = await program.account.post.fetch(postAccount); + expect(data.metadataUri).to.equal(metadataUri); + }); + + it("update post as host", async () => { + const metadataUri = + "https://gist.githubusercontent.com/shekdev/10593977/raw/589238c3d48e654347d6cbc1e29c1e10dadc7cea/monoid.md"; + try { + const host_post_tx = await program.methods + .updatePost(metadataUri) + .accounts({ + post: postAccount, + profile: hostProfileAccount, + authority: host.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + host_post_tx.feePayer = host.publicKey; + host_post_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await host_anchor_wallet.signTransaction(host_post_tx); + await provider.sendAndConfirm(host_post_tx, [host]); + } catch (error) { + console.log(`Error updating post as host`); + console.log(error); + } + const data = await program.account.post.fetch(postAccount); + expect(data.metadataUri).to.equal(metadataUri); + }); + + it("should not allow unauthorized update", async () => { + const randomUser = anchor.web3.Keypair.generate(); + const randomUser_anchor_wallet = new anchor.Wallet(randomUser); + await airdrop(randomUser.publicKey); + + // Set up randomUser profile + const randomUserPrfile = await setupProfile(randomUser.publicKey, program); + const randomUserProfileAccount = randomUserPrfile.profileAccount; + const randomUser_profile_tx = randomUserPrfile.profileTx; + await randomUser_anchor_wallet.signTransaction(randomUser_profile_tx); + await provider.sendAndConfirm(randomUser_profile_tx, [randomUser]); + + // Set up post + const postRandomHash = randombytes(32); + const metadataUri = + "https://gist.githubusercontent.com/abishekk92/10593977/raw/589238c3d48e654347d6cbc1e29c1e10dadc7cea/monoid.md"; + const postSeed = [ + Buffer.from("post"), + postRandomHash, + ]; + const [randomUserPostAccount] = await anchor.web3.PublicKey.findProgramAddress( + postSeed, + program.programId + ); + const tx = await program.methods + .createPostAsEditor(metadataUri, postRandomHash) + .accounts({ + post: randomUserPostAccount, + hostProfile: randomUserProfileAccount, + editorProfile: editorProfileAccount, + editor: editorAccount, + authority: randomUser.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + tx.feePayer = randomUser.publicKey; + tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await randomUser_anchor_wallet.signTransaction(tx); + try { + await provider.sendAndConfirm(tx, [randomUser]); + } catch (error) { + expect(error).to.be.an("error"); + expect(error.toString()).to.contain("custom program error: 0x7d1"); + } + }); + + it("should not allow unauthorized delete of post as editor", async () => { + const randomUser = anchor.web3.Keypair.generate(); + const randomUser_anchor_wallet = new anchor.Wallet(randomUser); + await airdrop(randomUser.publicKey); + + const randomUser_post_tx = await program.methods + .deletePostAsEditor() + .accounts({ + post: postAccount, + hostProfile: hostProfileAccount, + editorProfile: editorProfileAccount, + editor: editorAccount, + authority: randomUser.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + randomUser_post_tx.feePayer = randomUser.publicKey; + randomUser_post_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await randomUser_anchor_wallet.signTransaction(randomUser_post_tx); + try { + await provider.sendAndConfirm(randomUser_post_tx, [randomUser]); + } catch (error) { + expect(error).to.be.an("error"); + expect(error.toString()).to.contain("custom program error: 0x7d1"); + } + }); + + it("should delete post as editor", async () => { + try { + const editor_post_tx = await program.methods + .deletePostAsEditor() + .accounts({ + post: postAccount, + hostProfile: hostProfileAccount, + editorProfile: editorProfileAccount, + editor: editorAccount, + authority: editor.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + editor_post_tx.feePayer = editor.publicKey; + editor_post_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await editor_anchor_wallet.signTransaction(editor_post_tx); + await provider.sendAndConfirm(editor_post_tx, [editor]); + } catch (error) { + console.log(`Error deleting post as editor`); + console.log(error); + } + try { + await program.account.post.fetch(postAccount); + } catch (error) { + expect(error).to.be.an("error"); + expect(error.toString()).to.contain(`Account does not exist ${postAccount.toString()}`); + } + }); + + it("should not allow unauthorized remove of editor", async () => { + const randomUser = anchor.web3.Keypair.generate(); + const randomUser_anchor_wallet = new anchor.Wallet(randomUser); + await airdrop(randomUser.publicKey); + + const randomUser_tx = await program.methods + .removeEditor() + .accounts({ + editor: editorAccount, + hostProfile: hostProfileAccount, + editorProfile: editorProfileAccount, + authority: randomUser.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + randomUser_tx.feePayer = randomUser.publicKey; + randomUser_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await randomUser_anchor_wallet.signTransaction(randomUser_tx); + try { + await provider.sendAndConfirm(randomUser_tx, [randomUser]); + } catch (error) { + expect(error).to.be.an("error"); + expect(error.toString()).to.contain("custom program error: 0x7d1"); + } + }); + + it("remove editor", async () => { + try { + const editor_tx = await program.methods + .removeEditor() + .accounts({ + editor: editorAccount, + hostProfile: hostProfileAccount, + editorProfile: editorProfileAccount, + authority: host.publicKey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + editor_tx.feePayer = host.publicKey; + editor_tx.recentBlockhash = (await provider.connection.getLatestBlockhash()) + .blockhash; + await host_anchor_wallet.signTransaction(editor_tx); + await provider.sendAndConfirm(editor_tx, [host]); + } catch (error) { + console.log(error); + } + try { + const data = await program.account.editor.fetch(editorAccount); + } catch (error) { + expect(error).to.be.an("error"); + expect(error.toString()).to.contain(`Account does not exist ${editorAccount.toString()}`); + } + }); +}); \ No newline at end of file diff --git a/tests/utils/index.ts b/tests/utils/index.ts index 4e5c814..6e2e536 100644 --- a/tests/utils/index.ts +++ b/tests/utils/index.ts @@ -1,5 +1,8 @@ import * as anchor from '@project-serum/anchor'; -import {PublicKey, LAMPORTS_PER_SOL} from '@solana/web3.js'; +import { Program } from '@project-serum/anchor'; +import { PublicKey, LAMPORTS_PER_SOL, SystemProgram } from '@solana/web3.js'; +import randombytes from 'randombytes'; +import { Wordcel } from '../../target/types/wordcel'; const provider = anchor.getProvider(); @@ -8,3 +11,20 @@ export async function airdrop(key: PublicKey) { return provider.connection.confirmTransaction(airdropSig); } +export async function setupProfile(pubkey: PublicKey, program: Program) { + const randomHash = randombytes(32); + const profileSeed = [Buffer.from("profile"), randomHash]; + const [profileAccount] = await anchor.web3.PublicKey.findProgramAddress(profileSeed, program.programId); + const profileTx = await program.methods + .initialize(randomHash) + .accounts({ + profile: profileAccount, + user: pubkey, + systemProgram: SystemProgram.programId, + }) + .transaction(); + profileTx.feePayer = pubkey; + profileTx.recentBlockhash = (await provider.connection.getLatestBlockhash()).blockhash; + + return { profileAccount, profileTx }; +} \ No newline at end of file diff --git a/tests/wordcel.spec.ts b/tests/wordcel.spec.ts index 27a9929..9b540a0 100644 --- a/tests/wordcel.spec.ts +++ b/tests/wordcel.spec.ts @@ -12,8 +12,8 @@ const program = anchor.workspace.Wordcel as Program; const user = provider.wallet.publicKey; describe("wordcel", async () => { - const randomHash = randombytes(32); - const profileSeed = [Buffer.from("profile"), randomHash]; + const profileHash = randombytes(32); + const profileSeed = [Buffer.from("profile"), profileHash]; const [profileAccount, _] = await anchor.web3.PublicKey.findProgramAddress( profileSeed, program.programId @@ -23,30 +23,7 @@ describe("wordcel", async () => { describe("Profile", async () => { it("should initialize", async () => { await program.methods - .initialize(randomHash) - .accounts({ - profile: profileAccount, - user: user, - systemProgram: SystemProgram.programId, - }) - .rpc(); - const data = await program.account.profile.fetch(profileAccount); - expect(data.authority.toString()).to.equal(user.toString()); - }); - }); - - describe("Editor", async () => { - before(async () => { - //set up profile 1 - //set up profile 2 - //set up Editor - //set up Post - //post as editor - }); - - it("should initialize", async () => { - await program.methods - .initialize(randomHash) + .initialize(profileHash) .accounts({ profile: profileAccount, user: user,