diff --git a/hardhat.config.ts b/hardhat.config.ts index c13fbd4a..2bf71763 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -112,7 +112,7 @@ const config: HardhatUserConfig = { coinmarketcap: COINMARKETCAP_API_KEY, }, mocha: { - timeout: 60_000, + timeout: 120_000, reporter: "mochawesome", }, etherscan: { diff --git a/test/hardhat/e2e/grouping/group.ipa.test.ts b/test/hardhat/e2e/grouping/group.ipa.test.ts index 365305a2..5916115e 100644 --- a/test/hardhat/e2e/grouping/group.ipa.test.ts +++ b/test/hardhat/e2e/grouping/group.ipa.test.ts @@ -2,23 +2,148 @@ import "../setup" import { expect } from "chai" -import { EvenSplitGroupPool } from "../constants" +import { EvenSplitGroupPool, PILicenseTemplate, RoyaltyPolicyLRP } from "../constants" +import { mintNFTAndRegisterIPA, mintNFTAndRegisterIPAWithLicenseTerms } from "../utils/mintNFTAndRegisterIPA"; +import { LicensingConfig, registerPILTerms } from "../utils/licenseHelper"; -describe("Group IPA", function () { +describe("Register Group IPA", function () { it("Register Group IPA with whitelisted group pool", async function () { - const groupId = await expect( this.groupingModule.registerGroup(EvenSplitGroupPool) ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); console.log("groupId", groupId) expect(groupId).to.be.properHex(40); + + const isRegisteredGroup = await this.ipAssetRegistry.isRegisteredGroup(groupId); + expect(isRegisteredGroup).to.be.true; }); it("Register Group IPA with non-whitelisted group pool", async function () { - const nonWhitelistedGroupPool = "0xC384B56fD62d6679Cd62A2fE0dA3fe4560f33300" + const nonWhitelistedGroupPool = this.user1.address; await expect( this.groupingModule.registerGroup(nonWhitelistedGroupPool) - ).to.be.rejectedWith(Error) + ).to.be.revertedWithCustomError(this.errors, "GroupIPAssetRegistry__GroupRewardPoolNotRegistered"); + }); +}); + +describe("Add/Remove IP from Group IPA", function () { + let groupId: any; + let commRemixTermsId: any; + + before(async function () { + groupId = await expect( + this.groupingModule.registerGroup(EvenSplitGroupPool) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); + console.log("groupId", groupId); + + commRemixTermsId = await registerPILTerms(true, 0, 10 * 10 ** 6, RoyaltyPolicyLRP); + await expect( + this.licensingModule.attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + }); + + it("Add/Remove an IP to the group", async function () { + // Register IP + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await expect( + this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + + // Add IP to the group + await expect( + this.groupingModule.addIp(groupId, [ipId]) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + + let containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); + expect(containsIp).to.be.true; + + // Remove IP from the group + await expect( + this.groupingModule.removeIp(groupId, [ipId]) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + + containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); + expect(containsIp).to.be.false; + }); + + it("Add/Remove multiple IPs to the group", async function () { + // Register IPs + const {ipId: ipId1} = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await expect( + this.licensingModule.setLicensingConfig(ipId1, PILicenseTemplate, commRemixTermsId, LicensingConfig) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + const {ipId: ipId2} = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user1, this.user1); + await expect( + this.licensingModule.connect(this.user1).setLicensingConfig(ipId2, PILicenseTemplate, commRemixTermsId, LicensingConfig) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + + // Add multiple IPs to the group + await expect( + this.groupingModule.addIp(groupId, [ipId1, ipId2]) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + + let containsIp1 = await this.ipAssetRegistry.containsIp(groupId, ipId1); + expect(containsIp1).to.be.true; + let containsIp2 = await this.ipAssetRegistry.containsIp(groupId, ipId2); + expect(containsIp2).to.be.true; + + // Remove multiple IPs from the group + await expect( + this.groupingModule.removeIp(groupId, [ipId1, ipId2]) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + + containsIp1 = await this.ipAssetRegistry.containsIp(groupId, ipId1); + expect(containsIp1).to.be.false; + containsIp2 = await this.ipAssetRegistry.containsIp(groupId, ipId2); + expect(containsIp2).to.be.false; + }); + + it("Non-owner add IP to the group", async function () { + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await expect( + this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + await expect( + this.groupingModule.connect(this.user1).addIp(groupId, [ipId]) + ).to.be.revertedWithCustomError(this.errors, "AccessController__PermissionDenied");; + + const containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); + expect(containsIp).to.be.false; + }); + + it("Non-owner remove IP from the group", async function () { + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await expect( + this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + await expect( + this.groupingModule.addIp(groupId, [ipId]) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + let containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); + expect(containsIp).to.be.true; + + // Remove IP from the group + await expect( + this.groupingModule.connect(this.user1).removeIp(groupId, [ipId]) + ).to.be.revertedWithCustomError(this.errors, "AccessController__PermissionDenied"); + containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); + expect(containsIp).to.be.true; + }); + + it("Add IP with none/different license term to the group", async function () { + const { ipId } = await mintNFTAndRegisterIPA(); + // IP has no license term attached + await expect( + this.groupingModule.addIp(groupId, [ipId]) + ).to.be.revertedWithCustomError(this.errors, "LicenseRegistry__IpHasNoGroupLicenseTerms"); + + // IP has different license term attached + await expect( + this.licensingModule.attachLicenseTerms(ipId, PILicenseTemplate, this.commericialUseLicenseId) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + await expect( + this.groupingModule.addIp(groupId, [ipId]) + ).to.be.revertedWithCustomError(this.errors, "LicenseRegistry__IpHasNoGroupLicenseTerms"); }); }); diff --git a/test/hardhat/e2e/setup.ts b/test/hardhat/e2e/setup.ts index 4ce98511..216fe31c 100644 --- a/test/hardhat/e2e/setup.ts +++ b/test/hardhat/e2e/setup.ts @@ -14,6 +14,7 @@ before(async function () { this.groupingModule = await hre.ethers.getContractAt("GroupingModule", GroupingModule); this.licenseTemplate = await hre.ethers.getContractAt("PILicenseTemplate", PILicenseTemplate); this.accessController = await hre.ethers.getContractAt("AccessController", AccessController); + this.errors = await hre.ethers.getContractFactory("Errors"); console.log(`================= Load Users =================`); [this.owner, this.user1] = await hre.ethers.getSigners(); diff --git a/test/hardhat/e2e/utils/licenseHelper.ts b/test/hardhat/e2e/utils/licenseHelper.ts new file mode 100644 index 00000000..0f1d24bb --- /dev/null +++ b/test/hardhat/e2e/utils/licenseHelper.ts @@ -0,0 +1,39 @@ +// Purpose: Helper functions for licensing config and registering PIL terms functions + +import hre from "hardhat"; +import { EvenSplitGroupPool, MockERC20, PILicenseTemplate } from "../constants"; +import { terms } from "../licenseTermsTemplate"; + +export const LicensingConfig = ({ + isSet: true, + mintingFee: 20, + licensingHook: hre.ethers.ZeroAddress, + hookData: "0x", + commercialRevShare: 10 * 10 ** 6, + disabled: false, + expectMinimumGroupRewardShare: 0, + expectGroupRewardPool: EvenSplitGroupPool, +}); + +export async function registerPILTerms( + commercialUse: boolean = false, + mintingFee: number = 0, + commercialRevShare: number = 0, + royaltyPolicy: string = hre.ethers.ZeroAddress, + currencyToken: string = MockERC20): Promise { + + const licenseTemplate = await hre.ethers.getContractAt("PILicenseTemplate", PILicenseTemplate); + + const testTerms = terms; + testTerms.royaltyPolicy = royaltyPolicy; + testTerms.defaultMintingFee = mintingFee; + testTerms.commercialUse = commercialUse; + testTerms.commercialRevShare = commercialRevShare; + testTerms.currency = currencyToken; + + await licenseTemplate.registerLicenseTerms(testTerms).then((tx) => tx.wait()); + const licenseTermsId = await licenseTemplate.getLicenseTermsId(testTerms); + console.log("licenseTermsId", licenseTermsId); + + return licenseTermsId; +} diff --git a/test/hardhat/e2e/utils/mintNFTAndRegisterIPA.ts b/test/hardhat/e2e/utils/mintNFTAndRegisterIPA.ts index ca3dd99c..a58d949a 100644 --- a/test/hardhat/e2e/utils/mintNFTAndRegisterIPA.ts +++ b/test/hardhat/e2e/utils/mintNFTAndRegisterIPA.ts @@ -2,7 +2,7 @@ import "../setup"; import { mintNFT } from "./nftHelper"; -import { MockERC721, IPAssetRegistry } from "../constants"; +import { MockERC721, IPAssetRegistry, LicensingModule, PILicenseTemplate } from "../constants"; import { expect } from "chai"; import hre from "hardhat"; import { network } from "hardhat"; @@ -37,3 +37,13 @@ export async function mintNFTAndRegisterIPA(mintNFTSigner?: any, registerIPASign return { tokenId, ipId }; }; +export async function mintNFTAndRegisterIPAWithLicenseTerms(licenseTermsId: any, mintNFTSigner?: any, registerIPASigner?: any): Promise<{ tokenId: number; ipId: HexString }> { + const { tokenId, ipId } = await mintNFTAndRegisterIPA(mintNFTSigner, registerIPASigner); + + const licensingModule = await hre.ethers.getContractAt("LicensingModule", LicensingModule, registerIPASigner); + await expect( + licensingModule.attachLicenseTerms(ipId, PILicenseTemplate, licenseTermsId) + ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + + return { tokenId, ipId }; +};