Skip to content

Commit

Permalink
Merge pull request #26 from jacqueline-57b/add-spg-test
Browse files Browse the repository at this point in the history
Add tests for SPG
  • Loading branch information
AndyBoWu authored May 28, 2024
2 parents bd71ca7 + 76388ed commit b945d1e
Show file tree
Hide file tree
Showing 13 changed files with 1,142 additions and 182 deletions.
7 changes: 5 additions & 2 deletions config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,30 @@ export let royaltyApproveAddress: Hex;
export let mintingFeeTokenAddress: Hex;
export let arbitrationPolicyAddress: Hex;
export let disputeModuleAddress: Hex;
export let ipAssetRegistryAddress: Hex;
export let rpcProviderUrl: string;

if (String(TEST_ENV) === "sepolia") {
rpcProviderUrl = process.env.SEPOLIA_RPC_PROVIDER_URL as string;
licensingModuleAddress = process.env.SEPOLIA_LICENSING_MODULE_ADDRESS as Hex;
nftContractAddress = process.env.SEPOLIA_NFT_CONTRACT_ADDRESS as Hex;
nftContractAddress = process.env.SEPOLIA_MOCK_ERC721_ADDRESS as Hex;
royaltyPolicyAddress = process.env.SEPOLIA_ROYALTY_POLICY_ADDRESS as Hex;
royaltyPolicyLAPAddress = process.env.SEPOLIA_ROYALTY_POLICY_LAP_ADDRESS as Hex;
royaltyApproveAddress = process.env.SEPOLIA_ROYALTY_ERC20 as Hex;
mintingFeeTokenAddress = process.env.SEPOLIA_MINTING_FEE_TOKEN as Hex;
arbitrationPolicyAddress = process.env.SEPOLIA_ARBITRATION_POLICY_ADDRESS as Hex;
disputeModuleAddress = process.env.SEPOLIA_DISPUTE_MODULE_ADDRESS as Hex;
ipAssetRegistryAddress = process.env.SEPOLIA_IPASSET_REGISTRY_ADDRESS as Hex;
} else if (String(TEST_ENV) === "storyTestnet") {
rpcProviderUrl = process.env.STORY_RPC_PROVIDER_URL as string;
licensingModuleAddress = process.env.STORY_LICENSING_MODULE_ADDRESS as Hex;
nftContractAddress = process.env.STORY_NFT_CONTRACT_ADDRESS as Hex;
nftContractAddress = process.env.STORY_MOCK_ERC721_ADDRESS as Hex;
royaltyPolicyAddress = process.env.STORY_ROYALTY_POLICY_ADDRESS as Hex;
royaltyPolicyLAPAddress = process.env.STORY_ROYALTY_POLICY_LAP_ADDRESS as Hex;
royaltyApproveAddress = process.env.STORY_ROYALTY_ERC20 as Hex;
mintingFeeTokenAddress = process.env.STORY_MINTING_FEE_TOKEN as Hex;
arbitrationPolicyAddress = process.env.STORY_ARBITRATION_POLICY_ADDRESS as Hex;
ipAssetRegistryAddress = process.env.STORY_IPASSET_REGISTRY_ADDRESS as Hex;
disputeModuleAddress = process.env.STORY_DISPUTE_MODULE_ADDRESS as Hex;
} else {
throw new Error(`Unknown TEST_ENV value: ${TEST_ENV}`);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"url": "https://github.com/storyprotocol/sdk-e2e-tests.git"
},
"dependencies": {
"@story-protocol/core-sdk": "1.0.0-rc.11",
"@story-protocol/core-sdk": "1.0.0-rc.12",
"viem": "^2.8.12"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/dispute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ describe("SDK E2E Test", function () {
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.royaltyTokensCollected).to.be.a("bigint").and.be.equal(BigInt(commercialRevShare2));
expect(response.royaltyTokensCollected).to.be.a("bigint").and.be.equal(BigInt(commercialRevShare2 * 1000000));
});

step("Captue snapshot", async function () {
Expand Down Expand Up @@ -661,7 +661,7 @@ describe("SDK E2E Test", function () {
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.royaltyTokensCollected).to.be.a("bigint").and.be.equal(BigInt(commercialRevShare2));
expect(response.royaltyTokensCollected).to.be.a("bigint").and.be.equal(BigInt(commercialRevShare2 * 1000000));
});

step("Captue snapshot", async function () {
Expand Down
8 changes: 4 additions & 4 deletions test/e2e/royalty.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ describe('SDK E2E Test', function () {
expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.royaltyTokensCollected).to.be.a('bigint').and.to.be.ok;

expect(Number(response.royaltyTokensCollected)).to.be.equal(commercialRevShare1);
expect(Number(response.royaltyTokensCollected)).to.be.equal(commercialRevShare1 * 1000000);
});

step("Capture snapshotId", async function () {
Expand Down Expand Up @@ -369,7 +369,7 @@ describe('SDK E2E Test', function () {
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare2));
expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare2 * 1000000));
});

