Skip to content

Commit

Permalink
Add collection pass and fail test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
danenbm committed Jan 12, 2024
1 parent 5faac3b commit 7a45a14
Showing 1 changed file with 225 additions and 5 deletions.
230 changes: 225 additions & 5 deletions clients/js/test/updateMetadata.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import {
createNft,
findMetadataPda,
} from '@metaplex-foundation/mpl-token-metadata';
import {
defaultPublicKey,
generateSigner,
none,
some,
publicKey,
PublicKey,
percentAmount,
} from '@metaplex-foundation/umi';
import { generateSignerWithSol } from '@metaplex-foundation/umi-bundle-tests';
import test from 'ava';
import {
MetadataArgsArgs,
Expand All @@ -20,14 +26,15 @@ import {
getMerkleProof,
hashMetadataCreators,
hashMetadataData,
mintToCollectionV1,
} from '../src';
import { mint, createTree, createUmi } from './_setup';
import {
DasApiAsset,
GetAssetProofRpcResponse,
} from '@metaplex-foundation/digital-asset-standard-api';

test('it update the metadata of a minted compressed NFT', async (t) => {
test('it can update the metadata of a minted compressed NFT', async (t) => {
// Given an empty Bubblegum tree.
const umi = await createUmi();
const merkleTree = await createTree(umi);
Expand Down Expand Up @@ -70,7 +77,6 @@ test('it update the metadata of a minted compressed NFT', async (t) => {
name: some('New name'),
uri: some('https://updated-example.com/my-nft.json'),
};

await updateMetadata(umi, {
leafOwner,
merkleTree,
Expand Down Expand Up @@ -115,8 +121,10 @@ test('it can update metadata using the getAssetWithProof helper', async (t) => {
await mint(umi, { merkleTree, leafIndex: 7 }),
];

// And a 9th minted NFT that we will use for the test.
// And a 9th minted NFT owned by leafOwner.
const leafOwner = generateSigner(umi).publicKey;
const { metadata, leaf, leafIndex } = await mint(umi, {
leafOwner,
merkleTree,
leafIndex: 8,
});
Expand All @@ -125,7 +133,7 @@ test('it can update metadata using the getAssetWithProof helper', async (t) => {
const merkleTreeAccount = await fetchMerkleTree(umi, merkleTree);
const [assetId] = findLeafAssetIdPda(umi, { merkleTree, leafIndex });
const rpcAsset = {
ownership: { owner: umi.identity.publicKey },
ownership: { owner: leafOwner },
compression: {
leaf_id: leafIndex,
data_hash: publicKey(hashMetadataData(metadata)),
Expand Down Expand Up @@ -158,9 +166,9 @@ test('it can update metadata using the getAssetWithProof helper', async (t) => {
name: some('New name'),
uri: some('https://updated-example.com/my-nft.json'),
};

await updateMetadata(umi, {
...assetWithProof,
leafOwner,
currentMetadata: metadata,
updateArgs,
}).sendAndConfirm(umi);
Expand All @@ -169,3 +177,215 @@ test('it can update metadata using the getAssetWithProof helper', async (t) => {
t.is(assetWithProof.rpcAsset, rpcAsset);
t.is(assetWithProof.rpcAssetProof, rpcAssetProof);
});

test('it cannot update metadata using collection update authority when collection not verified', async (t) => {
// Given an empty Bubblegum tree.
const umi = await createUmi();
const merkleTree = await createTree(umi);
const leafOwner = generateSigner(umi).publicKey;
let merkleTreeAccount = await fetchMerkleTree(umi, merkleTree);

// And a Collection NFT.
const collectionMint = generateSigner(umi);
const collectionAuthority = generateSigner(umi);
await createNft(umi, {
mint: collectionMint,
authority: collectionAuthority,
name: 'My Collection',
uri: 'https://example.com/my-collection.json',
sellerFeeBasisPoints: percentAmount(5.5), // 5.5%
isCollection: true,
}).sendAndConfirm(umi);

// When we mint a new NFT from the tree with an unverified collection.
const { metadata, leafIndex } = await mint(umi, {
leafOwner,
merkleTree,
metadata: {
collection: some({ key: collectionMint.publicKey, verified: false }),
},
});

// Then we attempt to update metadata using the collection update authority.
const updateArgs: UpdateArgsArgs = {
name: some('New name'),
uri: some('https://updated-example.com/my-nft.json'),
};
let promise = updateMetadata(umi, {
leafOwner,
merkleTree,
root: getCurrentRoot(merkleTreeAccount.tree),
nonce: leafIndex,
index: leafIndex,
currentMetadata: metadata,
proof: [],
updateArgs,
authority: collectionAuthority,
collectionMint: collectionMint.publicKey,
collectionMetadata: findMetadataPda(umi, {
mint: collectionMint.publicKey,
}),
}).sendAndConfirm(umi);

// Then we expect a program error.
await t.throwsAsync(promise, { name: 'TreeAuthorityIncorrect' });

// And the leaf was not updated in the merkle tree.
const notUpdatedLeaf = hashLeaf(umi, {
merkleTree,
owner: leafOwner,
leafIndex,
metadata,
});
merkleTreeAccount = await fetchMerkleTree(umi, merkleTree);
t.is(merkleTreeAccount.tree.rightMostPath.leaf, publicKey(notUpdatedLeaf));
});

test('it can update metadata using collection update authority when collection is verified', async (t) => {
// Given an empty Bubblegum tree.
const umi = await createUmi();
const merkleTree = await createTree(umi);
const leafOwner = generateSigner(umi).publicKey;
let merkleTreeAccount = await fetchMerkleTree(umi, merkleTree);

// And a Collection NFT.
const collectionMint = generateSigner(umi);
const collectionAuthority = generateSigner(umi);
await createNft(umi, {
mint: collectionMint,
authority: collectionAuthority,
name: 'My Collection',
uri: 'https://example.com/my-collection.json',
sellerFeeBasisPoints: percentAmount(5.5), // 5.5%
isCollection: true,
}).sendAndConfirm(umi);

// When we mint a new NFT from the tree using the following metadata, with collection verified.
const metadata: MetadataArgsArgs = {
name: 'My NFT',
uri: 'https://example.com/my-nft.json',
sellerFeeBasisPoints: 550, // 5.5%
collection: {
key: collectionMint.publicKey,
verified: true,
},
creators: [],
};
await mintToCollectionV1(umi, {
leafOwner,
merkleTree,
metadata,
collectionMint: collectionMint.publicKey,
collectionAuthority: collectionAuthority,
}).sendAndConfirm(umi);

// And when metadata is updated.
const updateArgs: UpdateArgsArgs = {
name: some('New name'),
uri: some('https://updated-example.com/my-nft.json'),
};
await updateMetadata(umi, {
leafOwner,
merkleTree,
root: getCurrentRoot(merkleTreeAccount.tree),
nonce: 0,
index: 0,
currentMetadata: metadata,
proof: [],
updateArgs,
authority: collectionAuthority,
collectionMint: collectionMint.publicKey,
collectionMetadata: findMetadataPda(umi, {
mint: collectionMint.publicKey,
}),
}).sendAndConfirm(umi);

// Then the leaf was updated in the merkle tree.
const updatedLeaf = hashLeaf(umi, {
merkleTree,
owner: leafOwner,
leafIndex: 0,
metadata: {
...metadata,
name: 'New name',
uri: 'https://updated-example.com/my-nft.json',
},
});
merkleTreeAccount = await fetchMerkleTree(umi, merkleTree);
t.is(merkleTreeAccount.tree.rightMostPath.leaf, publicKey(updatedLeaf));
});

test('it cannot update metadata using tree owner when collection is verified', async (t) => {
// Given an empty Bubblegum tree.
const umi = await createUmi();
const treeCreator = await generateSignerWithSol(umi);
const merkleTree = await createTree(umi, { treeCreator });
const leafOwner = generateSigner(umi).publicKey;
let merkleTreeAccount = await fetchMerkleTree(umi, merkleTree);

// And a Collection NFT.
const collectionMint = generateSigner(umi);
const collectionAuthority = generateSigner(umi);
await createNft(umi, {
mint: collectionMint,
authority: collectionAuthority,
name: 'My Collection',
uri: 'https://example.com/my-collection.json',
sellerFeeBasisPoints: percentAmount(5.5), // 5.5%
isCollection: true,
}).sendAndConfirm(umi);

// When we mint a new NFT from the tree using the following metadata, with collection verified.
const metadata: MetadataArgsArgs = {
name: 'My NFT',
uri: 'https://example.com/my-nft.json',
sellerFeeBasisPoints: 550, // 5.5%
collection: {
key: collectionMint.publicKey,
verified: true,
},
creators: [],
};
await mintToCollectionV1(umi, {
leafOwner,
merkleTree,
metadata,
collectionMint: collectionMint.publicKey,
collectionAuthority: collectionAuthority,
treeCreatorOrDelegate: treeCreator,
}).sendAndConfirm(umi);

// Then we attempt to update metadata using the tree owner.
const updateArgs: UpdateArgsArgs = {
name: some('New name'),
uri: some('https://updated-example.com/my-nft.json'),
};
let promise = updateMetadata(umi, {
leafOwner,
merkleTree,
root: getCurrentRoot(merkleTreeAccount.tree),
nonce: 0,
index: 0,
currentMetadata: metadata,
proof: [],
updateArgs,
authority: treeCreator,
collectionMint: collectionMint.publicKey,
collectionMetadata: findMetadataPda(umi, {
mint: collectionMint.publicKey,
}),
}).sendAndConfirm(umi);

// Then we expect a program error.
await t.throwsAsync(promise, { name: 'InvalidCollectionAuthority' });

// And the leaf was not updated in the merkle tree.
const notUpdatedLeaf = hashLeaf(umi, {
merkleTree,
owner: leafOwner,
leafIndex: 0,
metadata,
});
merkleTreeAccount = await fetchMerkleTree(umi, merkleTree);
t.is(merkleTreeAccount.tree.rightMostPath.leaf, publicKey(notUpdatedLeaf));
});

0 comments on commit 7a45a14

Please sign in to comment.