Skip to content

Commit

Permalink
Add E2E tests for Alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
kingster-will committed Nov 22, 2023
1 parent 0edd7f0 commit 5f9e48b
Showing 1 changed file with 337 additions and 0 deletions.
337 changes: 337 additions & 0 deletions test/foundry/e2e/e2e.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { IIPOrg } from "contracts/interfaces/ip-org/IIPOrg.sol";
import { AccessControl } from "contracts/lib/AccessControl.sol";
import { RegistrationModule } from "contracts/modules/registration/RegistrationModule.sol";
import { StoryProtocol } from "contracts/StoryProtocol.sol";
import { RelationshipModule } from "contracts/modules/relationships/RelationshipModule.sol";
import { LicensingModule } from "contracts/modules/licensing/LicensingModule.sol";
import { TokenGatedHook } from "contracts/hooks/TokenGatedHook.sol";
import { HookRegistry } from "contracts/modules/base/HookRegistry.sol";
import { IHook } from "contracts/interfaces/hooks/base/IHook.sol";
import { TokenGated } from "contracts/lib/hooks/TokenGated.sol";
import { MockERC721 } from "test/foundry/mocks/MockERC721.sol";
import { TermsRepository } from "contracts/modules/licensing/TermsRepository.sol";
import { Licensing } from "contracts/lib/modules/Licensing.sol";
import { TermCategories, TermIds } from "contracts/lib/modules/ProtocolLicensingTerms.sol";
import { BaseTest } from "test/foundry/utils/BaseTest.sol";
import { LibRelationship } from "contracts/lib/modules/LibRelationship.sol";
import { ShortString, ShortStrings } from "@openzeppelin/contracts/utils/ShortStrings.sol";
import { TermsData } from "contracts/lib/modules/ProtocolLicensingTerms.sol";
import { Registration } from "contracts/lib/modules/Registration.sol";