step("Capture snapshot", async function () {
Expand Down Expand Up @@ -518,7 +518,7 @@ describe('SDK E2E Test', function () {
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare1));
expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare1 * 1000000));
});

step("Collect royalty tokens", async function () {
Expand All @@ -527,7 +527,7 @@ describe('SDK E2E Test', function () {
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare1));
expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare1 * 1000000));
});

step("Capture snapshot", async function () {
Expand Down
168 changes: 168 additions & 0 deletions test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import { accountA, mintingFeeTokenAddress } from '../../config/config';
import { createNFTCollection, mintAndRegisterIpAssetWithPilTerms } from '../../utils/sdkUtils';
import { expect } from 'chai'
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
chai.use(chaiAsPromised);
import '../setup';
import { Hex, toHex } from 'viem';
import { PIL_TYPE } from '@story-protocol/core-sdk';

const metadataURI = "http://example.com/metadata/12345";
const metadataHash = toHex("test-metadata-hash", { size: 32 });
const nftMetadataHash = toHex("test-nft-metadata-hash", { size: 32 });
let nftCollectionAddress: Hex;

describe('SDK Test', function () {
before("Create NFT collection",async function () {
const response = await expect(
createNFTCollection("A", "sdk-e2e-test", "test", true)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.nftContract).to.be.a("string").and.not.empty;

nftCollectionAddress = response.nftContract;
});

describe('Test ipAsset.registerDerivativeIp Function', async function () {
it("Register an IP asset fail as undefined NFT contract address", async function () {
let nftContractAddress: any;
await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftContractAddress, PIL_TYPE.NON_COMMERCIAL_REMIX)
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Address "undefined" is invalid.`);
});

it("Register an IP asset fail as invalid NFT contract address", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("A", "0x0000", PIL_TYPE.NON_COMMERCIAL_REMIX)
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Address "0x0000" is invalid.`);
});

it("Register an IP asset fail as non-existent NFT contract address", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("A", "0x121022F354787754f39f55b9795178dA291348Ba", PIL_TYPE.NON_COMMERCIAL_REMIX)
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: The contract function "mintAndRegisterIpAndAttachPILTerms" reverted.`);
});

it("Register an IP asset fail as undefined pilType", async function () {
let pilType: any;
await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, pilType)
).to.be.rejectedWith("Failed to mint and register IP and attach PIL terms: PIL type is required.");
});

it("Register an IP asset fail as invalid metadataHash", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, "0x0000")
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Size of bytes "0x0000" (bytes2) does not match expected size (bytes32).`);
});

it("Register an IP asset fail as invalid nftMetadataHash", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, undefined, "0x0000")
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Size of bytes "0x0000" (bytes2) does not match expected size (bytes32).`);
});

it("Register an IP asset fail as invalid recipient", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, undefined, undefined, "0x000")
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Address "0x000" is invalid.`);
});

it("Register an IP asset fail as missing required parameters for commercial use PIL", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.COMMERCIAL_USE, true)
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: mintingFee currency are required for commercial use PIL.`);
});

it("Register an IP asset fail as missing required parameters for commercial remix PIL", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.COMMERCIAL_REMIX, true)
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: mintingFee, currency and commercialRevShare are required for commercial remix PIL.`);
});

it("Non-owner register an IP asset fail", async function () {
await expect(
mintAndRegisterIpAssetWithPilTerms("B", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, true)
).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: The contract function "mintAndRegisterIpAndAttachPILTerms" reverted.`, `Error: SPG__CallerNotMinterRole()`);
});

it("Register an IP asset with waitForTransaction: false", async function () {
const response = await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, false)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.not.be.exist;
expect(response.tokenId).to.not.be.exist;
expect(response.licenseTermsId).to.not.be.exist;
});

it("Register an IP asset with non-commercial remix license terms", async function () {
const response = await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, true)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.be.a("string").and.not.empty;
expect(response.tokenId).to.be.a("bigint").and.to.be.ok;
expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok;
});

it("Register an IP asset with commercial use license terms", async function () {
const response = await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.COMMERCIAL_USE, true, undefined, undefined, undefined, undefined, "80", undefined, mintingFeeTokenAddress)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.be.a("string").and.not.empty;
expect(response.tokenId).to.be.a("bigint").and.to.be.ok;
expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok;
});

it("Register an IP asset with commercial remix license terms", async function () {
const response = await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.COMMERCIAL_REMIX, true, undefined, undefined, undefined, undefined, "60", 20, mintingFeeTokenAddress)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.be.a("string").and.not.empty;
expect(response.tokenId).to.be.a("bigint").and.to.be.ok;
expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok;
});

it("Register an IP asset with non-commercial remix license terms and all optional parameters", async function () {
const response = await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, metadataHash, nftMetadataHash, accountA.address)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.be.a("string").and.not.empty;
expect(response.tokenId).to.be.a("bigint").and.to.be.ok;
expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok;
});

it("Register an IP asset with commercial use license terms and all optional parameters", async function () {
const response = await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.COMMERCIAL_USE, true, metadataURI, metadataHash, nftMetadataHash, accountA.address, "100", undefined, mintingFeeTokenAddress)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.be.a("string").and.not.empty;
expect(response.tokenId).to.be.a("bigint").and.to.be.ok;
expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok;
});

it("Register an IP asset with commercial remix license terms and all optional parameters", async function () {
const response = await expect(
mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.COMMERCIAL_REMIX, true, metadataURI, metadataHash, nftMetadataHash, accountA.address, "100", 10, mintingFeeTokenAddress)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.be.a("string").and.not.empty;
expect(response.tokenId).to.be.a("bigint").and.to.be.ok;
expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok;
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { privateKeyA, privateKeyB, privateKeyC, nftContractAddress } from '../../config/config';
import { registerIpAsset } from '../../utils/sdkUtils';
import { checkMintResult, mintNFTWithRetry } from '../../utils/utils';
import { checkMintResult, isRegistered, mintNFTWithRetry } from '../../utils/utils';
import { expect } from 'chai'
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
Expand All @@ -15,24 +15,22 @@ let ipIdA: Address;

describe('SDK Test', function () {
describe('Test ipAsset.register Function', async function () {
before("Mint 2 NFTs to Wallet A",async function () {
before("Mint 3 NFTs to Wallet A", async function () {
tokenIdA = await mintNFTWithRetry(privateKeyA);
checkMintResult(tokenIdA);
expect(tokenIdA).not.empty;

tokenIdB = await mintNFTWithRetry(privateKeyB);
checkMintResult(tokenIdB);
expect(tokenIdB).not.empty;

tokenIdC = await mintNFTWithRetry(privateKeyC);
checkMintResult(tokenIdC);
expect(tokenIdC).not.empty;
});

// 0x1033cd88 - IPAssetRegistry__UnsupportedIERC721(address)
it("Register an IP asset fail as non-existent NFT contract address", async function () {
await expect(
registerIpAsset("A","0x7ee32b8B515dEE0Ba2F25f612A04a731eEc24F48", tokenIdA, true)
).to.be.rejectedWith("Failed to register IP: The contract function \"register\" reverted.", "Error: IPAssetRegistry__UnsupportedIERC721(address contractAddress)");
).to.be.rejectedWith(`Failed to register IP: The contract function "registerIp" reverted with the following signature:`, "0x1033cd88");
});

it("Register an IP asset fail as invalid NFT contract address", async function () {
Expand All @@ -47,10 +45,11 @@ describe('SDK Test', function () {
).to.be.rejectedWith("Cannot convert tokenid to a BigInt");
});

// 0x7e273289 - ERC721NonexistentToken(uint256)
it("Register an IP asset fail as empty tokenId", async function () {
const response = await expect(
registerIpAsset("A", nftContractAddress, " ", true)
).to.be.rejectedWith("Failed to register IP: The contract function \"register\" reverted with the following signature");
).to.be.rejectedWith(`Failed to register IP: The contract function "registerIp" reverted with the following signature:`, "0x7e273289");
});

it("Owner can register an IP asset", async function () {
Expand All @@ -62,6 +61,10 @@ describe('SDK Test', function () {
expect(response.ipId).to.be.a("string").and.not.empty;

ipIdA = response.ipId;

// call contract to check isRegistered
const checkIpIdRegistered = await isRegistered(ipIdA);
expect(checkIpIdRegistered).to.be.equal(true);
});

it("Register an IP asset that is already registered", async function () {
Expand All @@ -74,13 +77,11 @@ describe('SDK Test', function () {
expect(response.ipId).to.be.equal(ipIdA);
});

// 0xb3e96921 - AccessController__PermissionDenied(address,address,address,bytes4)
it("Non-owner can register an IP asset", async function () {
const response = await expect(
registerIpAsset("B", nftContractAddress, tokenIdC, true)
).to.not.be.rejected;

expect(response.txHash).to.be.a("string").and.not.empty;
expect(response.ipId).to.be.a("string").and.not.empty;
).to.be.rejectedWith(`Failed to register IP: The contract function "registerIp" reverted with the following signature:`, `0xb3e96921`)
});

it("Register a root IP asset with waitForTransaction: false", async function () {
Expand All @@ -93,4 +94,4 @@ describe('SDK Test', function () {
expect(response.ipId).not.to.be.exist;
});
});
});
});
Loading

0 comments on commit b945d1e

Please sign in to comment.