contract E2ETest is BaseTest {
using ShortStrings for string;

address public tokenGatedHook;
MockERC721 public mockNFT;

// create 3 roles: protocol admin, ip org owner, ip asset owner
address public ipOrgOwner1 = address(1234);
address public ipOrgOwner2 = address(4567);
address public ipAssetOwner1 = address(6789);
address public ipAssetOwner2 = address(9876);
address public ipAssetOwner3 = address(9876);

address public ipOrg1;
address public ipOrg2;

function setUp() public virtual override {
super.setUp();
_grantRole(vm, AccessControl.RELATIONSHIP_MANAGER_ROLE, admin);
_grantRole(vm, AccessControl.TERMS_SETTER_ROLE, admin);
_grantRole(
vm,
AccessControl.HOOK_CALLER_ROLE,
address(registrationModule)
);
_grantRole(
vm,
AccessControl.HOOK_CALLER_ROLE,
address(relationshipModule)
);
_grantRole(
vm,
AccessControl.HOOK_CALLER_ROLE,
address(licensingModule)
);

/// TOKEN_GATED_HOOK
tokenGatedHook = address(new TokenGatedHook(address(accessControl)));
/// MOCK_ERC_721
mockNFT = new MockERC721();
mockNFT.mint(ipAssetOwner1, 1);
mockNFT.mint(ipAssetOwner2, 2);
}

function test_e2e() public {
// ip org owner create IP Org
string[] memory ipAssetTypes = new string[](2);
ipAssetTypes[0] = "CHARACTER";
ipAssetTypes[1] = "STORY";
ipOrg1 = spg.registerIpOrg(
ipOrgOwner1,
"IPOrgName1",
"IPO1",
ipAssetTypes
);
ipOrg2 = spg.registerIpOrg(
ipOrgOwner2,
"IPOrgName2",
"IPO2",
ipAssetTypes
);

// ip org owner configure modules
vm.prank(ipOrgOwner1);
spg.setMetadata(
ipOrg1,
"http://iporg1.baseuri.url",
"http://iporg1.contracturi.url"
);

vm.prank(ipOrgOwner2);
spg.setMetadata(
ipOrg2,
"http://iporg2.baseuri.url",
"http://iporg2.contracturi.url"
);

// ip org 1 owner register hooks to RegistrationModule
address[] memory hooks = new address[](1);
hooks[0] = tokenGatedHook;

TokenGated.Config memory tokenGatedConfig = TokenGated.Config({
tokenAddress: address(mockNFT)
});
bytes[] memory hooksConfig = new bytes[](1);
hooksConfig[0] = abi.encode(tokenGatedConfig);
vm.prank(ipOrgOwner1);
RegistrationModule(registrationModule).registerHooks(
HookRegistry.HookType.PreAction,
IIPOrg(ipOrg1),
hooks,
hooksConfig
);

// configure license terms
vm.startPrank(admin);
Licensing.CommercialStatus comStatus = Licensing.CommercialStatus.Both;
termsRepository.addCategory(TermCategories.SHARE_ALIKE);
Licensing.LicensingTerm memory term = _getTerm(
TermIds.NFT_SHARE_ALIKE,
comStatus
);
termsRepository.addTerm(
TermCategories.SHARE_ALIKE,
TermIds.NFT_SHARE_ALIKE,
term
);

termsRepository.addCategory(TermCategories.LICENSOR);
term = _getTerm(TermIds.LICENSOR_APPROVAL, comStatus);
termsRepository.addTerm(
TermCategories.LICENSOR,
TermIds.LICENSOR_APPROVAL,
term
);

termsRepository.addCategory(TermCategories.CATEGORIZATION);
term = _getTerm(TermIds.FORMAT_CATEGORY, comStatus);
termsRepository.addTerm(
TermCategories.CATEGORIZATION,
TermIds.FORMAT_CATEGORY,
term
);

termsRepository.addCategory(TermCategories.ACTIVATION);
term = _getTerm(TermIds.LICENSOR_IPORG_OR_PARENT, comStatus);
termsRepository.addTerm(
TermCategories.ACTIVATION,
TermIds.LICENSOR_IPORG_OR_PARENT,
term
);
vm.stopPrank();
// protocol admin add relationship type
LibRelationship.RelatedElements memory allowedElements = LibRelationship
.RelatedElements({
src: LibRelationship.Relatables.ADDRESS,
dst: LibRelationship.Relatables.ADDRESS
});
uint8[] memory allowedSrcs = new uint8[](0);
uint8[] memory allowedDsts = new uint8[](0);
LibRelationship.AddRelationshipTypeParams
memory relTypeParams = LibRelationship.AddRelationshipTypeParams({
relType: "APPEAR_IN",
ipOrg: ipOrg1,
allowedElements: allowedElements,
allowedSrcs: allowedSrcs,
allowedDsts: allowedDsts
});
vm.prank(ipOrgOwner1);
spg.addRelationshipType(relTypeParams);

// ip org owner configure IpOrg Licensing
// no commercial terms
Licensing.TermsConfig memory comTermsConfig = Licensing.TermsConfig({
termIds: new ShortString[](0),
termData: new bytes[](0)
});

// non commercial terms
// all licensors would be ipOrg
// all licenses begin as Pending, isLicenseActive == false,
// need approval from licensor to activate them
ShortString[] memory termIds_ = new ShortString[](3);
bytes[] memory termsData_ = new bytes[](3);
termIds_[0] = TermIds.NFT_SHARE_ALIKE.toShortString();
termsData_[0] = abi.encode(true);
termIds_[1] = TermIds.LICENSOR_APPROVAL.toShortString();
termsData_[1] = abi.encode(true);
termIds_[2] = TermIds.LICENSOR_IPORG_OR_PARENT.toShortString();
termsData_[2] = abi.encode(TermsData.LicensorConfig.IpOrg);

Licensing.TermsConfig memory nonComTermsConfig = Licensing.TermsConfig({
termIds: termIds_,
termData: termsData_
});

Licensing.FrameworkConfig memory frameworkConfig = Licensing
.FrameworkConfig({
comTermsConfig: comTermsConfig,
nonComTermsConfig: nonComTermsConfig
});

vm.prank(ipOrgOwner1);
spg.configureIpOrgLicensing(ipOrg1, frameworkConfig);

// ip asset owner register IP Asset
uint ipAssetId;
uint ipOrgAssetId;
Registration.RegisterIPAssetParams
memory registerIpAssetParamsCharacter = Registration
.RegisterIPAssetParams({
owner: ipAssetOwner1,
name: "Character IPA",
ipAssetType: 0,
hash: 0x558b44f88e5959cec9c7836078a53ff4d6432142a9d5caa6f3a6eb7c83930000,
mediaUrl: "https://arweave.net/chracter"
});
TokenGated.Params memory tokenGatedHookDataCharacter = TokenGated
.Params({ tokenOwner: ipAssetOwner1 });
bytes[] memory preHooksDataCharacter = new bytes[](1);
preHooksDataCharacter[0] = abi.encode(tokenGatedHookDataCharacter);
vm.prank(ipAssetOwner1);
(ipAssetId, ipOrgAssetId) = spg.registerIPAsset(
ipOrg1,
registerIpAssetParamsCharacter,
preHooksDataCharacter,
new bytes[](0)
);
assertEq(ipAssetId, 1);
assertEq(ipOrgAssetId, 1);

Registration.RegisterIPAssetParams
memory registerIpAssetParamsStory = Registration
.RegisterIPAssetParams({
owner: ipAssetOwner2,
name: "Story IPA",
ipAssetType: 1,
hash: 0x558b44f88e5959cec9c7836078a53ff4d6432142a9d5caa6f3a6eb7c83931111,
mediaUrl: "https://arweave.net/story"
});
TokenGated.Params memory tokenGatedHookDataStory = TokenGated.Params({
tokenOwner: ipAssetOwner2
});
bytes[] memory preHooksDataStory = new bytes[](1);
preHooksDataStory[0] = abi.encode(tokenGatedHookDataStory);
vm.prank(ipAssetOwner2);
(ipAssetId, ipOrgAssetId) = spg.registerIPAsset(
ipOrg1,
registerIpAssetParamsStory,
preHooksDataStory,
new bytes[](0)
);
assertEq(ipAssetId, 2);
assertEq(ipOrgAssetId, 2);

Registration.RegisterIPAssetParams
memory registerIpAssetParamsOrg2 = Registration
.RegisterIPAssetParams({
owner: ipAssetOwner3,
name: "Story IPA Org2",
ipAssetType: 1,
hash: 0x558b44f88e5959cec9c7836078a53ff4d6432142a9d5caa6f3a6eb7c83933333,
mediaUrl: "https://arweave.net/story2"
});
vm.prank(ipAssetOwner3);
(ipAssetId, ipOrgAssetId) = spg.registerIPAsset(
ipOrg2,
registerIpAssetParamsOrg2,
new bytes[](0),
new bytes[](0)
);
assertEq(ipAssetId, 3);
assertEq(ipOrgAssetId, 1);

// ip asset owner transfer IP Asset
// ip asset owner create relationship
LibRelationship.CreateRelationshipParams memory params = LibRelationship
.CreateRelationshipParams({
relType: "APPEAR_IN",
srcAddress: ipOrg1,
srcId: 1,
srcType: 0,
dstAddress: ipOrg1,
dstId: 2,
dstType: 0
});
bytes[] memory preHooksDataRel = new bytes[](0);
bytes[] memory postHooksDataRel = new bytes[](0);
vm.prank(ipOrg1);
uint256 id = spg.createRelationship(
ipOrg1,
params,
preHooksDataRel,
postHooksDataRel
);
assertEq(id, 1);
LibRelationship.Relationship memory rel = relationshipModule
.getRelationship(1);
assertEq(rel.relType, "APPEAR_IN");
assertEq(rel.srcAddress, ipOrg1);
assertEq(rel.dstAddress, ipOrg1);
assertEq(rel.srcId, 1);
assertEq(rel.dstId, 2);

vm.prank(ipOrgOwner1);
uint256 lId = spg.createIpaBoundLicense(
ipOrg1,
Licensing.LicenseCreation({
parentLicenseId: 0,
isCommercial: false
}),
1,
new bytes[](0),
new bytes[](0)
);
Licensing.License memory license = licenseRegistry.getLicense(lId);
assertFalse(license.isCommercial, "commercial");
assertEq(license.ipaId, 1);
}

function _getTerm(
string memory termId,
Licensing.CommercialStatus comStatus_
) internal pure returns (Licensing.LicensingTerm memory) {
return
Licensing.LicensingTerm({
comStatus: comStatus_,
url: string(abi.encodePacked("https://", termId, ".com")),
hash: "qwertyu",
algorithm: "sha256",
hook: IHook(address(0))
});
}
}

0 comments on commit 5f9e48b

Please sign in to comment.