From 8b9c0bf7c12d535c5fbf5d6dbdbac628391054b8 Mon Sep 17 00:00:00 2001 From: jacqueline-57b Date: Tue, 16 Jul 2024 06:51:03 +0000 Subject: [PATCH] deploy: 1a437ebef16b79bd67cf5950d98238f3d2810e59 --- .env.example | 20 + .gitignore | 27 + .nvmrc | 1 + README.md | 62 + config/abi.ts | 387 + config/config.ts | 109 + package.json | 50 + pnpm-lock.yaml | 1292 +++ policy_backup/commericalUsePolicy.test.ts | 192 + policy_backup/commicialPolicy.test.ts | 270 + policy_backup/nonCommicialPolicy.test.ts | 154 + policy_backup/socialRemixPolicy.test.ts | 71 + policy_backup/test-results-commicial.csv | 129 + policy_backup/test-results-noncommicial.csv | 65 + .../assets/MaterialIcons-Regular.woff | Bin 0 -> 57620 bytes .../assets/MaterialIcons-Regular.woff2 | Bin 0 -> 44300 bytes test-reports/assets/app.css | 14 + test-reports/assets/app.js | 2 + test-reports/assets/app.js.LICENSE.txt | 55 + test-reports/assets/roboto-light-webfont.woff | Bin 0 -> 25772 bytes .../assets/roboto-light-webfont.woff2 | Bin 0 -> 19508 bytes .../assets/roboto-medium-webfont.woff | Bin 0 -> 26292 bytes .../assets/roboto-medium-webfont.woff2 | Bin 0 -> 19944 bytes .../assets/roboto-regular-webfont.woff | Bin 0 -> 26280 bytes .../assets/roboto-regular-webfont.woff2 | Bin 0 -> 19868 bytes ...ass_07-16-2024_065057_sdk-test-report.html | 2 + ...ass_07-16-2024_065057_sdk-test-report.json | 9368 +++++++++++++++++ test/dispute/cancelDispute.test.ts | 113 + test/dispute/raiseDispute.test.ts | 148 + test/dispute/resolveDispute.test.ts | 119 + test/e2e/derivativeIP.comRemixPIL.test.ts | 577 + test/e2e/derivativeIP.comUsePIL.test.ts | 593 ++ test/e2e/derivativeIP.nonComPIL.test.ts | 521 + test/e2e/dispute.test.ts | 693 ++ test/e2e/licenseTerms.nonComPIL.test.ts | 197 + test/e2e/multiLIcenseTerms.test.ts | 277 + test/e2e/royalty.comRemixPIL.test.ts | 533 + test/e2e/royalty.comUsePIL.test.ts | 205 + test/e2e/setPermissions.test.ts | 137 + test/ipAccount/executeWithSig.test.ts | 77 + ...mintAndRegisterIpAssetWithPilTerms.test.ts | 158 + test/ipAsset/register.test.ts | 97 + test/ipAsset/registerDerivative.test.ts | 160 + test/ipAsset/registerDerivativeIp.test.ts | 220 + ...egisterDerivativeWithLicenseTokens.test.ts | 203 + .../registerIpAndAttachPilTerms.test.ts | 189 + test/license/attachLicenseTerms.test.ts | 233 + test/license/getLicenseTerms.test.ts | 118 + test/license/mintLicenseTokens.test.ts | 216 + test/license/registerPIL.test.ts | 184 + test/nftClient/createNFTCollection.test.ts | 115 + test/permission/permission.test.ts | 131 + test/royalty/claimRevenue.test.ts | 185 + test/royalty/claimableRevenue.test.ts | 182 + test/royalty/collectRoyaltyTokens.test.ts | 218 + test/royalty/payRoyaltyOnBehalf.test.ts | 220 + test/royalty/snapshot.test.ts | 140 + test/setup.ts | 86 + test/testUtils.ts | 213 + tsconfig.json | 11 + utils/sdkUtils.ts | 589 ++ utils/utils.ts | 461 + 62 files changed, 20789 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 README.md create mode 100644 config/abi.ts create mode 100644 config/config.ts create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 policy_backup/commericalUsePolicy.test.ts create mode 100644 policy_backup/commicialPolicy.test.ts create mode 100644 policy_backup/nonCommicialPolicy.test.ts create mode 100644 policy_backup/socialRemixPolicy.test.ts create mode 100644 policy_backup/test-results-commicial.csv create mode 100644 policy_backup/test-results-noncommicial.csv create mode 100644 test-reports/assets/MaterialIcons-Regular.woff create mode 100644 test-reports/assets/MaterialIcons-Regular.woff2 create mode 100644 test-reports/assets/app.css create mode 100644 test-reports/assets/app.js create mode 100644 test-reports/assets/app.js.LICENSE.txt create mode 100644 test-reports/assets/roboto-light-webfont.woff create mode 100644 test-reports/assets/roboto-light-webfont.woff2 create mode 100644 test-reports/assets/roboto-medium-webfont.woff create mode 100644 test-reports/assets/roboto-medium-webfont.woff2 create mode 100644 test-reports/assets/roboto-regular-webfont.woff create mode 100644 test-reports/assets/roboto-regular-webfont.woff2 create mode 100644 test-reports/pass_07-16-2024_065057_sdk-test-report.html create mode 100644 test-reports/pass_07-16-2024_065057_sdk-test-report.json create mode 100644 test/dispute/cancelDispute.test.ts create mode 100644 test/dispute/raiseDispute.test.ts create mode 100644 test/dispute/resolveDispute.test.ts create mode 100644 test/e2e/derivativeIP.comRemixPIL.test.ts create mode 100644 test/e2e/derivativeIP.comUsePIL.test.ts create mode 100644 test/e2e/derivativeIP.nonComPIL.test.ts create mode 100644 test/e2e/dispute.test.ts create mode 100644 test/e2e/licenseTerms.nonComPIL.test.ts create mode 100644 test/e2e/multiLIcenseTerms.test.ts create mode 100644 test/e2e/royalty.comRemixPIL.test.ts create mode 100644 test/e2e/royalty.comUsePIL.test.ts create mode 100644 test/e2e/setPermissions.test.ts create mode 100644 test/ipAccount/executeWithSig.test.ts create mode 100644 test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts create mode 100644 test/ipAsset/register.test.ts create mode 100644 test/ipAsset/registerDerivative.test.ts create mode 100644 test/ipAsset/registerDerivativeIp.test.ts create mode 100644 test/ipAsset/registerDerivativeWithLicenseTokens.test.ts create mode 100644 test/ipAsset/registerIpAndAttachPilTerms.test.ts create mode 100644 test/license/attachLicenseTerms.test.ts create mode 100644 test/license/getLicenseTerms.test.ts create mode 100644 test/license/mintLicenseTokens.test.ts create mode 100644 test/license/registerPIL.test.ts create mode 100644 test/nftClient/createNFTCollection.test.ts create mode 100644 test/permission/permission.test.ts create mode 100644 test/royalty/claimRevenue.test.ts create mode 100644 test/royalty/claimableRevenue.test.ts create mode 100644 test/royalty/collectRoyaltyTokens.test.ts create mode 100644 test/royalty/payRoyaltyOnBehalf.test.ts create mode 100644 test/royalty/snapshot.test.ts create mode 100644 test/setup.ts create mode 100644 test/testUtils.ts create mode 100644 tsconfig.json create mode 100644 utils/sdkUtils.ts create mode 100644 utils/utils.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..abbda89 --- /dev/null +++ b/.env.example @@ -0,0 +1,20 @@ +WALLET_PRIVATE_KEY_A=0x0000000000000000000000000000000000000000 +WALLET_PRIVATE_KEY_B=0x0000000000000000000000000000000000000000 +WALLET_PRIVATE_KEY_C=0x0000000000000000000000000000000000000000 + +STORY_RPC_PROVIDER_URL=https://story-network.rpc.caldera.xyz/http +STORY_NFT_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +STORY_LICENSING_MODULE_ADDRESS=0x0000000000000000000000000000000000000000 +STORY_ROYALTY_POLICY_ADDRESS=0x0000000000000000000000000000000000000000 +STORY_MINTING_FEE_TOKEN=0x0000000000000000000000000000000000000000 +STORY_ROYALTY_POLICY_LAP_ADDRESS=0x0000000000000000000000000000000000000000 +STORY_ROYALTY_ERC20=0x0000000000000000000000000000000000000000 +STORY_ARBITRATION_POLICY_ADDRESS=0x0000000000000000000000000000000000000000 + +SEPOLIA_RPC_PROVIDER_URL=https://rpc-sepolia.rockx.com +SEPOLIA_NFT_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +SEPOLIA_LICENSING_MODULE_ADDRESS=0x0000000000000000000000000000000000000000 +SEPOLIA_ROYALTY_POLICY_ADDRESS=0x0000000000000000000000000000000000000000 +SEPOLIA_MINTING_FEE_TOKEN=0x0000000000000000000000000000000000000000 +SEPOLIA_ROYALTY_POLICY_LAP_ADDRESS=0x0000000000000000000000000000000000000000 +SEPOLIA_ARBITRATION_POLICY_ADDRESS=0x0000000000000000000000000000000000000000 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb9d4fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +mochawesome-report +dist +dist-ssr +*.local +.env + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +package-lock.json diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..2a59cf4 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.0.0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e1ac06b --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# SDK-E2E-Tests + +This project dedicates to perform e2e test for the story protocol typescript sdk. + +## Prerequisites to run the e2e test + +- install nvm if don't have it by running: + + `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash`. + +- run `nvm use` to switch node version to v20.0.0 +- if you don't have v20.0.0 node installed, please install it by running: `nvm install v20.0.0` + +- run `npm i` to install dependencies. +- once all dependencies are installed, you should config your `.env` file with a reference to the `.env.example` file + +## How to run the test + +- Run specific test: + +``` +mocha -r ts-node/register -r mocha-steps ./test/**/**/*.test.ts --timeout 240000 +``` + +- Run smoke test in Sepolia: + +``` +test:sepolia:smoke +``` + +- Run smoke test in Story Network: + +``` +test:story:smoke +``` + +- Run e2e test in Sepolia: + +``` +npm run test:sepolia:e2e +``` + +- Run e2e test in Story Network: + +``` +npm run test:story:e2e +``` + +- Run all tests in Sepolia: +``` +npm run test:sepolia +``` + +- Run all tests in Story: +``` +npm run test:story +``` + +- Open report, test report is under ./mochawesome-report folder +``` +npm run open:report +``` diff --git a/config/abi.ts b/config/abi.ts new file mode 100644 index 0000000..e31a7fd --- /dev/null +++ b/config/abi.ts @@ -0,0 +1,387 @@ +export const accessControllerAbi = [ + { + type: "constructor", + inputs: [ + { name: "ipAccountRegistry", internalType: "address", type: "address" }, + { name: "moduleRegistry", internalType: "address", type: "address" }, + ], + stateMutability: "nonpayable", + }, + { + type: "error", + inputs: [ + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + ], + name: "AccessController__BothCallerAndRecipientAreNotRegisteredModule", + }, + { + type: "error", + inputs: [], + name: "AccessController__CallerIsNotIPAccountOrOwner", + }, + { + type: "error", + inputs: [{ name: "ipAccount", internalType: "address", type: "address" }], + name: "AccessController__IPAccountIsNotValid", + }, + { + type: "error", + inputs: [], + name: "AccessController__IPAccountIsZeroAddress", + }, + { + type: "error", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + ], + name: "AccessController__PermissionDenied", + }, + { type: "error", inputs: [], name: "AccessController__PermissionIsNotValid" }, + { type: "error", inputs: [], name: "AccessController__SignerIsZeroAddress" }, + { + type: "error", + inputs: [], + name: "AccessController__ToAndFuncAreZeroAddressShouldCallSetAllPermissions", + }, + { type: "error", inputs: [], name: "AccessController__ZeroAccessManager" }, + { + type: "error", + inputs: [], + name: "AccessController__ZeroIPAccountRegistry", + }, + { type: "error", inputs: [], name: "AccessController__ZeroModuleRegistry" }, + { + type: "error", + inputs: [{ name: "authority", internalType: "address", type: "address" }], + name: "AccessManagedInvalidAuthority", + }, + { + type: "error", + inputs: [ + { name: "caller", internalType: "address", type: "address" }, + { name: "delay", internalType: "uint32", type: "uint32" }, + ], + name: "AccessManagedRequiredDelay", + }, + { + type: "error", + inputs: [{ name: "caller", internalType: "address", type: "address" }], + name: "AccessManagedUnauthorized", + }, + { + type: "error", + inputs: [{ name: "target", internalType: "address", type: "address" }], + name: "AddressEmptyCode", + }, + { + type: "error", + inputs: [{ name: "implementation", internalType: "address", type: "address" }], + name: "ERC1967InvalidImplementation", + }, + { type: "error", inputs: [], name: "ERC1967NonPayable" }, + { type: "error", inputs: [], name: "EnforcedPause" }, + { type: "error", inputs: [], name: "ExpectedPause" }, + { type: "error", inputs: [], name: "FailedInnerCall" }, + { type: "error", inputs: [], name: "InvalidInitialization" }, + { type: "error", inputs: [], name: "NotInitializing" }, + { type: "error", inputs: [], name: "UUPSUnauthorizedCallContext" }, + { + type: "error", + inputs: [{ name: "slot", internalType: "bytes32", type: "bytes32" }], + name: "UUPSUnsupportedProxiableUUID", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "authority", + internalType: "address", + type: "address", + indexed: false, + }, + ], + name: "AuthorityUpdated", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "version", + internalType: "uint64", + type: "uint64", + indexed: false, + }, + ], + name: "Initialized", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "account", + internalType: "address", + type: "address", + indexed: false, + }, + ], + name: "Paused", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "ipAccountOwner", + internalType: "address", + type: "address", + indexed: false, + }, + { + name: "ipAccount", + internalType: "address", + type: "address", + indexed: true, + }, + { + name: "signer", + internalType: "address", + type: "address", + indexed: true, + }, + { name: "to", internalType: "address", type: "address", indexed: true }, + { name: "func", internalType: "bytes4", type: "bytes4", indexed: false }, + { + name: "permission", + internalType: "uint8", + type: "uint8", + indexed: false, + }, + ], + name: "PermissionSet", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "account", + internalType: "address", + type: "address", + indexed: false, + }, + ], + name: "Unpaused", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "implementation", + internalType: "address", + type: "address", + indexed: true, + }, + ], + name: "Upgraded", + }, + { + type: "function", + inputs: [], + name: "IP_ACCOUNT_REGISTRY", + outputs: [ + { + name: "", + internalType: "contract IIPAccountRegistry", + type: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "MODULE_REGISTRY", + outputs: [{ name: "", internalType: "contract IModuleRegistry", type: "address" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "UPGRADE_INTERFACE_VERSION", + outputs: [{ name: "", internalType: "string", type: "string" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [{ name: "accessManager", internalType: "address", type: "address" }], + name: "__ProtocolPausable_init", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "authority", + outputs: [{ name: "", internalType: "address", type: "address" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + ], + name: "checkPermission", + outputs: [], + stateMutability: "view", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + ], + name: "getPermission", + outputs: [{ name: "", internalType: "uint8", type: "uint8" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [{ name: "accessManager", internalType: "address", type: "address" }], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "isConsumingScheduledOp", + outputs: [{ name: "", internalType: "bytes4", type: "bytes4" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "pause", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "paused", + outputs: [{ name: "", internalType: "bool", type: "bool" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "proxiableUUID", + outputs: [{ name: "", internalType: "bytes32", type: "bytes32" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "permission", internalType: "uint8", type: "uint8" }, + ], + name: "setAllPermissions", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [{ name: "newAuthority", internalType: "address", type: "address" }], + name: "setAuthority", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [ + { + name: "permissions", + internalType: "struct AccessPermission.Permission[]", + type: "tuple[]", + components: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + { name: "permission", internalType: "uint8", type: "uint8" }, + ], + }, + ], + name: "setBatchPermissions", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + { name: "permission", internalType: "uint8", type: "uint8" }, + ], + name: "setPermission", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "unpause", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [ + { name: "newImplementation", internalType: "address", type: "address" }, + { name: "data", internalType: "bytes", type: "bytes" }, + ], + name: "upgradeToAndCall", + outputs: [], + stateMutability: "payable", + }, +] as const; + +export const transferLicenseTokenAbi = { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" } + ], + name: "transferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", +}; + +export const getLicenseTokenOwnerAbi = { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' } + ], + name: 'ownerOf', + outputs: [ + { internalType: 'address', name: 'address', type: 'address' } + ], + stateMutability: 'view', + type: 'function' +}; diff --git a/config/config.ts b/config/config.ts new file mode 100644 index 0000000..73eb9b1 --- /dev/null +++ b/config/config.ts @@ -0,0 +1,109 @@ +import { Hex, http, Address, Chain, defineChain } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { StoryClient, StoryConfig } from "@story-protocol/core-sdk"; +import { SupportedChainIds } from "@story-protocol/core-sdk/dist/declarations/src/types/config"; + +const TEST_ENV = process.env.TEST_ENV as SupportedChainIds; + +export let licensingModuleAddress: Hex; +export let licenseTokenAddress: Hex; +export let nftContractAddress: Hex; +export let royaltyPolicyAddress: Hex; +export let royaltyPolicyLAPAddress: Hex; +export let royaltyApproveAddress: Hex; +export let mintingFeeTokenAddress: Hex; +export let arbitrationPolicyAddress: Hex; +export let disputeModuleAddress: Hex; +export let ipAssetRegistryAddress: Hex; +export let rpcProviderUrl: string; +export let chainId: number; + +if (String(TEST_ENV) === "sepolia") { + chainId = 11155111; + rpcProviderUrl = process.env.SEPOLIA_RPC_PROVIDER_URL as string; + licensingModuleAddress = process.env.SEPOLIA_LICENSING_MODULE_ADDRESS as Hex; + licenseTokenAddress = process.env.SEPOLIA_LICENSE_TOKEN_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_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}`); +} + +export const privateKeyA = process.env.WALLET_PRIVATE_KEY_A as Hex; +export const privateKeyB = process.env.WALLET_PRIVATE_KEY_B as Hex; +export const privateKeyC = process.env.WALLET_PRIVATE_KEY_C as Hex; + +export const accountA = privateKeyToAccount(privateKeyA as Address); +export const accountB = privateKeyToAccount(privateKeyB as Address); +export const accountC = privateKeyToAccount(privateKeyC as Address); + +export const configA: StoryConfig = { + account: accountA, + chainId: TEST_ENV, + transport: http(rpcProviderUrl), +} + +export const configB: StoryConfig = { + account: accountB, + chainId: TEST_ENV, + transport: http(rpcProviderUrl), +} + +export const configC: StoryConfig = { + account: accountC, + chainId: TEST_ENV, + transport: http(rpcProviderUrl), +} + +export const clientA = StoryClient.newClient(configA) +export const clientB = StoryClient.newClient(configB) +export const clientC = StoryClient.newClient(configC) + +export function chainStringToViemChain(chainId: SupportedChainIds): Chain { + switch (chainId) { + case "sepolia": + // case "storyTestnet": + // return storyTestnet; + default: + throw new Error(`chainId ${chainId as string} not supported`); + } +} + +export const storyTestnet = defineChain({ + id: 15_13, + name: "story-network", + nativeCurrency: { name: "Ether", symbol: "SEP", decimals: 18 }, + rpcUrls: { + default: { + http: ["https://story-network.rpc.caldera.xyz/http"], + webSocket: ["wss://story-network.rpc.caldera.xyz/ws"], + } + }, + blockExplorers: { + default: { name: "Explorer", url: "https://story-network.explorer.caldera.xyz" }, + }, + contracts: { + multicall3: { + address: "0xcA11bde05977b3631167028862bE2a173976CA11", + blockCreated: 5882, + }, + }, + testnet: true +}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..67bec0d --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "sdk-e2e-tests", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test:sepolia:smoke": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps --grep '\\[smoke\\]' './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:story:smoke": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps --grep '\\[smoke\\]' './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:sepolia:e2e": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps './test/**/e2e/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:story:e2e": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps './test/**/e2e/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:sepolia": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps './test/**/**/**.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:story": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "open:report": "open test-reports/*.html", + "test:sepolia:open:report": "rm -rf test-reports && npm run test:sepolia && npm run open:report" + }, + "repository": { + "type": "git", + "url": "https://github.com/storyprotocol/sdk-e2e-tests.git" + }, + "dependencies": { + "@story-protocol/core-sdk": "1.0.0-rc.15", + "viem": "^2.8.12" + }, + "devDependencies": { + "@types/chai": "^4.3.12", + "@types/chai-as-promised": "^7.1.6", + "@types/mocha": "^10.0.2", + "@types/mocha-steps": "^1.3.3", + "@types/mochawesome": "^6.2.4", + "@types/node": "^20.8.2", + "@types/sinon": "^10.0.18", + "chai": "^4.3.10", + "chai-as-promised": "^7.1.1", + "eslint": "^8.50.0", + "mocha": "^10.2.0", + "mocha-steps": "^1.3.0", + "mochawesome": "^7.1.3", + "nyc": "^15.1.0", + "prettier": "^2.8.8", + "ts-node": "^10.9.2", + "typechain": "^8.3.1", + "typescript": "^5.4.2" + }, + "author": "storyprotocol engineering ", + "license": "MIT", + "bugs": { + "url": "https://github.com/storyprotocol/sdk-e2e-tests/issues" + }, + "homepage": "https://github.com/storyprotocol/sdk-e2e-tests#readme" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..9cc7904 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1292 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@story-protocol/core-sdk': + specifier: 0.0.1-beta-rc.9 + version: 0.0.1-beta-rc.9(typescript@5.3.3) + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + tsx: + specifier: ^4.7.1 + version: 4.7.1 + viem: + specifier: ^1.18.4 + version: 1.21.4(typescript@5.3.3) + +devDependencies: + '@types/node': + specifier: ^20.11.22 + version: 20.11.22 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 + typescript: + specifier: ^5.2.2 + version: 5.3.3 + +packages: + + /@adraffy/ens-normalize@1.10.0: + resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} + dev: false + + /@esbuild/aix-ppc64@0.19.12: + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm64@0.19.12: + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm@0.19.12: + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-x64@0.19.12: + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-arm64@0.19.12: + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-x64@0.19.12: + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-arm64@0.19.12: + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-x64@0.19.12: + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm64@0.19.12: + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm@0.19.12: + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ia32@0.19.12: + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64@0.19.12: + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-mips64el@0.19.12: + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ppc64@0.19.12: + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-riscv64@0.19.12: + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-s390x@0.19.12: + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-x64@0.19.12: + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/netbsd-x64@0.19.12: + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/openbsd-x64@0.19.12: + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/sunos-x64@0.19.12: + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-arm64@0.19.12: + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-ia32@0.19.12: + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-x64@0.19.12: + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@scure/base@1.1.5: + resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} + dev: false + + /@scure/bip32@1.3.2: + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.5 + dev: false + + /@scure/bip39@1.2.1: + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + dependencies: + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.5 + dev: false + + /@story-protocol/core-sdk@0.0.1-beta-rc.9(typescript@5.3.3): + resolution: {integrity: sha512-HcP3U8pp6n2VjeJRt3mkymy9BQfV1VD1TPvoTafTomgCqRH5Q5EC8QQSuvAgX5UX9TDXyx+xl+Vhmtpdq8ZEsA==} + dependencies: + abitype: 0.10.3(typescript@5.3.3) + axios: 1.6.7 + dotenv: 16.4.5 + viem: 1.21.4(typescript@5.3.3) + transitivePeerDependencies: + - bufferutil + - debug + - typescript + - utf-8-validate + - zod + dev: false + + /@types/node@20.11.22: + resolution: {integrity: sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==} + dependencies: + undici-types: 5.26.5 + dev: true + + /abitype@0.10.3(typescript@5.3.3): + resolution: {integrity: sha512-tRN+7XIa7J9xugdbRzFv/95ka5ivR/sRe01eiWvM0HWWjHuigSZEACgKa0sj4wGuekTDtghCx+5Izk/cOi78pQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.3.3 + dev: false + + /abitype@0.9.8(typescript@5.3.3): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.3.3 + dev: false + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + dev: true + + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 + dev: true + + /axios@1.6.7: + resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + dependencies: + follow-redirects: 1.15.5 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.1 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + dev: false + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.22.5: + resolution: {integrity: sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.1 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.0 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.5 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.14 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.1 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + dev: false + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.1 + dev: true + + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + dev: true + + /get-tsconfig@4.7.2: + resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: false + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + dev: true + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.1 + side-channel: 1.0.5 + dev: true + + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.1 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.14 + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.7 + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isows@1.0.3(ws@8.13.0): + resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} + peerDependencies: + ws: '*' + dependencies: + ws: 8.13.0 + dev: false + + /json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + dev: true + + /load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + dev: true + + /memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + dev: true + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + + /npm-run-all@4.1.5: + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} + engines: {node: '>= 4'} + hasBin: true + dependencies: + ansi-styles: 3.2.1 + chalk: 2.4.2 + cross-spawn: 6.0.5 + memorystream: 0.3.1 + minimatch: 3.1.2 + pidtree: 0.3.1 + read-pkg: 3.0.0 + shell-quote: 1.8.1 + string.prototype.padend: 3.1.5 + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + dev: true + + /path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + dependencies: + pify: 3.0.0 + dev: true + + /pidtree@0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: true + + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + dev: true + + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + dev: true + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: false + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /safe-array-concat@1.1.0: + resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + dev: true + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /set-function-length@1.2.1: + resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + dev: true + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + dev: true + + /shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + + /shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + dev: true + + /shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + dev: true + + /side-channel@1.0.5: + resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.17 + dev: true + + /spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.17 + dev: true + + /spdx-license-ids@3.0.17: + resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} + dev: true + + /string.prototype.padend@3.1.5: + resolution: {integrity: sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + dev: true + + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + dev: true + + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + dev: true + + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /tsx@4.7.1: + resolution: {integrity: sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + esbuild: 0.19.12 + get-tsconfig: 4.7.2 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-length@1.0.5: + resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + dev: true + + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /viem@1.21.4(typescript@5.3.3): + resolution: {integrity: sha512-BNVYdSaUjeS2zKQgPs+49e5JKocfo60Ib2yiXOWBT6LuVxY1I/6fFX3waEtpXvL1Xn4qu+BVitVtMh9lyThyhQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@5.3.3) + isows: 1.0.3(ws@8.13.0) + typescript: 5.3.3 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-typed-array@1.1.14: + resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false diff --git a/policy_backup/commericalUsePolicy.test.ts b/policy_backup/commericalUsePolicy.test.ts new file mode 100644 index 0000000..50518a1 --- /dev/null +++ b/policy_backup/commericalUsePolicy.test.ts @@ -0,0 +1,192 @@ +import { clientA } from '../config/config' +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai' +chai.use(chaiAsPromised); +import addContext = require("mochawesome/addContext"); +import { captureConsoleLogs } from '../utils/utils' + +describe("SDK Test", function () { + describe("Register PIL Commercial Use Policy (policy.registerPILCommercialUsePolicy)", async function () { + let consoleLogs: string[] = []; + + beforeEach(function () { + consoleLogs = captureConsoleLogs(consoleLogs) + }); + + afterEach(function () { + if (consoleLogs.length > 0) { + addContext(this, { + title: 'Test Result', + value: consoleLogs[0] + }); + } + }); + + it("Register a PIL commercial use policy with the parameter commercialRevShare 0", async function () { + const response = await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL commercial use policy with the parameter commercialRevShare 100%", async function () { + const response = await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 1000, + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL commercial use policy with the parameter commercialRevShare > 100%", async function () { + const response = await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 1001, + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL commercial use policy with mintingFee 0", async function () { + const response = await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + mintingFee: "0", + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL commercial use policy with invalid mintingFee", async function () { + await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + mintingFee: "minting fee", + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register commercial use policy: Cannot convert minting fee to a BigInt") + }); + + it("Register a PIL commercial use policy with invalid mintingFeeToken", async function () { + await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + mintingFee: "0", + mintingFeeToken: "0x0", + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register commercial use policy: Address \"0x0\" is invalid.") + }); + + it("Register a PIL commercial use policy with non-existent mintingFeeToken", async function () { + await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + mintingFee: "0", + mintingFeeToken: "0xA6B8193b10D7882B8E392d5FDC265C6397dad12", + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register commercial use policy: Address \"0xA6B8193b10D7882B8E392d5FDC265C6397dad12\" is invalid") + }); + + it("Register a PIL commercial use policy with parameters territories, distributionChannels, contentRestrictions as empty array", async function () { + const response = await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + mintingFee: "0", + mintingFeeToken: "0x857308523a01B430cB112400976B9FC4A6429D55", + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL commercial use policy with valid parameters territories, distributionChannels, contentRestrictions", async function () { + const response = await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + mintingFee: "0", + mintingFeeToken: "0x857308523a01B430cB112400976B9FC4A6429D55", + territories: ["US", "AU"], + distributionChannels: ["Book", "Youtube"], + contentRestrictions: ["casino"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL commercial use policy with parameters territories, distributionChannels, contentRestrictions as special characters", async function () { + const response = await expect( + clientA.policy.registerPILCommercialUsePolicy({ + commercialRevShare: 100, + mintingFee: "0", + mintingFeeToken: "0x857308523a01B430cB112400976B9FC4A6429D55", + territories: ["***", "$%^"], + distributionChannels: ["!@#", "$#@"], + contentRestrictions: ["&*%"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + }); +}); \ No newline at end of file diff --git a/policy_backup/commicialPolicy.test.ts b/policy_backup/commicialPolicy.test.ts new file mode 100644 index 0000000..486756c --- /dev/null +++ b/policy_backup/commicialPolicy.test.ts @@ -0,0 +1,270 @@ +import { clientA, mintFeeTokenAddress, royaltyPolicyAddress } from '../../config/config' +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai' +chai.use(chaiAsPromised); +import addContext = require("mochawesome/addContext"); +import { captureConsoleLogs, writeToCSV } from '../../utils/utils' + +const testResults: any[] = []; +let response: any; + +describe("SDK Test", function () { + describe("Register Commercial Policies (policy.registerPILPolicy)", async function () { + let consoleLogs: string[] = []; + + beforeEach(function () { + consoleLogs = captureConsoleLogs(consoleLogs) + }); + + afterEach(function () { + if (consoleLogs.length > 0) { + addContext(this, { + title: 'Test Result', + value: consoleLogs[consoleLogs.length - 1] + }); + } + }); + + const parameters = [ + "transferable", + "attribution", + "derivativesAllowed", + "derivativesAttribution", + "derivativesApproval", + "derivativesReciprocal", + "commercialAttribution" + ]; + + const combinations = []; + + for (let i = 0; i < Math.pow(2, parameters.length); i++) { + const combination: Record = {}; + + for (let j = 0; j < parameters.length; j++) { + combination[parameters[j]] = (i >> j) % 2 === 0 ? false : true; + } + + combinations.push(combination); + } + + for (const combination of combinations) { + let policyOptions: any + + policyOptions = { + ...combination, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + territories: [], + distributionChannels: [], + contentRestrictions: [] + } + + it("Create a policy with parameters" + JSON.stringify(policyOptions), async function () { + // derivativesAllowed is false, and one or more other derivatives-related parameters are true, the registration process fails. + if (!policyOptions.derivativesAllowed && (policyOptions.derivativesAttribution || + policyOptions.derivativesApproval || policyOptions.derivativesReciprocal)) { + response = await expect( + clientA.policy.registerPILPolicy({ + ...policyOptions, + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: The contract function \"registerPolicy\" reverted with the following signature:", "0x550c4952") + } else { + response = await expect( + clientA.policy.registerPILPolicy({ + ...policyOptions, + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + expect(response.policyId).to.be.a("string").and.not.empty; + } + console.log(JSON.stringify(response)) + + const policyOptionsKeyValue: { [key: string]: string } = {}; + + Object.entries(policyOptions).forEach(([key, value]) => { + policyOptionsKeyValue[key] = String(value); + }); + + testResults.push({ ...policyOptionsKeyValue, policyId: response && response.policyId ? `${response.policyId}` : "" }); + }); + }; + + it("Register a commercial policy without royaltyPolicy address", async function () { + await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: The contract function \"registerPolicy\" reverted with the following signature:", "0x7660ada6"); + }); + + it("Register a commercial policy with an invalid commercializerChecker address", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + commercializerChecker: "0x16eF58e959522727588921A92e9084d36E5d3851", + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: The contract function \"registerPolicy\" reverted.", + "Error: PolicyFrameworkManager__CommercializerCheckerDoesNotSupportHook(address commercializer)"); + }); + + it("Register a commercial policy with an invalid commercialRevShare value", async function () { + await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + commercialRevShare: -1, + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: Number \"-1\" is not in safe 256-bit unsigned integer range") + }); + + it("Register a commercial policy with commercializerCheckerData", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + commercializerCheckerData: "0x48656c6c6f2c20776f726c6421", + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a commercial policy with minting fee but no mintingFee token address", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + mintingFee: "10", + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: The contract function \"registerPolicy\" reverted.", + "Error: LicensingModule__MintingFeeTokenNotWhitelisted()") + }); + + it("Register a commercial policy with an invalid mintingFeeToken address", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + mintingFeeToken: "0x0000", + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: Address \"0x0000\" is invalid.") + }); + + it("Register a commercial policy with invalid minting fee value", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + mintingFee: "mintingFee", + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: Cannot convert mintingFee to a BigInt") + }); + + it("Register a commercial policy with valid territories, distributionChannels and contentRestrictions parameters", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + territories: ["US", "AU"], + distributionChannels: ["YouTube"], + contentRestrictions: ["Casino"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a commercial policy with the parameters territories, distributionChannels, contentRestrictions as special characters", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: true, + royaltyPolicy: royaltyPolicyAddress, + territories: ["!@#", "@#$"], + distributionChannels: ["***"], + contentRestrictions: ["`*&"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a commercial policy with all parameters set", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + attribution: true, + derivativesAllowed: true, + derivativesAttribution: true, + derivativesApproval: true, + derivativesReciprocal: true, + commercialUse: true, + commercialAttribution:true, + commercialRevShare: 300, + commercializerCheckerData: "0x48656c6c6f2c20776f726c6421", + royaltyPolicy: royaltyPolicyAddress, + mintingFee: "10", + mintingFeeToken: mintFeeTokenAddress, + territories: ["US", "AU", "UK", "CA", "FR"], + distributionChannels: ["Book", "Youtube", "Tiktok"], + contentRestrictions: ["Casino"], + txOptions: { + waitForTransaction: true + } + }) + ).not.to.be.rejected + + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + after(function () { + if (testResults.length > 0) { + const csvFilename = "./test/policy/test-results-commicial.csv"; + const headers = Object.keys(testResults[0]); + writeToCSV(csvFilename, headers, testResults); + } + }); + }); +}); \ No newline at end of file diff --git a/policy_backup/nonCommicialPolicy.test.ts b/policy_backup/nonCommicialPolicy.test.ts new file mode 100644 index 0000000..e79b518 --- /dev/null +++ b/policy_backup/nonCommicialPolicy.test.ts @@ -0,0 +1,154 @@ +import { clientA } from '../../config/config' +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai' +chai.use(chaiAsPromised); +import addContext = require("mochawesome/addContext"); +import { captureConsoleLogs, writeToCSV } from '../../utils/utils' + +const testResults: any[] = []; +let response: any; + +describe("SDK Test", function () { + describe("Register Non-Commercial Policies (policy.registerPILPolicy)", async function () { + let consoleLogs: string[] = []; + + beforeEach(function () { + consoleLogs = captureConsoleLogs(consoleLogs) + }); + + afterEach(function () { + if (consoleLogs.length > 0) { + addContext(this, { + title: 'Test Result', + value: consoleLogs[consoleLogs.length - 1] + }); + } + }); + + const parameters = [ + "transferable", + "attribution", + "derivativesAllowed", + "derivativesAttribution", + "derivativesApproval", + "derivativesReciprocal" + ]; + + const combinations = []; + + for (let i = 0; i < Math.pow(2, parameters.length); i++) { + const combination: Record = {}; + + for (let j = 0; j < parameters.length; j++) { + combination[parameters[j]] = (i >> j) % 2 === 0 ? false : true; + } + + combinations.push(combination); + } + + for (const combination of combinations) { + let policyOptions: any + + policyOptions = { + ...combination, + commercialUse: false, + territories: [], + distributionChannels: [], + contentRestrictions: [] + } + + it("Create a policy with parameters" + JSON.stringify(policyOptions), async function () { + // derivativesAllowed is false, and one or more other derivatives-related parameters are true, the registration process fails. + if (!policyOptions.derivativesAllowed && (policyOptions.derivativesAttribution || + policyOptions.derivativesApproval || policyOptions.derivativesReciprocal)) { + response = await expect( + clientA.policy.registerPILPolicy({ + ...policyOptions, + txOptions: { + waitForTransaction: true + } + }) + ).to.be.rejectedWith("Failed to register policy: The contract function \"registerPolicy\" reverted with the following signature:", "0x550c4952") + } else { + response = await expect( + clientA.policy.registerPILPolicy({ + ...policyOptions, + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + expect(response.policyId).to.be.a("string").and.not.empty; + } + console.log(JSON.stringify(response)) + + const policyOptionsKeyValue: { [key: string]: string } = {}; + Object.entries(policyOptions).forEach(([key, value]) => { + policyOptionsKeyValue[key] = String(value); + }); + + testResults.push({ ...policyOptionsKeyValue, policyId: response && response.policyId ? `${response.policyId}` : "" }); + }); + }; + + it("Register a Non-Commercial Policies with the parameters territories, distributionChannels, contentRestrictions as empty array", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: false, + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a Non-Commercial Policies with valid parameters territories, distributionChannels, contentRestrictions", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: false, + territories: ["US", "AU"], + distributionChannels: ["TV"], + contentRestrictions: ["Casino"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a Non-Commercial Policies with the parameters territories, distributionChannels, contentRestrictions as special characters", async function () { + const response = await expect( + clientA.policy.registerPILPolicy({ + transferable: true, + commercialUse: false, + territories: ["Test", "***"], + distributionChannels: ["!@#"], + contentRestrictions: ["$%^@"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + after(function () { + if (testResults.length > 0) { + const csvFilename = "./test/policy/test-results-noncommicial.csv"; + const headers = Object.keys(testResults[0]); + writeToCSV(csvFilename, headers, testResults); + } + }); + }); +}); \ No newline at end of file diff --git a/policy_backup/socialRemixPolicy.test.ts b/policy_backup/socialRemixPolicy.test.ts new file mode 100644 index 0000000..d75e7ba --- /dev/null +++ b/policy_backup/socialRemixPolicy.test.ts @@ -0,0 +1,71 @@ +import { clientA } from '../config/config' +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai' +chai.use(chaiAsPromised); +import addContext = require("mochawesome/addContext"); +import {captureConsoleLogs} from '../utils/utils' + +describe("SDK Test", function () { + describe("Register PIL Social Remix Policy (policy.registerPILSocialRemixPolicy)", async function () { + let consoleLogs: string[] = []; + + beforeEach(function () { + consoleLogs = captureConsoleLogs(consoleLogs) + }); + + afterEach(function () { + if (consoleLogs.length > 0) { + addContext(this, { + title: 'Test Result', + value: consoleLogs[0] + }); + } + }); + + it("Register a PIL social remix policy with all parameters as empty array", async function () { + const response = await expect( + clientA.policy.registerPILSocialRemixPolicy({ + territories: [], + distributionChannels: [], + contentRestrictions: [], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL social remix policy with valid parameters", async function () { + const response = await expect( + clientA.policy.registerPILSocialRemixPolicy({ + territories: ["US", "AU", "UK"], + distributionChannels: ["BOOK", "YouTube", "Tiktok"], + contentRestrictions: ["casino", "test"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + + it("Register a PIL social remix policy with special characters in parameters", async function () { + const response = await expect( + clientA.policy.registerPILSocialRemixPolicy({ + territories: ["ABC", "***"], + distributionChannels: ["!@#"], + contentRestrictions: ["#$%"], + txOptions: { + waitForTransaction: true + } + }) + ).to.not.be.rejected + console.log(JSON.stringify(response)) + expect(response.policyId).to.be.a("string").and.not.empty; + }); + }); +}); \ No newline at end of file diff --git a/policy_backup/test-results-commicial.csv b/policy_backup/test-results-commicial.csv new file mode 100644 index 0000000..f5a8cf4 --- /dev/null +++ b/policy_backup/test-results-commicial.csv @@ -0,0 +1,129 @@ +transferable,attribution,derivativesAllowed,derivativesAttribution,derivativesApproval,derivativesReciprocal,commercialAttribution,commercialUse,royaltyPolicy,territories,distributionChannels,contentRestrictions,policyId +false,false,false,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,54 +true,false,false,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,55 +false,true,false,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,56 +true,true,false,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,61 +false,false,true,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,62 +true,false,true,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,119 +false,true,true,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,63 +true,true,true,false,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,64 +false,false,false,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,65 +true,false,true,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,120 +false,true,true,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,66 +true,true,true,true,false,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,67 +false,false,false,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,68 +true,false,true,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,69 +false,true,true,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,70 +true,true,true,false,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,71 +false,false,false,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,72 +true,false,true,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,121 +false,true,true,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,73 +true,true,true,true,true,false,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,74 +false,false,false,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,75 +true,false,true,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,76 +false,true,true,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,77 +true,true,true,false,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,78 +false,false,false,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,79 +true,false,true,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,80 +false,true,true,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,81 +true,true,true,true,false,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,122 +false,false,false,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,82 +true,false,true,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,123 +false,true,true,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,83 +true,true,true,false,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,84 +false,false,false,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,85 +true,false,true,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,86 +false,true,true,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,87 +true,true,true,true,true,true,false,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,88 +false,false,false,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,57 +true,false,false,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,58 +false,true,false,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,59 +true,true,false,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,60 +false,false,true,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,89 +true,false,true,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,90 +false,true,true,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,124 +true,true,true,false,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,91 +false,false,false,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,92 +true,false,true,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,125 +false,true,true,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,93 +true,true,true,true,false,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,94 +false,false,false,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,95 +true,false,true,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,96 +false,true,true,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,97 +true,true,true,false,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,98 +false,false,false,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,99 +true,false,true,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,100 +false,true,true,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,101 +true,true,true,true,true,false,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,102 +false,false,false,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,103 +true,false,true,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,104 +false,true,true,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,105 +true,true,true,false,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,106 +false,false,false,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,107 +true,false,true,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,108 +false,true,true,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,109 +true,true,true,true,false,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,110 +false,false,false,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,111 +true,false,true,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,112 +false,true,true,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,113 +true,true,true,false,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,114 +false,false,false,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,false,false,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,true,false,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +true,true,false,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,, +false,false,true,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,115 +true,false,true,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,116 +false,true,true,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,117 +true,true,true,true,true,true,true,true,0x16eF58e959522727588921A92e9084d36E5d3855,,,,118 \ No newline at end of file diff --git a/policy_backup/test-results-noncommicial.csv b/policy_backup/test-results-noncommicial.csv new file mode 100644 index 0000000..8168ea4 --- /dev/null +++ b/policy_backup/test-results-noncommicial.csv @@ -0,0 +1,65 @@ +transferable,attribution,derivativesAllowed,derivativesAttribution,derivativesApproval,derivativesReciprocal,commercialUse,territories,distributionChannels,contentRestrictions,policyId +false,false,false,false,false,false,false,,,,13 +true,false,false,false,false,false,false,,,,12 +false,true,false,false,false,false,false,,,,20 +true,true,false,false,false,false,false,,,,9 +false,false,true,false,false,false,false,,,,21 +true,false,true,false,false,false,false,,,,22 +false,true,true,false,false,false,false,,,,23 +true,true,true,false,false,false,false,,,,24 +false,false,false,true,false,false,false,,,, +true,false,false,true,false,false,false,,,, +false,true,false,true,false,false,false,,,, +true,true,false,true,false,false,false,,,, +false,false,true,true,false,false,false,,,,25 +true,false,true,true,false,false,false,,,,26 +false,true,true,true,false,false,false,,,,27 +true,true,true,true,false,false,false,,,,8 +false,false,false,false,true,false,false,,,, +true,false,false,false,true,false,false,,,, +false,true,false,false,true,false,false,,,, +true,true,false,false,true,false,false,,,, +false,false,true,false,true,false,false,,,,28 +true,false,true,false,true,false,false,,,,29 +false,true,true,false,true,false,false,,,,30 +true,true,true,false,true,false,false,,,,31 +false,false,false,true,true,false,false,,,, +true,false,false,true,true,false,false,,,, +false,true,false,true,true,false,false,,,, +true,true,false,true,true,false,false,,,, +false,false,true,true,true,false,false,,,,32 +true,false,true,true,true,false,false,,,,33 +false,true,true,true,true,false,false,,,,34 +true,true,true,true,true,false,false,,,,35 +false,false,false,false,false,true,false,,,, +true,false,false,false,false,true,false,,,, +false,true,false,false,false,true,false,,,, +true,true,false,false,false,true,false,,,, +false,false,true,false,false,true,false,,,,36 +true,false,true,false,false,true,false,,,,37 +false,true,true,false,false,true,false,,,,38 +true,true,true,false,false,true,false,,,,6 +false,false,false,true,false,true,false,,,, +true,false,false,true,false,true,false,,,, +false,true,false,true,false,true,false,,,, +true,true,false,true,false,true,false,,,, +false,false,true,true,false,true,false,,,,39 +true,false,true,true,false,true,false,,,,10 +false,true,true,true,false,true,false,,,,3 +true,true,true,true,false,true,false,,,,1 +false,false,false,false,true,true,false,,,, +true,false,false,false,true,true,false,,,, +false,true,false,false,true,true,false,,,, +true,true,false,false,true,true,false,,,, +false,false,true,false,true,true,false,,,,40 +true,false,true,false,true,true,false,,,,41 +false,true,true,false,true,true,false,,,,42 +true,true,true,false,true,true,false,,,,43 +false,false,false,true,true,true,false,,,, +true,false,false,true,true,true,false,,,, +false,true,false,true,true,true,false,,,, +true,true,false,true,true,true,false,,,, +false,false,true,true,true,true,false,,,,46 +true,false,true,true,true,true,false,,,,44 +false,true,true,true,true,true,false,,,,45 +true,true,true,true,true,true,false,,,,5 \ No newline at end of file diff --git a/test-reports/assets/MaterialIcons-Regular.woff b/test-reports/assets/MaterialIcons-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..b648a3eea2d16b6ce783906d6b7d5f251b9eb56c GIT binary patch literal 57620 zcmY&^NelVwr$(CZQHhO+t!`$=Dp;-onGnG%1YJl`q9)OmoxnxQ~!cx z7yTwvL_vxFmrDfzAms%BFq1u;FO!o|pk)96AY1*_{QHG2qyvG0ft8*u0022U001yH z001b^-7WpDiJrqRN5%B30sjv_KLEfcmTtzs92WpU*)#y4J?2lST9B!co*@9hGW4&8 z`4=pp>u1uYzvM6XUw$aRAo>Fc^vBf7(e;Ws_PPwU|4;c6vAY`D4U;s#9fGPn0SECQP7GZX@2I3WUo4pB*5bE|8|@Fm_rEMeislDJkxA(b z7tCUlVW`i$#DWbQZsJMnX?Wci4^U?JYSLP9^{854ZTD(mZmHb5Kg#0WKDy&x2*LAw zTo>W>_}n7h_S_HghvODJCnAQCPwY%2)^GlIWGK?6;jNOlF0WOptuo*kv8|j_g}1_c zE+(DP(B{zS(DhLNP{BA|<)Y%`;w0l_Q6WO2EZKL|*ys_L#EFFrpqv(C%GE%Zc>Y>~HgyL!|@;oHhHQP}pO{tpwUsv%B#6 zd!u<`WFA2+30r%fO!U*(zhn@xA;rJNv7)dPqcC&`Gkpup)6p#8t-&S%`VH#+Vw47 z1ZrYVoekY6m!+MmkfSl@=(83Jh>RM=6@_BZ@#m2@gjSQDm~M#;i*tlcAUFkg;=PQs zMJnWEk_2tyBE8hNCL`jfI6N%DY2a%&bpE?0I6k{55d>M94FoUL_axD8r2MZ;xv-@Hvaw zq9i|4u;P4|nOd?89&S@e7$fg9w5ik7{;s1p<$%{Px^pXA)ZiJ*T_`9A%ZsrKN$)%D ztOb7M#2uWj)1nwnb0-iLgR~WM*q`jEA@w~(cU<3;TcGz6UD5z$GW#O`20df8;pRVY zzoC4zzo)g|0FvRy)=K0+BCPi)KabsDwpTdF%AsoFeo@XLYf`R3tW(N(V4APa8VTqO zYaFp!PT=^&)H+bv3U5T*5vk{AeXej$R;Oewpd^)uVn0)o;zmt7lRTM9REl*{mONZN z<|S<4WFKxe0$E{t$xn2nCGWG0$W{E${W(Sw*BQ{1U**^A&8 zI$rVs&Q8tZEFBp*nancPz{--(mmK4uN7@+{1uq?=-Qk{v}Ai(*JQ<Qb) ziI9oKiR_8ziS&uliH3S=!6yBgeC6Harr>SJm)-bB1PpopT0sz{MF16qoR^V~HVCLue&LVU6e$yTtP$;v!eHTHBEyb|!?`@o*sevdTrHJeop zwT0oAcEND0l*idnVa$A8P(K0ZVSeX`ivqs>8G5=X`&lYF5ee)Be(wuIckU$q*}<;@ z4r2#7nhUhaoUJcj*VC0s$-JYm=`HaJpLeRxTzn;J_aSv6KyL2}I@N-Vcnp-x5iQOX zh|qORY8E5lSTmQTC|@~e(_QfIL@S-9IHiq1PS)wZ*$t!IY(~`< z@a6PU3WzmFyeT?es(00UuAHM@*;!`}3SHx%=v)j#UpfM9*n2$NSKt9wR?y-h;`3^0 zlYNOTiCjHHknv2F8#vP^LJ`;lRH+t>(JB&-@R!sXn&Y*hje6bmXmdd%}w>*#3>A))z4~D%XF*+~}&sYg%I=ANO zz+0?E;B}3LCnPO}qgGQ!*}YM8HpXcy0t)~RdNRI{N?XQk$esPOG6h--f1AR(K2Yziif%z`E-CQd|Vjt8W*X++>o7Rd;B-rq6B<{d^Zlfz}sJqYrNd!pa_ zv~xQf91*{23mLP% z=BlE92usq)WUw6&Ro)nNR3PVL#>GlTLTK{`kJK^8KKJLHq&ZVA4;v&*36q<~QinCH z8E8{4&WTw=(-taC8{*&Y)m>{mW;<|X=qQp<-?&t`l^B*7m*i@fXMII|Q+)w_3;ssi z%qnt_Hr$~Zm1?=m@E-RRyV`{IWmoBEdvGCKTzT8TS91N#R<1Np$x??E36qMGdv<18 z-6C$)sM&E&c*s)~p)A_WQ4HKo+H)oAY8H!rC62qL1M);9P+;YW0|eykR*VC;U+M$b ztVo>Ecpx6C5U+sWXwHg;;i@n-q2H3Oeh+`um{bho(vHgJ^=3xK-bvtgD!Q+M%U>PP zQpY9F=}<8`)-ouvWJa~Y#!7b;#NGKhR^V@_k;Io-OE|z-BG$LdgV;o>~$$`2S05D;l@z?Bzz6w^+;vkT0VL`Ae&SJ zB7L8(p|q!#^NJ=dXA143B}42VU%KTfd%-Y_rKfmqA9`_DiO*O)Ij*dIQDvIVs0itZ>oVwYF~0%fjhehYKuIl;r$d0Z{9rb$9%=i zll)UXq1#cW|ECVFNqkfDd4YUbD+D05 zKJhAu2Ew|aPfc~ZCwAyQQIaVTo!aw5f0++2`+ zfh+wx1C4~2ezj|#t5caIHkncw<$=cm+JOvG0#m%$7+%6#0!l(uf>y#n0%Jl&f=7Z$ zLQ4YeM6o70Tq0?r$v#Hbi&S>oK*JS54wtBrT`Vs1WpP4tXE5gz9&el z<)-MSY1?K(>7M;TV#DV1BQd6`oqLQz>u%LYpC1Rvxm6ceTY_XuJ75~{Ri=3s%%yL4 z6#hikAX3@&grZH&61yjBtJqUC;@0^)_q%a0ZOcqWj3q!fZc&6{W!}EwL@8JOWf7;1 zoQZNbbVuXgqUc6R3poRBwF2_1*5G{UT9_g>pDmxZ=^WXsVIr-I@^#YnJ7jA-{r=6I&hH zN#!;#6L&mW<`MItoSS0tjqbmAvUogwxJflVDmDxZ*!0wKp7%)JmTY3p!_` zuHK_rDjtS~%J(<3mhcsP630pGaY|{xrTNUfkyAR2e)g|4d9Cps5uy_j7CP@6?Ks@& zD@oo9BS^C+ub8IcqJ0ttGfTxPO*MC3*);KI7SZWza^_vsPrlMgp+5&xU}>sG!wO{^ zR|1U!mknKuS7M8-wzvmTE^0?UT`PZ#$+IFUc4!P(5pCp z7b^|QjLrMQ$J5ibz-r3ga%PbOV#S%pE>P3v!h1SancBz>cSRYh9a=?~s;+s)!5DC* zhs}NNBxPb9{(sAtkPxmn)jm0+ne-N z2lo(C_W<2mr`PV|o*5!yugWoq57fBC^<~`xOZF1oV+Rm#!ZGsuSX|=0F%UyrA$%G| zty?ztS=*)7-2(-Vb5h7{7p#o(s;ls{VtRUJRB1_!?*J5fg}XrBY(FT1<1q@kF3-Y^ zhnto$jkY<0=g>?wnXk=`bXj66^8t?xUgLvG)2^uBq_m?G_vxMFH=`a4q-<@Kqbmp| zB>9l;CEI=+e-Y0nbj@oJ-|5m&y!eb})kCwC1|#U3#rTIz7s+a~y&WitVNrTy^J0QP zwIFd`$;0bb+`Qs*0EC3WQS1V8ibwY_8okmt%#-<84>$><$U7m0&Sf-WAIODLRZMEX z6z4JIJ>naiAf+1$V0b5GQ)-z#?pw6t_le&)} zV-DC~dpZj<`;$9K@y1FXhCI1<#^4?rl&@3QgD*^iA64x0!*B$+-7#UBWae z8y+5zDNDMW@1WS~!l&nI3&`zv23(b{R@kq!TJ?G{OPeS2z68QOa^h?zb6Fm#g5F+o z)565l!C0(>i90JJxK{xo!7Z9YB%l;G^8e{zs}KkH=E%>ead@Px{N;^xTF(Aih(%-(+? zaga~hD5!tGa;2Ed?Y7$VXPHjdNo>w;!jS;vL-J0eGAf_jEREX|t+DS-aJAM>a5*}7 znxOS_w%Y_v2!zBtliWNgr))mBt4GFNwi!;Gh3WME*}6}k3xFV`x< zLD6p(sai1gKU<~W5+)pyia28fSaQrTgkHOh4BzM%63Nh#v#v?$&}`kf48&L3fT`n} zq#E?+Nb_Xm?Xz(|{OZrxw>rH#%R1G<7`Fc2_ev)>5@uLnxCqhCGGIhAxt`=o za^rrmYEHK@DluA_x=!V0@^BC3fAe}SyPQ~?ad?~UXb`nlw!Yfj+{|txbSMd7OU!U^ z31UYoXj2)e46Auaq&@O5RqM+HH=mYQ{FHa^371(K-{zS5*J4HcUZbAtFDM_a62_-6 zhtjg78Cbj7yhMLTeqNnor!6X?j?v`G^whuBA<@G&WVQfbwss6WNV-0pTo@PYS(Z53 zCa2LF9}m@0K*EJ7gjNp06~1p~Dy68fV_%EYSZFn8Gv{>>FAAwXWTt18!lvP?EY%Dj zJ{}%)BNQKEpm@w2jH8EjF{LIST~-emATQdZTNhm$@1yqG(mxH9+IGf>Oayn;ho zgr3_1dOlpex`UYIRWQ*kUV$b(>T*L78OOW=L{D2zt8r#2)vTRS+NJPn4!cD2l=Qm> zCDT3vdEa6wLRLjfiTICBfIoE$nOu4he>^|toeqZ@MbCguI=8ItwBIdT)m|eG?Oi6W z`WU%V4M`Q~4ttQ(q8WLKZu z)AEbW>s2UiCgjd}(H4BydS_(kb;>oqjG*>GE|Maax~k(xvc8e}G4&zh&cjs3^pD#^ z@PkjZ^}lIv7cOrzZHM!QMzVVPn}?c1-aE(K4e)59b(9Ah2J^b*sf$s;f?FSaq%4I8 z3a%*hEijojCk&wi*oT_EGG22(GR*KWRjiK#{>^|Cm^6fj&b4K1D;idpG`RPFgi!&PcXzh}kwqAiwc$otwH-YVRm!q#YQJ%P&Lnt={ZWph5NFkx&SH>mQ z9R0T#;KyrtihYj6#PX~5KB7cR z=?sG$Sp{=PnlU!0s;KO#GxD8*}K%1W8<)k#|ooe|xCu5dRvXaU1MaI1r2So1D)!R|?Qa!}` zxlhNyu~9KGrfH1xF|+c>b%|O~;B%B!EPI|KN`=_4Qc1Yp1==k*xOyE&NUkN5mlY&V zzh$6;NIedWNI<4KD%EZtUn4p+(tYL5Kw7C7wed;|XI9emiYee@onsC2S%OA}siLnl z!S+<^Lf(0UMLl|=aC01W2;u=7WzJ>{ zCOnJCQjx|}GGWCScuq%(aeLgQ0<^m-b0x;3!Lpct?iI=ul-&Z|^fH?u+=054X>(WL zn>NGRNDmPHi=JT2!JkQy?1(1tP+uS`hCK5cv-^~R!vpy>lmEo-_Vuz76Pagjpc2=O z8S)vwxs()yw7TDz!{?|Dp;-&H5|;V?vO8#9Mcg_)`w?WlyUHCt9hN)hQxnLf=!?t< zE6X8qqtoFLWT?@4biJW>>KM-xl#~fL_k$Z$Q*^lA4g^YIGxaqaaP{?Q2aeO>(NjxFMOT>DrUj#tD|h-~DZ z+t(`cessRx)1Ncd?Y_c+#?C6f3c5ebY$1a!M_9Mxg6KNWaP;(PFG1zj?ea>=6H#A% zFd%fbE;F_1gl@k&tzMy(jZ(brs$XX}RmE7N_rRqzwf3;!xiT)Wm_%T1r=bt2Dbym9 zDkv@Hu6sKC06mUy>~J#@xR+c!LN+T@Ipx(Zh?Bx1*1&br5(;UX!y7!eZOmBYuvi_4 zF1nMcm?9z~krDCw_86JSPu>L|B5tq9rEZc^P_81~)Cze+Y+^AlYG9dB`W$e*2&=PS zdcWqCi6MNFa;yNWi9V9Ml9b2}G&kWnF_OKStk{z*H<%VY{{6boH(=8aCKLAm5gN*t zeu5{QWszDudu;9I2BP`!bZYO}%78#G&XA3M5hBZsU2TOta=alk=9kIC-U%ev>2H`G zwQAymG3vN3mLIz&l95`39l1cts_>&+Xb?X|T_F?aXBtD7DJ@;Tk+V+WEVo*k9bz@# z37+M5pP;60!T5spyVwhD2y$Zp;yl2OKub{etR6o}-ujDm#Pl(Wj_Q^%>Bss(C|aZN zw3!88I9;>;cFcK2df{w^$}td)k#l?(&dU3{XD8=5CPU2DxX@V`E3NNYYb#}EVJ~x@ z5%F0$6Hk=+Og3eL2M0XWQik1p^l}Q(_CHg06Bisv6n-YagwuLAE)BW&(~ zY8&0+G6Yx>fbN)UsVrPj7#AY2KhbRCo>7vGCXS2@b3AkIqk^e;nS@q`S&wWC?ZG76 za5BaVGco-O%-aAm#v6jtTvZ$Us+wURw`iH9r|-CXvcZlnDsbGcc zng6y^2tPHL_U$;kT_0(ghBIq8SGr^!hA-t~lnGd4ZR8zqWIYaN-d%=+kjtZ=gqku~ z{}H2TAxs9m!+!^fhaiBy84nqU;usmE9y}HW{8mwh4Fac^pji`U zeV7w>w55Iy9zV;rii7Xt!lbCS_IW>sXasYt)Z~YpA(fIcAIZMBHbnOIOTca63;grI zhq0SOY1>+-q?3B~b4i6+BDc2x$$gn8TF=Fkt3&5j7gU!>Kii|M@z7*;p4OM_@s}lG zB)3flH@%0&bJ1)*F66<~#<4WG14QyR84(F>t zJKwUP&Pz!#tg`QyL{BW zq&#q%U5FDtB7@T!?hqtgrN+X*skIAOv;b=zZBB-ER?C=Y+FCc$9q3kuEqD zyIEA-9LCD+IH1UYh}kwjYYs2HlzEG!6@F2rlGiKC|oLYe}fe zMNTJ;f{1#%58fpE1)P?&3(K7oMNPk%V$IYxgjyJXu-ppe86kDvmI2{o^ zEMV15dI-8`$+R`4U)P4($zoo{F4nC~b#OLQTC_sygyfj>?l!QleK$e;S!t1%o*pCm=VN~xwzT+le6Qq|bE&So zAnwtuG&1RkMDZIpDfRkHp;s@sqvGRYoB8iS8WqLEw$ag{l&qbKnH(O!3Wv({tZx(9 zrVG-Fh}u!&`2mB;R|cyvJM*)x;n=-!**cN9;ew-;rIoC(ay~fUia@`{U-Sr(Nxic6 zV4+!?uwHc#lnM|i?eH8~?ehpzOPxQ~^F!dn>jtnR*b@u`>)?i+dT9yg511ZXTEk_9 z4;OQX%m{^K1@_@IiEYsN>B0wl{fq0=P2>^sk}{+`-U#B(f+NcLDzb>uk_Q;oB4*q5 z1eXenJkr(JGeUp^6c$xV;wJ^ZfKBLwHTVp+oXD4D4RJu;*dSYZ?)zFP0)>jFI5ns; z`MbmMhaJ4&%i9DLOBwcR`xZ)8YlT&Eu?m#)tLu7|MMfTQffpqmvaz%=Y`E1ZO^%rf zB^|h)Yc6*YtO0R>N_*kNd54@5&QbqB`3$ zGxc6r%uWtB(G2a(H|=GJbi%E8e)UQG2OHe4oej(3FH{(QNe$gC#%85G^mpwV2{cP+ zWYoo??vPGz|NdOn#EZND+(h6v;igqoGHaFCcrOr>ot@3Mb}a!vi_BdWF}Z>YMev9U zdQFK-yTw$t1(V!_`xhBV_7KX6&dcoRv;lRCYQ?R*BMJiOkn1xm-CL>k90M(qla^>L z7u)BGp}ZzDI#zoEd^%Iy^W1JYEW5HEUUeEBDK59j?{Ai96-ITV6O&f@dg?dhrrJb_ zTLx0aWXe*63u#&Z*o<#=K-e>24OJ^3v<;@J{kGa-BI+k6_eO^snJVy+#?&bOB0Uva z9dt5nD|p`QbJK~8x!L52ZS*Ce0xJfQW@?;tRjzo!(FMyMW%b7I*fN3lC#Ubhqk!i zBY@}MCB;}M@2vF-Gbzjo@+>|td`#wFyuaZ`g+8nDD(5;Klt#;MxCbvCbRvj9Tjam2 zv*QNjKO<;Sm&Zv}doO!Y0diJcN(7VF$6@=f3p2mgmLp`=R1lNf5{9+09AGiB3xu z9U0v^z3hM7sJ^cA4#(nPq^z-3iW+7qAcJi{dw-%NMFosfx`@mT3=|0pEASo#k9K%S zs^G`yjm+Hfj+%+#otuh9U%s!RnH)HC1-QVZ;WqfD=`AyFWB^Zv9rHVMy%o6iN2aGt zbsQ`3@O2m6)J%SKDV-;)5IupQM`&6Imt+kvqQt~`(=Q^+Ha{P~u2SZnhT4k!EszM~ zy!Rmt6>-*?KinXOMO>r!dX`=j(ML);EE`t2RWKb=a}R+b)yBKq+eo7bDg)FJu2@Hd z)_C->k4dsxo^d_r(^h9b!bKN^(jh$2Me2wZAij(4l^ErF6_uF<8inX$N*KfrkZk1P zLC7}t*nyNWX=O*><2XZwFQ>bGC1P3x&A{h8HTGUYx_PbZMD9YiN(xmKlUbq)euF;T z!sNkeD-|>ry^R$@joo5C9RP`ou0mKW^eC!Z|~_q>TqxGE^JW` zgD68I9UUEgEdygOKmmNLuHHW&7--O+A4b14Nm*vmdPwMXfIvmiFIT|9Dd1Qt737dR zM%9guE0d{fMrRlOUke^q&}wr6zifDpRYpq(Sc?Ig|1=ubkW0Du(+?`6ilBHbKWGwx zm;_>CVb5MmqTydv!}7Y~-E1#`B9b+mQ74*cwvn_vVe~i6UTeT(&FO83$w?ZG~rF^Q=s^Y5r zZA6^(srpvF$0Oi7!B?<0wwNO3lF-2R4rjEG;UC(Z+`ts6B^elHE%U~6rI6B8xp-X{%|#>F;Up=Z|NP=H>|JzW4F>e)sM6)%MxX{!K$` zCRTLHsG?zPgXFvTJ72pVyBxb3yBNC`yA(T<52yIpDyOB`Ld56^{Xgw-{dT++eGsjP zO$6e-J4SRHfTF?7b0OD;A9=jo!8no7+|gJ4qU|X-QP%F9&1hhA9rYo*K<{kN%#wvQ z#-s+2UX+}`jAt8bYoiM;;jbOL*zZcu)?EK;^zgt8kv_1EXEWB?duZ1~f>V>$n+Cm2(X^CTUf`&zZu6m_X*tPSIlDwKta>5jV!(K-cNO-mK( z8L~#4y{Xms^Vm^In@bvwObEyw_9ZGvdOBu_Vt#gH39Np)bcy~ri?!-y3xHD#wnxxD zs_oAzD1UURp(=SZMuQR-$m1uKpV*y3ErRm}zu~L*s6cS@qHpt#Qx?;MG7BYySOmYf zS{S+umlE5fNuedLuB-JMrg)>hP1)ippzz47LK4;d~#PEl@t4jljp z0HBEy)ck8t1^o5p0=WWSx`ViGs5akrg;NjF58;zHBPHll#>KbSQBw+(iJv*jXJWY7 z{?G!SSzjD&O;b4uPfT9WFpf+_?%d$v(gZxDwrLwX?zE}cQ*oXdc+Z4Y7gkg_Omn~7 zqUg*1`TJ;YnNL6XS20YHz@C^uDBIyDjdAs|iJ;Y=&i*TT_Gj~F=8N~j8@fz%2xl{o z0Zq6xSF95pOaXP@vRieiGoK8M*LJTTjK-0=qPl#w_1|@D$q$JaZLnaV`H^~4s>y-e ziB?y?1Q&LWd*ARd6pMBKzjesZNtpQn1!Vb2d8OWILSPph4iZpD+d6b&y^4*i#f#!{ z%+@uFUNYdjR+xh?vH(a&u1JzoigdDjcBz$eX8S~tY_vbw74Y%3W@N#6T(zqWs8L0) zj-F$$ms4S$`|;-Jw?6K2$Y?q8>{oCh`**UdKJD{iL{NDUL(HbC}$2sXg*i=+26DI`coUniD8kh006JaS3WX zG>I1KO=J)9n;7OG`F*;NV2xfhKId~W-U|gWJxpJ(o76IGN5Sd*bL)?VW*hz|F+5G) zDBfo8b`R_0)Gd`%J6t?JB8OK1MpduT8KDZFQc32DV#6#bL0RbXt0X|W{&J*P|~e-Ycu^>GyjV)cXW`i`}0ND5j#f3 zB{DXVVO@R?N zj$H%A-%eL^S+Vj$U0q3K%vh$#p#$w&+Q~W340=zT2RXL_N!xA|Mn*G=Byt3?Y{r^4 zzgS7Al&~hIlbfd0pw>e7Rj2oQ5e;C};OARprmNX*{Wt$&WMJLV?}9N9Hg2IbJxp*! z-`t;vr2@T4Uh+nfMX-5flgtZL)ctDz$#Mv%9C0)2CyVdL2>=^!7 zY64g&U=d9NA|I)T5mu3Cn+w>s=oZN#**S!z|p-)!@HIMB|zQA_7&R z(TnGDn#je1v%^+~;b#&bSr$z{jg z3}Z41!#>bf;|OXnuA0mjqzC*>m+2@Rxt^>6txplh;xfM-8e4*qu}rFqLm4zDxx-Sz zk4}VRZ@XXCK4=6?U2hGY#g_c&FGA<8i zgQxYOh7}rb6K6v4tQ$(S8m+C=D=)ie&O;!L<`1LTAk5W%DRIU)YB7Ru;N=D*e#g3? zr0wPFxVXdUNN8JF1!NfuByZI-50{k;Z%hn1i;-wS5rRiQZ0-pZY-S~2MHeuUo2^Yj z^d{eJlG%yg@^H~rG?Q}9n6VRS8FY7lRy+i4OM{YRV1 zxLrT&@c=S^*TmW{Y8w%ar213h2Y_}c+udPyU@9egcHDC(_31ygMa>C=*6!iq`g3BI zGkFqj>4Xjd9Dwm7dsnJ_hZF)1fD4UbaqA!KO??S$$nU)~`3eei+s2NNgh;u~;fDyu zxa=N82tjSVlJw$)w6a?OQWo->7({>5Mp2&jJg1hg&tYRA>~VnKhQEPVa9uU+jEmVE z!e2)wLfPaj$;!)FNP`UJQ$Lq5?q5;gp@nr#%SdK{>7^t2DkTP!Pq1G_v;&-G5YQl> z&lqBBbWPKpZsUsUjB;jIpF5~zc|dHC)aEGnrSZ959e(>ki!31B%+N6HaeQB_VQJ$) zYWyQm&tA`Q9(?voO%4_o>cGe++e?Hm+a7`%0nzRSd(i}H$b}6EPTKQE@CFzYsRsbV zO<-u(8f;|SEwdkdm|(b)ycAz0jVCpk*#WZwrNni$LQj5I8i)u31kOC+)C8=_7SI8z zm{9S0IUlD+h2^)IkSo0gpDg!)LJ&*>h2)^n`=X;&F~=AnxpA{=&Cz%*(KXyhsG)Cg zJz<6bt!eF?Pi-9vE&=?=HY!IO>n-smT_c@)^f7J&b(>Oamr-k2eu`*EWXTbSRQ#ZM z7^ZfOn_=}~jWCz(e?mYp)zOn0mzR~b*2%O1>i{v-D19Oder!9v#p(bFlzyEx~NR(#3&6kQe7&=O>N#+a8#GMFS^dilnJn4 zi1c4$t8A)Fs0-6%6pW>|!n#jG?2|=n`QGwX1Q@=mW@?)1ZoW%rp`KM|mpwrvJcozr zjVBHB!GofNn7JM-@U@JB*%4p^{vgCUW-gL04|Wk+#fMF|o6lLgg?RdM5#y)h>7~Oo zP$QCwbfC36|2?-qV+sO{?LOw(9AKxw^Mz;2#?X`Bs@fF`70IW;616T3O;jHK>076j zgi&_!yl(I2n~bH&cZ2W(mPN{-$yUBujL``fI*dt`cA|*HYsITX?KB`V*qPrnP!lzg z$BVLIXfd(cK2cr&5D`v}`}zoO>uulmg|$4vd^@&}pyu}>_tCiUo7UUn$U|8PxA_cQ zxl&mqo;Hd67$J&_-A3^G32blFA%Smy9#3&Zs}vc-6mH@A;dt#oJTf0d$U0tefBUi( ze2n^uX_YzV)8BSUNT2{14~iMUsNVt7BU@$>my~q`!`vTqIr4#?RAWKE5Xp34odH0= z!2ve8S}kaCX;%!mf!EYJ`kB>L>;Ze+);l+JRB7ysO3!YJXV)w&QI zg}xroV1rIv;V0Kl16=!P5N^I?y;?92q`hxuB;Bud3M|+{Ni{u@&7bo-FzSn)l zY~`^@>=K}BBQ;}Q+#XZu4(=Fn`)2m+u)!k-G_>)UdJ*78UUl(<>*P2>@BVZQV5hAo zWdV$`;yyP3TZ3{RTFtno>T&DA(sXUt+4TmfK_BXYdXVNN5I_(bXG|D1LSh^9VT;y| zCpA&nrqT^h!G~aZWlz}4#k;5_=GaNjYLL@SqR-NUh5~Zl{)Hw@HTgsK$Y98DgS&r# z7rj>}&o-u{u_3iYVfUxYv{`wdIo8er;YDxyMH zVX!28fL8)SiwiLX+HepTd@VBLGF7d<_zh#^tukHsh1-u2Ye?|!@S~rvvlbOZm;8p7 z_!SdfyIusPt5*6}RMk=Ui-?i*|lhrKy2hiCCH} z{a@(TFv_2pG+_@}jHS$RHm6yAp=!JK!LfKU&a9(#Q(Y>cnBTL=nW-^ZO0c1BH6%jK zZw3{1(BHzM5B(T|nmeLVO=*Y=+nWa>q&%LQN!wKMn0Vf5)FMS|o;K+Yr5zQ#$P5 zFg~G|Y?1Fk+3ZAhIV;!-LmP_7*dU&ibWyQ9Uk-$m(!wHBRdOY90tYPT8hK;Z@ca6@ zJ1{})hP<-4q?DDag~ja-ab^K@&~kA(pdz!`Fryzo(ZD{WdNj$ZHfJBtiiN@UrPkny zJ6cCDpFD|>U-B`ilxv1+2wOV;0vXgig#$y$gQ3>PoVA+oXIybK!Q@rU3#xoj3<)7B zOgDj;Q^M!^@b;zl1c4;sl!>DJTnlnw3*$fQ+6Vm<&Pzn_C^Jdb57e?<=#d0m6E15i z9iK1zIz@_Sma~f2t31w|4#q}!F53sc-JfDx&3kc%DeNK8@?!QTFp4@t$~g*>Hd$au z_?_Z=aec1!ZeVe^8ChBqD6XmTsXTxg#>5tIruKxle$imQ2u6155Gkkv?^5x8<%CgQ zWRml$ff*laDKm9|_n!oQ5uNe&)qFLesnj~~u@dmO3tchZ6szr|t(^UX`cNRK3<<&qNnWx&VOqIInKK3wkQr+F@BM>gLl1 z=JIi4g7!8DJ42l?txuQp1oU3_8dFjh`ksh5Sr=A#D)oO*y$>~nyptk=jLuS^RubVP zk!Sv+0+0muLTV=LWyJ!ND~@u8?3-?fX7wue?;2mEnItj1YUxvo&)fhviuaF2Eh*x$JdD-csIjW~)&=oKD=Y@5D zzWA(k@|86e<`*}GkT9?1StV&jCI6!vG@n`co_ z?y3XSG8TvQcKAHIG`4%nm|6R};Ry3Wmk=OT(ciG+uh$H!}vG-N{$SsUD>zWAl!;I-|wfQ|y-z)@~rFB28`08RtSLizn}dG1lpvbu(MM4b2fdt0Vj zMn~rDo_`bcozzlB&xZ|vzol?Ps>$i)s}&HsCRyxp*0ZfjP7MMG$XoT$dCzR!Rad(iGWZZ|i7E3C%M_4yu=Y2%y zDD6U}$xYoHzk+*+qZwr=!lY$84wBMXv5FKJC98E}ZX|&~z6&WS1_3aNa6X|};8wx& z4Amf)I!IiBKA0vDf)cV*@kH0G0{A!_=D+18Xfas>fspz;a!CHr?>!(w$Q`|@xyo33 zumRun9>55_n0bAxa{?lGnHkyH8Q%33*6KG_EDZ{0kBZMP#bW~+o6-4ThIFBV7Bo1c z`T011(VUflrkCOCzsx#3(^>-L?FEoATY{eo6yJ4-b!?rbcVUuPPb)9_MMN5l98cuO zP9Q$(@MR4^4BYsL)A|K{a(32OCjn%{MMXYx*X`|Ptxz)^tPZ(TsrrEX%R(^Jtx`&sZFOlrsKxnJH{TUwey9>m{ysJ@I z{AAACnmx3%Ji__ZCkPP`Pr!+35kncGdc#)#c;O&v0^LCIPwP5+0Zt}p6>unz?V|(g z)WFOvv8;bnzdBHBU% zNlF%UbQ7$ia7qQiBkDCK^1Kb|E4p5#9oE^{msLot;F90$9oLBIq4aptx-FA+9b3S0 zC#Y16$RCtdL>$d8Oso{ThTSH{)~N^%Nws5ffvoRZHX%bq!y6d?q45$wYRCdu(ya?SFth-rGjSg|D)B0Xn((j%D-ITWgS-J z1U^4K7Z~4)B$n~r-z#4P3;o{S3#RAUWaQh+V?X^~Ir*;_Cy>1=jm|NT%IE;V7BNUB z2QYP_Ban0ebb2ZDuf-8b5@{=K_pb7IBlRZifea|`Q}`Jvp3d!&`K7BC7CLGnQ@-xj z3z;mxu_WQLySW6%KrQMwjL0}jj z3K;?a9Z1D*$6XrJr;udlV`S#;T1>GF;sqik*6a&xSQjQjp@}DvMrt2UFTY_qef7cv zU^;Hkn5|YPH1Q>P1WlMcTuxuNu#nDBtK@v+;ABV;RTUiH)6Y$u?{l7-hzv3b+}PS8 zdQ2PJw(+>>Pz|~-MYb)svsOcIG-y5L!9+jlg7!ZUCD^H^wdnUHqGXp~9a*G~)cMp; zpdaI6%QV0vfkQIP?JL}>H>Gk}Y7(g6W1HZVoSR)Ox2uL&7&e*>l_W=47?@pNrN8!Y ze2h>NB-lcnU8S9M{0r-xXUl@kMM`^|tAKIB4_{H$m4!lWx(Nf~Af1sKV2_8_O zsH`amIy8j3wr-lm5)_$Bh;ib9E)ogl*tK5tLt_FHpotu)A}3Stj43O@qpO{cO7=HR z-mLS`)=k{)C%cA<>#7k+zNY^OTKX-DgN=hIM*~gouk5gnIjgK+ftt_7lCe7`CL{jy z6O)q@g*~(HAEF5J*}&vvAUo+_gF(=QvqCm2d~B39+mG|O<49~0<#(4_uRu5Ob$Y7G zSak_8R^xF#8a*&KC(O*4B#*!slP-z=3}1~2iKzp{MnTA&oF+V2+2(i#-F#)9GyRn% z*#s-eENNko4yKS}Wf^vbG`UE&hQu0aD`j4!?p6eYIkHH_d?JxgK1K8}JmZ-TdA(k& zGGo}|4W$_`&rD5`2i{bW^S}ev>kUma9-a|*u4nHOl^{0eVG3l|Bjxqr6yx(T-dT?) zB1E>ky`&d=W<5;AU0Wg*a$r2{xsz~sw}Nm-F-@i3CAE{mP60+BX8Z9%@9Ve@eYBoO zYI{^0G=TgjVbuZef(LHx(cB7vHhNe4Opwz~fSY$Unvgz+w<21zi0K%)tOL?8%& z>}Cc*aE3FSo*X#4lNOlS*&uG#5-aVjw6l4oR@@}{Buf~Dv!vDflnBdtC1=5sqt>!d zI)Tpjt%Iz);hp94|JLdAVgB#E>IRA+Ig;-r`#us~9nh$%uCDOn?+ttCb)r0ap4F1t z{<*pR+3ZP8b~znmd-u=jC+4S7JtOPOC%}UL?>ZB&C0HWS_-&WWp!=xI<6^rKi3B{2 zAeG{hvOA5A2;*m+l2qtzkESeKC zQ%a@#RlRtn*pP}SXr%mKIemJv_l>)s&_Qxr#|EnVImHo$T>qFT!zB8S6y|~4KuZ-n z-$Ir_$HwwtRl_2jFqc$@W`+}QWS@%eZafWT^d#9YhaMR&Ib_Er=J$vD7X7tR-*Egd z8@EJv>o67qzGUNS*!M`{)C6M>4uF(XmqghJ$x{m4r$RPjFFgtpkqWy34nRgyv8>cS z$v#PQXc+G1Ci|(pwO5Eg!FO1^@YLR$m!A8|o=-d!9gRc-!6+Mh>cY~^FMs8^hd%LV zfoNnj8s(A}lK6B%Teg&DAQd(>6FwW5nC(6j>FZc!vT_McI?a|H$_AXnr`|5JY+8B- zHs@$_*;Y<(Aj?xLldEKR+Ge*J-NwsEX(mmGQ80fJ$h8|{H^ArQ?bMvLV9%T1+!Op6xMY8r&Pxt_ z{__E88@p&&|Iut@o!zH|;lQu%&;=E)j zm?yhkV8dqThFeCFe6KQepb52Xdbx7~Cox#XsOX7M=-q# z(1?)Llq>pj=nLVIaCqd~l=>V0pj7PdVE(blz( zlUtVA@;JI#PG|`kmQ2HdS<>{;_oA9EFfb61gb|9KLnIji!W*~(cL5xS*e_&HXMuX3 z^)$@?cKW}aW~+D(r~R+OX;W52Z>*nYRoUGV{1;$tWztXnH{N%j zi(XGX?0e`T?kz@o1Y7=DKnW($$f(#fnbd%<8fK-mp=lMpuIs#S86?5&usofhnLr|+ zd+dt$F%537YZX?8uLRp%iJ|2U$OR>kTd^Xn8l^R?|6c3qz0zUo^#u=dxLHuE5f4k; z5W1%Db5u!rEJnL9>4J3+-E0_i?2+=z@`QGM?T3!!WE0wnG zDizqqyQ0kxc6EJy)6#TMlNi_FS~?l9#vu!v`s*L+zv1JR3Nw1&cFP;iS1LALMEBv- z+IPyb3Mo^pAAs6U_!V-4@LO@^vsYs!WYsmGf=y614_RoPAwSTr51>W)B_IrL^@sZU zLM#EN@M+71I7Ts-&3={jCrKDmEjC>~p)Pgq2TeMmU&s|_74k44y}}4s3ygz} z_`I|mc!dLC%eM?Iq~xeaJFTq%Tb3UOJ$OK0!eoqJDrmL@j){C$P=~y$})T;26iQh28gnQSSr0Wgtj|J&932v>DgBCO43$%EETVX@% zclut3uh$?e;^#T#@5XsEozA;;W;EcjVS&;sHEHMBRe|an+)lq?n$5}8$=7Y7zB~Df zkdx84ONHeSe#WHH)3*i3?@8P<9{egv7|e2JYGY&SqDHl;vj4{#H?t%sgeejf{lF7+ z9e-Gz_20a(G<{?3{>;=RQyJ_MLqi>iPceU z_%Yci7DI*sjUli|rLg}pNDK^vb!r-LGg`#I0oNgkXq%)}eksfOX9X5TC5aB>n5S!V zL2!oOAvYcvxF!t*pw3gnT!uyZD2;)>b5c$ywl53*HLn!=?m39=HOIiurYQK#>*c@)F3qdq@c1UQ{QUAeaJYWPt+MJ36}e z)?1%Y?nM6ePUSz0onhWHW4GS=_)GlCOOo66RwSRk4zfTZD;9a1{HW){vaL;S&bO@L z3x~g3w-iu^t6c8OHNFlQwISlePy%J;ts-fn(y$sGeTgl^W^To--&@m^C-%pNpBf$e z&yC-T&D`=5UhFummml9BOG!fAc^gEf_MR6#v?9?XT{BqtYCHZyiuJ3Q8V z=(!_D?ml|-Zl3;HI9#pOv^Vh!l>YpUH%em8a1<9UHuwybZY$wW$pbL4iniiR7mHv; za{BwxW&G|bp&%TCV*Q)*vwKs{iu#I`EB_g#Cgs-8Pbn31BYq}Le3#mm7n4x)P;JZV zH^q!>-s78O*A4j;RGWiUh}jKP!A)~n zStB{WX2kBiGj{Ncv4aO=cQ&qC7t0z^Uq$TFH+XsJ4ow|G;zdt8_K?hFi*U<08a=&}2JC?RnIh&s> zOj>#}D*&wmuGeB21vi!|x9kddne3LY$Ima#{%sU}Jtqo0XHS})8y|P~CA!Wp#iEIL z8ZJNo^|4v#ue+n@^_lkYdK4z^*0Mv1Xl&_xSEA4Te{Y?B@NYs~pX?q^5;Ylo{RveE z_F33)T`B@EN(432OGWInfRVJu)*Adou&i;Q^n)?5f@NzuL(B=UG|&Elq*Ju|O&78t zWMn_fUVfP!dc5&CQ`xJpvYU!Ukpcy84YHsjzfbZyQ9_E1VudcC+i16#3ANJJj1cf0 zp|Jl-V@=czaZ@4i=9u<{aTJDq)1Y#zlUC6bIY-GO;Gg(ObD5Q%b@eUwgfs4nh8&~K%`j(k^s6CCh1k6*r zicF{LmUQn=*q=20C5TPQVnWgicGu&N-&Vcxu`2wrKY1MXkKI_kt?{STs^k)o9)`#_ zo@5=^k>pL!DC*Z}0Oy#N`5YK1eP3 zA<8yrGN%MJ!lDgBRGQgd#;;zthMTM$&a_vJn?0DKlDM{g?Wk=O_D>Fp+9pd#W!Ehk zWa98eHWvz|EwdR0Y!?a4Q5gdZ9J}|p5(`m%0OAIBjn@Xx^xXXcZ^Cn!UFz(7wj0%V*nI)q=cXYX3P<2`WiGo77Gg5N&d z2|pWu>~9~Rib4Gu)cBf1BL50}0;$lfp$hX>fwfgrM*IOamC3v~WL4_W*Pp#6J^OLS zc-0!$X#c+E*Yi||Ju87{ne^-@8rOIg7^8jE`ciUn3UnvC4^avWJejF0@Q+SGBz0wP zWyKQxwFaSNZt|E2koI|-0UzLmOpXiZNkrZ57ytlN$pM!#IjFf9w(Tm{bBkKV#zrO* z9&zaDC|D%6&141U*J&DSl*HMItf}x@)I3(VM(5id7#UqR9wBTi3wX?{(Fz7 zI}}cgWG5ykvLlIbsN3Ti_w-HdeI91HlDE6tTgD_d8GmKrb~f*Jb@ccETg>h5?CSOP zbhz9Lj=eV|kaNB*k|Yq zAi{;Tq~Qtj=tik@1=AWGLaW{@WoVuoZ(;+b#Py4s368kM5@byl8?a+WQ3>}Ok?3eN zVt{wmU}iAP1s)3Owfn>Sdjmk){+xy??|7ze`rjeobrwjO@#V~B=h6?^0()-jsH|ZT7)(8pd=v|q~KVAJt2@lk9Whd z+g6KMD*<`h;3gagtbG}4Qq>uO{50120c@H{TV2z26Sf-c$h}v`14!4&C8kb(SKP0P z4oHzg?3E-b|AJ>ZDlLOY$2n{@Qu@&5v~bDrIA@*PN};T9EN;1N?qLR2lW1st4HNpS z^V(ZqY1VaCfqUpVc#}|K>3&M|%xiS9NT>W3{_yk-%>}q{IPj<&*B*ouYw7o88Ms%6 z)R5ROXs0#O@gH74yz^Y@Iu;H(#J0!8coZmWN|M z?BU5x-bSbvLv6l^4+SZ{@FJvS*Kg~~Oll@NW6egO-DROre0luoP80Xn04LxrkUty%>#fT{xg5~Nh;3a_CFU&9CM#^^iKs%+h^Dg6D* z+T8A`DsM+>bH8;B>xQ^(^e#l*rf@FXJyWwgAsjVK`&6_4>>f#7td4z=o(OhaiO4%% zgMUv?ZQmowJ3NmRu=)dDJwhM11^5&&aiCWVhviu&& zD?AC(^|n4NNpG5TxBisfPi3n{xmF)+n5~Hvh7R>XtceNPH)lxx_b(sYs@+;vi!i8- zyRF6Kw$`IoYxOgY=5meK)3mBtZ=3%%_{=9YyAY#xEZQwsgztq3kIw$(PeUW!t|cGg zyhW`M!|;3IX>xSjHfro~L#<6BlIBI>NvNvLxeA}WId<%a5O3UmB@ZASO6!p2=LyFK z9gM(h;wvi-Aa_S9fPdfg}7 zu3jdSAT!EqyNZ#<$Yf8lD!1&k<>iDgNJnaj=wClFi7e664|oCw(zFYc6T=^R_sGo4 zK>ivv18v`xx#20M&mOZe@~UJV4$eK)lYIveIw`aG9%|#zi8gn0H z731{y$R3xw@k;dZ8=w3jNIis=xQCEC_*#rL;`}QpI=CZFihJG^vV3W-=-^|ZbT+>A zwfo-F*?GCM+t>L>XXhJpaag9irUsFJ^<{h$_nz*IbXm<%2>qcYb7?>F^M0cg9^2>uqneP1J?jHRpdtc+Xq6>-T{P6tIPxN;G+;ZRilQtE> zYPLN{0MXq7gzkp+AYZ#T2Y9~I>bnP~FH@DJXLdE}hG7&X$nsgKe;m?94vnBdY2c9J_0e8S&8FE}VFHoPo41G8$ihHTbGQNc^ZigLfG3PXcW z?hjm`I;Z%K>6&3`8@d4mSjjX?xRE@Syr5{VAZmbU4jA2j_%~|kU8k%XWhNP5=TmNlx;x8es!h zk$0_9r~vd~E+OL!aFCLtDPf~L3Q0n{Eo{!Civ10Y(kTyIfhro9#|e3m=QNk7@jT{5 zz8Cf+J^kwHa(;Yi99Xg<=oYJSU5{6*c|KB#_DEq$3gysA>?O>stgcqBNiP8Ur%^5& zx`|ddZDTdM8Ba=-s&y+_VsZ>o%ZW%^^6eysnHjvzH_A^6h#XW)oSx?6D^AB13b_8#hKC#&S zN8KN%A^Z+Xe@d{hd0{M>yh9k}|4Fp8vF*=Dt{&xREJ@^9a&3)FJ{mx8lfU6rU1>R6 zDEeBcTn1gGxv8~bnk<*4e?4npyU!3_msF6GAXXRZkCVg8Cz!T!Vv|?Mt1IS8o}Xa) zzmGK{`i5`D(5Q>J8C3x;x5%~0>?6#vzf%{)URAI&2^pTP?&$1 zK}hpB_F!YCj=tv-#T;p&^3BqCaWOF<+H&L3v-~tNt)-c6KLe<}uQBtSlgS5_a9{68F#F@VkuGOnU(cN`Z(?{RAB+E&`H{XJufw71 z%+37$djlS)+&eV;*hI+VML8~WvTijEcyNPbE!;qECrL9uk#cx|`^)=KW6IP{PkvF=2|f1~Xo%v5skbc|=_bKP=HtfX{4}M{m-$6SR9dOtcme zNs#VbNKwW~RyT}k8bja0>`bP>R14P-CK}g5R02R9&O@%BgE|DIVNQ#Qg1`d21@feC zi2~om3el-R(nyYj6mU(jbFh*kEBJ!C|iHW+lTOO-|i- zLKo>v;*I`tVKBYin>rplHoRg<4%T7gcFg8FPyXiY8?;*ODoJN__#QqwzoTf~L0;?2 zlFnXk&hdnCt;%WG3Ksu^O~_U!ViS$8#3o{I)-+tLP4@6aY;rO-5jPE(xQx|RuFZLc z)mdJO+HZ6?oASVB`|_%}dED5GD9Ih^Ug|yu+lY9=@}L+>z@N2~+FKcGg)}`dV%W|b z(9Aq?Pno@9(-}6pWY(fH*egIGtg}$rC^Mupj4}}#qPAxk{q@saR?KUfK`E|>My$f0 zBm|m?W*CXs!HWygfeDA^Sll&~zIm5An0IN;gS#G~MdU5r^Ly2vXm456`6=2aXp zFQbI~#g{rdzKFx-)%f^${FPT`e$5uK>k0_#(JxzKP1~M+@=D+&A~8$oh7n>P8{55a zys?pAJ}|AEoY;MVY0kac_`c=*%yD;i`ncGN{ZgdK56*E{4ystQ)mBL7I-813$WAm4 zbn-wP@Um06^dJLcLOULZ;796~2DlA&R!(oNU;VwY2ghTqzpa*)_r~5h9y_tAszRO~ z^4_6gr53h%=(15V%I#0S0gTMr<{WK3P?aQ|I=o5iRWP(>v8=z`ExWH&N&xQoR2tvZ ze{B2>nzHEslwUrUW5Z*+C*sLWByngat|qcm(B3*KLi*5(MO)6#op9(-g+e0UpNV9; zW)5}7!^g$e;u>6wTHr5%S81EJW0gpTiW*(&>czUSp|(ec*gsgvbQ z{Owv(M_RS?ruOCp^1afYCtszvS+}^kfre|fsc(RzjJfUI1yb7k#cN_Q>{lUv2qT z7Uvc@AeABJUI_(MH4v&s&?o+)Sd38LE@`OU8+dE}gwI)O;XR@#lZ?Nsf_h+Y}&M6#%hz24-$~Q+;YeaXQt6nU4iux3AQ!P;FDG z6|7Ntecwtjb;YWe*xQ|?wMOz}8=rPq{n4A1S)Bk$9i8{Uk$m?D); zY76pWMO)K25&{|e5LaXX)1=cHYP&JA<<}-%O<59g;B%5h@TVs=rpV`#axFu!YFA(hZB}#i_bti zansT%JMGv^TTRl5Tr92;m={mL&KCW#$wz;2t z@lpoBUBE!FXhbq>1*qxuF6z}+=^e$Fp?;=mV z0^adO`tgraN@aWz$|%zJSt^5m`bA2GcrRY^j8b_awZ=D2;teO6qTPT8H#B1eJxBT@ zqW`mWvk7HjSus=BzeWdAw}sGBYocp&&WCdY8q8`-XbGDu{GYrIskml*w>P4cuG$hA zt~9IAfi7G$gt>|+P-=}%8Y5P7BvJkKOS~Oen3YX_Xrub@SYtjOTZx*ufKIxglK5G= zukm#@g#x2Lr!%dIYghZ3Go-dk2AJy|6XfFmE&lnNy^Wk#I+xzDCrG& z4xDvha>k&$!Y^_BrCPSdPO1%md+jyi@n5e%y*LnAt8QgN7htigR~s8xIRa&%L~;mq z42w^j-<)}>{dqBZVZE`T>x%HiqD;}&*dwk~bB=Gy7cuwdB*g_^w9(uz=Pi)X@;W)z zg#9FY^oKW}RJEd6SzkA|`HD`+gx@rqa*F>7_45%Ohk+xU`6TIg(7htHapnAZhQau1 z`_5ls|MheGR~r8hMgzTvJ?LH8FF6IfSXolJRqS>?VeHbY|Gq?BX$=#T=?#3T3})5_ zU16n2M&kMLb%`XelwZ@Qx;@Wg?HoxJA3-*#iV5Xg!*v#0>^q7BQ@6v>208)Z4e7%gc>XQy_u1hjqfKj7sY_Y4?E|mEi-|Vem3C}py?#osYZy0T2m2MENfn2r< zd7(KTOy%?Q=s>72srJURXWv*`JnOAM?<|=&e;^qAz|CgmOM&|j{?dUbBuQ>c%*C}l zEyTDI_9XWY*rZs2I9e1Fkr|f>ZN<1`9Rs0(dJeuZi}Xk4Cq~mYIQ;!V!*dC^rM-kt zzr`;sKs+j*wEI&270vR&3;RHFP1ydB?Zsws79!)j_Tl$TS5nzB$gkG()h#eDfg9+6~QmN~O@c;(2(^x?zPxWO@#tb+~v zi_O^e^z1vthp4qXg;loo10zWz%(vvF5P%*UZtQ>+t1T;&nmcdV-;#MMD;Fu!Tq!UB{dXWxE$_d0aeujZNKTN~ ztdfuqaXtldVn%b!^BA6dBWr0^1Q<5>tgd2&{hDo8h8i-lk40h36}DeP?2cbRt7)t% z*-dBd@xhmtT5;9e)8jSKEc{V=do!C)p6 z7#a*@fZWq<`GiZreng57sw=f&O=bm|Mf*y?ei$|E{RgNX+)JG)V*CZtz@Mcw%;O$Z zh$E!rUpa>D7Q`>fa$wq`mo#W5TM@neBQ*DIY*InmSeKMzg!>@NvZ`)}b3JT<5{JpGZY>dnRnuAB`v0GwW zZ1?lh>!kan2PMh2#ZYH44p@G!y`9|rdh`1%Y&kf#?b_{gx&1zC-;N#6hLNW34s~{R z-7B`e0T;Sp%R?HVTky&9@yV-P$GXmySy}z)W?UbPu$Z^&FYDy*dm{5VTtYt##aX zEA8+LB%&QctB89R<4-B11~v_BjaRtQC>;J6aV@tA_A$%MB=SfVkm<5bM6%XZm1onxL({d4 z5%P1hN|s(rj#3%rl>FY59j+iB3LT)PT7~AgVxKUWYX2)W{0mWb%iw8-Edep?_Bi@| z-GRQYJq#PA!}BRz~|9dEO zqWP9;!hrmQ@HSPt^*OtPG@#@P-2STg+f_Qc396=S`MqH4Aw+G{X>R;1O|-P?aL%Ti zGzz3`rBGb+^_!o5`sUr!GrM-pOtU)NJUDpQ!*>l1(h8)r%67l0U3mKG3&XJk=gu97 z(Qi6}5B<atzKg8^uxuwxYqs{LE+Ef#k`1z_0H=V^Z3W z=cIjW+WmwiiCk^T^v5-8spiqii~WMf^QFZvfdx?GKf{Pk%_V!I>|=0>7d_v~L{hUl zbY{sT^hY18AYm!S(S+v-t|Oa+i5WDA=srhUTd+a~m8Q&P4c~CxsNA@CQu*TVotiwD zc;H1B`?PD}UeCYB)BowfZ^F~^v#DpME6@0kUi-zsz`0S__Wop-0_Ue3&rG{*4Iq^t z6(xd!oVvw|%w|r%N!+h)W)HO_xrb7t3!|e870&rGP2>!J6TcZHzFT4yhs2RBNI$I* z50cL}HBNF~)DPKKb4dPIAjA-sbj1Ms4g-&#BK&ROHR`WokfB#~>rJAw0e_2C9^>Y( z$VbvH-AibI60@E(RM??#Gzy05V;SM6H&Mp2Vw>%DGll8@xtH5|=7 z`JrsWGs48ecVkt{tOj?bwY7+!w8J6t$OKjc{Sj)LKTK)VNaO$tM6#MyB7)^TM>j~} z8%S?~G>~l+1KC#aG*^xaA=3lTRIJkx9)FCZi_m3O#H+eaC-oxUQ{nI;9+841sfQ-z zwqlv7-$QM9lq4?|dv%)%)p_hAD);Ahs+PzJdHD<+$XU$Qw&sVr#`&w7!KBi@FNxe0 zGl{*b7FSP2?Q3DbB(%3pQ_QtE%Z$Kbiu(eeMaV6bj&KC9*VC#yLFswnxN_>DedFn# z{=WX6)0ZwWNgz}C=k;{u$L~Hmz7**03i^8b5qp!*kH1Z_3WZyE1ROtBkeS}{>4uKLkqP7Z)x zLJ)!w2e`V5Hq*MkiYK9PY`2oW(YG$ z6-riSZ?kDaJPWC6@OZW)!6Pqy(+a(GdKei=6 zuCA@s1&Kj>l+Jd1g!UY^7uSh6GksE+>{T|YP;vp>Vbv-O+6&~Hm?Da91=5T8|W8luUi&c#r0!fLc@RPl=aEgnhVmo{?>cGF&x@Tp*Lq;B`%+Va)i z+NU??_fPkn%pKgW1w@a5?^Vj)mWdE=ap$)|R{9(dWT#$ABmV_fXD^6x677G&=V)#( zVE8^w7#|KxbDvH+pMC7H#&0nbrABqIoc=$x-xgyfd!!JLal!)Ii0lG1miXL(irJ7^ zYf()bw65#ioSEzo1XV$U~orNx2I97R?WW%jf|KaaoV(c zRf799rDr*uxy+q=<_lz3ni^J8VDt^BNNld;l3jjv?^}QF=KgNk(K$FdIS@vR>gArU zfG4UR7)jg#*g1XO?#Rr@K-j8JmFm;qtdA^Ck5%2cTVAKBmujY2Q?6CNI>iT=hWZIV zQa4vm_D}`6UAh{wo}o&@&2_4(x2rR#^mI)Q^z`^G^}-MxLi z-923cBLh8d0A-hhsewq)-G}_wXQ3uHLroNl&IN^LGs9R2j6s#K-}8BS4oiojPo;C) zd8T){I^~eu>FNs0T}qelofr1|Wj4^$(>L1J(=)(ENBtg;%jNO-M|Umsy8Qj4yX1$L zB7@_L@jkc5eVUL)Q& zuHRi1T_@=45>><8_T><`0Mw~}fKaiak~_aAp`|G15=FD)K8N3>B3coeeB1JCRd9y5 z-Z=3H?IDxoeV25Aw@6lK6>DcV%=g+p&_Xn5U|jRjbDee~2!k*mJqfhU6#Zi4r_ZhZ|MDoKN#y7~6?L`yO-8^+!ihFJ)}$-lSS@uaI`f> zeLkhO)f^i>yLm*?Y$MdLL`JfPLFz$BHtZThi<`vWSH((J6`V>H@X|v=1H-Pea}%8# zBKmA=4P_u7E0q?p2Pb8wnVaItSJyUkseQB(=_Hl=p80WZ5mDcU6Ss7TKd}=NF4)AW zlD64TKn{`3^mp|Y*gZ0q*JqDh$6H{k>+pCgx7B07<|!Q#+3OGS2#vt60u#KY3xX)p zf{|P~v3v&;VfBke2G7j&<>mHHRxC=))-6*knm`g*>nzi24b5B`-b1m%&F~q?*|yeP zf2G-Bk*Qp-mv>0x(m4Aj`=({>5GD)1XK9jNL=;`zxNo*qG-Ay25VcC;ZNIEVu8L z7=Dqa%jL|(Qtp$~e~OgNTi~|bo9Mpx3HKr0I3xMl@3HR?rc9Ijmr?r#mJIViB2wod z-xla2FgP(rPt2jh6;C!pDl#6w76>^mRDNP2-5(n^j1I3OH8hlRcsmSZIOdQ&PNzq9 zw0%=0dD2ap!@iFG#bi3|l6yRWItEx{o*vniPA3=pnajzT)5W&?9^ZgCi+72(&lZva zdbz=t5u&{yhB5^kfxQg-4eeu-vB^)zCS&j90Z~kI2rd-0EL>uyVw!J*Q~1Pwi(Z9W zdn=sWWt#7YOW-VLNoxLx_!jc5WH~68U>yp{oSbv!Q|!Lku!0cVy<>+Pb>L+y2D|M> z4dsfpYf_EV@Lb#Bwm2sMF(=@0^m1e6KI}U81d%ZRD{b054p0&;aE(z-q0A_fj6$B#Vx-sNuA9((zaPAR2hyO#{JN9 zWUoP6Ub&9HJH1u%S!g;^67DI$ND#kID~7(sCtl<5H~d>ugRp1lq+s$}D?0r#L!8^q z7K)QjzMnQf-fr(8=wRCRp6kW07w)5w^x+3d9R46lXBX-C{aYi})7N2ErL#R@N=c5s z$m7$CsqiiI3ixB+V&B5(kkl(+6#SR*$DvSjq4{$Jb}AU_(~>jr4oz7 zFIZn=K8ki*C-iu!gw}pv(BoR^1SQmaY+1n;zXw4hK$~-i<1OTNwS<3~kcw*(0;`(z zVba#4Hqc`jXE7q%g=GQJ;ZpN)V zMp^Nkew2=@f@U*8$EY*YB#rl?W?Yr5bdpEkv;FlvZQ6w_d>695Q(I6&vd6|7vT=-U zbU=33jW^y9BSrpk($~l7c;to~Zu~_$zo+Q&-0JD*^xRYg@z`x1PZ2KM28YF)JOTK| z1HZrV2|;}yr{g$WP0{(>4!Mw1Q~bHWEsj zXG_EyiGB(s8$+oM&hLI!;L8J<_H7M;S}ue9v{O&$dg3*KVo#i4aQ!v744)P8S-(fR zQq;Qnpe+Zb5kiMW`&Npo0{av{Aw$(XsIGI?K81T`dqQqB-6BmqGQoRn>AXhnir~U{ z=`=Ixl#bz=z*TU1bAo0%EJ;?gxO0*VvWzxOB?#S|J z5{%`U0vPY+{80!)cJj05H0`F2bA_b~7nXM2Wbs9R2){%ron#wff+SU@Y*J0}TuNzX z`9?AxXE&c*0QrtW0Sc5VWzQ7S;0JfzB%jk(38K4XSjCa&smYErlW^f>3iEWFJEz`B zJMug=S&`onz#Fo4bSb@)nY8=A+CIVd77!=^_qG%Olf;M*uQf>k2~)`-S`BQq84&FR zHdzRW7z--RcC*mkQ^TYn0;_F5sf9p8MC6o0z3I1oK8I`NH&$E@`(W_K+b*0td-H{J ztlHD~jUGoT<>+C%X1tn0((THX)*!i?3P*$S9jt3hI`5-(=ER zW75daS6cex@*B<;{<@k-R5y8C{j1uz{ot*NWPzJRJ~#sF%`}%;=UVb-m4JFv7R@PJ z%hBw7);ijDJ<^p8UY&~aDzHz9e1A_q-_u_XbmtRFcK~?eW(B(dZNPFWSq6jZgsCM$ z269$`LI_eV@OklBM4Jlo|JjKS4=CK_$~IJQw}5!9c3{teleoYPZew%M_!a~hjzo;1 z%+OGVb6_iMgT2W8{I=SfLJ6t|E@bCLufD;Ln}dTUCd?4L`F`iZv11ot!+iVc4g8HA zRg{G|vRVPO#x!CHI&9VrG z?)jmifmnL-b&=>q2Fff#nV+-0;>gpNB*HS64yRBE4AK@)%Q7m@UXQs9zA2{0N2Wih zyZ!OO^LJnsuqt0rW0UC+Ui17)OpT?FzU~|quTxbHNbTB;9r!aHG#*nG56|Fzf01MyDfHckil>It+dL*O_N^n(J3Y%8eArEJ@ zohWf88wLi3yanay6LEiJm|MahlzaL<=It2lT6IP~-rdZ z7tnnEq^9-z8prSP=*C~okNA6?J#+bi4tJu@*MIa41B1K9-uTA6>U2Au4pfaeJkAbx zS7%qc*Om2k##B#-)6?N_db`z3k1IB$xSYGw*QBpujGvpOx3Dk6(=SN3OA^CJ1M%~= z4;Lb=OL(^S=aca+a_J?5o;d<8Mf;+rbrGS0KN4rm2~X-_9UWc$-X7TlPa0V8yGKKQ zcvRWlHyG^aj~eiOQX5cD098P$zf9>}-F|H{5>9kDGLcTFHtp}rXe_BZT}~%+Zh6q& zUVKt0!_(~>peGHwov}VG-48BVL2u{Tr0VVhomq=6aT9RE#N# z5=!w8odR+=krGe@%)w3IxF*_xlpXn<;Q6<+C!_PT3#Tt77JmauU5~}IL_BzYX>>R- zz58IksQk|G*wO`7YP>5tpLpoh?&-ywW5@p=T|XI%=MU_jj>EU-gYkrhS_%;hsaxu& zngP-ltwSIT$3%f7uK*@u)=r#$T#%Z;exGtUK6uIJd}|`M^g)N?eQ$O8E-l4Qz;fiG zaaZ^Bg$%ztwB+imh59@OEKf_pzQ#|pv$!a+M+6>#N7eF5al(t{N^q4UehXkDph5E| z>!@Hdi@IT;45CN}Ok=3&Hcf&sgVjTa{WVG2B$*SVWLuVkDr8IE+OUUXy6Chcpc{IT zjCblf9GIF0zRvYJ8cdsn|F6TY4jV&^O+;NXu7|p0V`wRPNQBLf;)2JjaGm1WpkSv~ zsugR+4cM1fiwd1!7G_)RJ8b;YEak~_ z1eGavB}?ziF2yo21&qfj)>UfA+%VR)-_FD`PY-2cU)A5~-)2zdb6@U{r={0b8dGTLF$wLNRaCPFNmRhOr1$iP5zy#*=XH zFcg*Fw~wuIb%g#HREaIa4RG|3D671oTiYB9n(CIop2DOKXm$At|vHhj~{14p?A>mkA2<%Ax z@U_kIR~a;6N%pfe62w`KFx8wm!q9>Ongk_bSqn>e6}s*r*w_I`9@n(D!R}qCMN@o?D zXAOkBkecvRZ{<-p^FwEx-q&H`h#0c?WfFfdGu%I< z4K_BG@Wu~q;5`JSVTA7+T+WXzHm>a+1@SJml+HE?X~<7f3PKHrLIr@EEVY*)hS}@P zHO1Fo9~~Tmta`DaCEciG4^cM&V<$oc{W&OSXmB(`6?r=?upE_t-Ndhrc7#*X;aK<- zvb7KFC}F;Td^{M0?ViQOXk>9QQr%YK%;Ys9Cmk~*_;@zCTi`K(I}Qe?m(cMI`@WCXz`7BXcG&&6}D*J3Z7 zjA4BOpZ|OSIB7axhnM%?l%9tl?on9KAF<@Ke@fUV96Q8Tm;i7uMX{MH8-7r3BIl%< zM;X-qeuK0MKTfHB;nNquRTR8H*SaC~g_r{Prvj(!tmlS@b9KPR!51A0VVViHWOfy+ zHWNs%WmE07NvqAWlg*<7YC2#+PF(#{D&_YnWn<&M4#@wSM7wcM_-dFbD_<2V^JTNz zszudQpzQRu2K!^O2OCBofdGnwSvFIkaNtdJKNUI*FoYiX(CQ3(I3kWO1Rv8h8{Zt2 z6(9r*(*WW?kw@7~I=zxk&oEe{C&r4!u?bC^9L?UE9c3nB{53XyC@6Q_#W88_>X3s! z#I326@o_~Tj7DKtxy3g|oc|c7ee71s;&GdfPQ~ykBza*2Wm(KD2hV0%V^b)Z^>KWWV%e)|zqpz-BAp;iA ztGQGv_o`LEzwxs)k%$S$k>br??Xck_wYF=96`M;4AeQY^4 z0a+ft$STpr&n|r?9*(n(#--?)vz6$Ri?LxSVE*F!l*!LdH#Xvdn8cdx6@(%F-?F1s#8ay>la;j^x=PoG zrV){_!yN0^FWSg8r(p`PfsLcjrp#0h10Nxm3C;xl0|v$`#y-YZ^Y1ig`310Qy%BQ# z7tQq<&ej%yxC?E2_+1wRdEn~6MkLVZ^(Jl}?8n^&ezvjl3QZvV^A&TA@C+18*UXRx z&_P3;ooP@|ZF3}2fW$4gBGd!tO=*hkGe{Il_+t4aD=JDzFQPxDUN_cCYX;MpROWER zA;nNa2FSHbEMyREN239bddOm-kW@p|Q?e*Yb0(c0YNjlErlav{#~bD{iM~F=WTx&I z=v(g_aG=Y26VOl)6Mr|Hbo)bz=T2WbeF;A71;Uj)lI-nG zh7z4FM1gg6CPH)`?{Fc8qN^kRmk*tK=+r4ltaa#ROPZB$SrN#DR;utCQS%D07K#;r z%oa2j*rTKvDVr>V^-HXiUpM&4z(p9R@!<)T={^ogwYu1=zCs9(FEScZfT_2FqyD2V zh~LsP5#stk{%&NBbzxg@vYeWv29pt=PKK~0#OR|vWU8rc;AWnU`jH^p)8TWT^o2hW zVD7(12E#pcgU$_^IR*%OQ0wk+yPprGoNnMjIy>_(HR|+@Fv>Z8<#n+Am{|m0lG3UG z91G|0*$`RX@7pTl=DPN##v&_C2wDrPr#0h1w9m~2Y$c8z#NpU-lvet~_H29TvGDAX zBJt|1O8{#t*z+~c-Hl&+JbZMPS}AV5DL?je{tzFR-~>w62q6P8qdDoYgnma%Y8O#%CAW=sm&4xP|^2rA(qjO2~nY``XzDjNT>e zF_lES7Sd}swT?l~G}#VmD!0pF5Bq#qd?UV^4_t;p@mMB;>#}bIuENEB0A%+`jwXsC zy#r>&Q7w=O7*?A_$d1cEL8MV+3eZ)hD!gBlna$OV-a)vnpDVJ;;{_&B4pSr?jH*sg z#Cqei16FvCnr6Zk)6`0Vg92{pAX=k?eX<(jQwE&nEc-9+on2wBcnL>uhe}V zsBUz1u*hxGQ=M)fo!776m!l)y9m0G~QA1iiK4amlW@c5VlS9lHL=+GI)eW^;jYjiJ zH0BM^3bNwA5zSziN!E%iF9ZFxWge;GpXdyrm&-soY=TvA2{Z)sU*a9$CAoxoyFfFG zZMR0=Z+r~vYgZ!~@ZBwDA`B$_HM;uA)m2! zi~}u;e7(x{#y=4Izz1Ug(dQ4xPfm8k!^USXhQn7_r*(b62**1nZ-|Hcq8GzQ!WHRX z8L!H=LgPA`v6cj(0A1VFqKWLuhEfau{7po!82Q&VK1)Yz*}%!hgpK0NT&6+z`TPsC z|5~w(^9^nrATt*2Ww<2ZU&edW1oOS{-+43t-8gVv=U!vYQ8T=KoS=5JSM$Q@3m={y z9-bb)#m0NZb)gypszOisVP9rIPBipd@~3leHBSdwKlyej}J!wmDaF7IRJ zo1B!E|JTI-VxwJ+U-3G|CdOG8J3t45S0&+%2{L9N`aE_pK43EDtr&c^zmug*y=i=0 zUOA{8T#@aAKPJCHj_`9%{DKagmZt`jR^S<4BpU~b1+eQg>BZjnzrUB&8&C8aMlbYZ z8-tvzxH$SwvfsiSA4cy*dD21D9T~Z-M*QISJp6vJ%7Tc^FzFUG#(k{7ktUt)oqI}$ zX<2dz$mRpBbs>XOWsd{0bmix+5*66-)cN?h-rMI1&SevOD%j)6% zXX8tPR)=cI5$NSqt}qWvj4U@r^)i3om-UtW2fW^lSN;Igxy5@ij81eP@XB!e2VUWt zogy>gP5qBPb}e`>-XOw1S({d@D~u%&}!(ccfV-*I}w zd?eB+M43qIpg?xVkk}IgMKBQ(n-r&e{(2-FrVsQqd$&F^Xp9VYcL2jRIAZV*oxxQ! zUPmg<|1Mf3-x7((Zj!oIW&JEvq_&4!-dm&8lN|2Z{mCfc^?UTyF4MTobPd$MBW}iVSjRbMr(iqn$xB?v90b!ixK~{QRmmIh-G! zBvZXup;20ch`GZvj#|wzGhBf`fg42|GxBc-J!sCJ{R`hSKUyv7Mg4b(-(1{@AvG)I z7ng}Ao%(JJDd~Y|J?i4t*nyxbTcnD|rd4Dd1>Dhb?zOS6cSrmm?Mo1ma%|2>#vxl~ z?t<$y1I2D6%I0Xc>#hFC+!)hzw;{ zVBXp@^T5*L;iNh+lGu|-45&$$KG`Tu>iSE+Sg&^y&G#HJbf5nK(k&lQlLOvF!aI;; zlYNIK8vlh2OdRU-SIRj7r(2Yl%a%-exYY0dsVu&$DS2?ji&Vp>(ti%r%RKUPzKG z(yAjk1uL)LMrFS|6mjsPhtG|M-ik=KV%^xPh?4Ac6pm4n^hbC{AjFNjXlZ~?J+!f zj4%UgtV~uQh#62>hvTxy1v>~At&nQE)JnxQCpYyft#NBE%B2pu7?Oi*V=Cn`yrcGd zSi!-vOu{-e{+YQRWmT+&_Lxv!7a`hZN%5)5Fby^>&&oI45VJp@q8j{+aD^FmwB6%` z{r8;Yrn<0fq4wvoYto~!&+y&%!@tLl=}TB^Hho3QEvr2GXw3ewM}?Ek@#q-+gh`lP zj1_4|cT^eF&AtPw4;6whtR`Z>5u~tnZAn4>}qWlkabyQ)mS%H zwJUI~1Q&PA2QVY3|5I)XrK|`))K-l(ZFN;+MQydQ4!K-~i*SXcv^M6ZfFTGhlN&aJ zVg}I0OdYZ*>pHC=z-Kevw&(5N0im6X3O-8dUs1|*NH%|Py{Exr79^%=-2;zN~OPpar=A<7wb>x~BaqRKgD~B_4D6i2DbdUGkx_IR7yN?{@ zmw|_v$}AiM+ZyQCABWuTB&h=R6zn6;0=|6eY=;hgno{;&+BJTQb`t&0fZx^l@6x27 zD)3<}9g5*yls-l2uTk1I-U9d=K$nz@)oT1v?J;54iSa)=sfXtfLl*Aeh~4mO`gb74 zA2VV%tY4Ghh;lVph3=(Dj3j2uLRW{7e&5l5?S@zl4w$rlLu_*m=xG5&q`<0T6_^X= zAuFchbJTA-$d@O@qdcPMs)KqvQs*%`g1aB32#j>M7;O-3qW*L9?musi64Gz}nT3R& zZI3#`DU~EqA}W|bz&Nu)%drB{Bo9;i`Mr(xy%YU2i9?B*{>EQ14Ov%12#|4p0z7n< zCno$eeSI_j#vd1p=s+mBn{<~0jss|AOZq%NOz<*NcYLw{rG5xw~GTRD?Yz6qchGMqBTv_Y6 zOml$fa)a!F0>bI|TMwxduP7(i2*c_SLA=uOQll(%k-jZ7ai@$5hSwK$lq9|c$!?#vZ zN=VnHFf(`NB4*`7z|$QU0m#) z>D)UxxwrG>Hr>M1tus>{F5gd$1}}{UAMf3>r+4NI-gw5AYHm=iQs1pc91M4-N`OKA z4h63O)l_b`HXN5Eh6)I74@!IadZjZX11c`<{L<-5%C;3?QY51Tz{Gg~`dHq+BCR^` z_rDwJaNYOsziy2_8j2|wv4}Dz@$tm=^{RIEhC;oat-jHTYU^v#4s|5#!Gkn9hR`lF z&2?wwLX-zLZ}c3p4G`xOX>Lu8^A!6hk0%d?hJ!=C$=6T%5@9$7cgXwMaO0m6=JJZE zRDOhCiuAa94)pdO=ymrF@Za41!m^owJFbXck5)7a%>H`qfHvCS&4|++t#m5*j(laX`$xy#}u9ZYT^_q%CD(@ti67e8`ZDY%1SR5v3^pU zyxNZ2*+YJj$cdAjNJXLmGqio96tvR9D8JEo?{ePSfxy=&mW+Fj%#OvQ$^0_Yn}={6 z>bFnMQk%?=EBJAMq# zOt^Zlr!yW7;SGnUwRmi34lc){0LC}l;~96le~e$@-#R>rUbjfAP)zVN$0jUbZLk8o zKFEM&DJVj-IvZMbcJ|mpW-2{h)av}eoSoe;&022u$l|R%HfnKRkQNDzIl%#gGv&&?GK36E}Sx)AL z@F@lNdFzDHNSVr@v8O zU$25g$hvNtqGbY~4`c!%D72}HfZa1&luPx{q3YpZ6h@nfzTHVEg*RY7#Ks{KypRhu z=Sf>!$`ebLt3p35TzAa@ccc4UrH0O)zJO7^;z_`X^mXVa1k{Olj!!8uW%6o=gUGT(adg zk_H|R>R3f99oXK=*331Ntu;1ksafX7Yp`9?bP!FLIf>SbGW$0BR4YHqE+iM+GCJ|3 zW#Gg^p`V@3h5WF6s+U!I?pR~fy^VjE_`-0E&ERF&?i>B#(c$40*XZjWKj1T($Wvu# z@qRu|pknPdMGZ}~C^FZt*ycnQdeC398kcRSL5Ihc!I%dj%!Sg3UC z@imvDUB?D|;l{&YKVXh8Y47tzJR_A%q-qXSy4>D-h~TK%R8+lL0=G=b+ht&dH2jkIRg%!kQv+O4D_xj zCND#a`2tMhc{V=Xs~SbCoZhC*<{zL9B2mODwGPl1AhMYUy%$WTSyff&S`OY{&VjEL z4m|AQlZi7wtft&UPBp+ny{YNB>7~$JS4Q`EVBKbdOKzpBPrAeb7IJG)YYv}yy9%hpLtpwVn=4-Qhnkq%DD$wD*CTaqeP zjW0hC$qWTppfBd%6;-VTy)-SN-9wmNRTw(^ly7Vnno@A(Mk9Kf9Il@q~LJn!Bq5Ofg=5o1A6=DT8!Sl7JKcr5|`8U9FunG~ozOljkX z&6i@am&_L_jQ!;oC8uSX^GOTWP(l|W8K`y@_u2Ubos^e;0^D=oGOkBXMvRR+S>O)+ z^sA>g_U_fk;Tl}J;|~4QsTS%G*URaft=F=!;X0zWA%$)DzW{VL11C(p{ZPeFIuHxF?)j zoa))-9h)#a8~>g41jGGZo&VsK1fMPiDTIIm;VWBu(JXHRCTDpAkWBJdvhKyP@qM5T z{nLlx;h7^c;Pv3stK%5HJv%xNPZ{?A^q=74H$E5{aKO`teLBqoMNTCUz1L5clRWqy zP6AEwXU;aP!XgQ)w?Oq_Wy7del_DXOcCTw|XjA2nTqzj_7*DafVd(n0VVEQV&1q;< z753A+&*I_hg>FaBzO{6Cb7h-GbzXC_mzenli}pdVu7F8!(HJY!L3QO9q2+#P6mkfYunQ zmr7)j!2ospJ{k<0ysSGY{yIqeWq$~qOtXFj<6)sM$q$@7`GEW-{mg?8UWEg;1{c26 zD0!dw^b?Xx_-2^ZNFn(119%$Ujrf^f)eNO&htz_)G|AX?m&rq$;%jb5N0JH~S z61*SWeJ;nJz$xNNlQpVUe@|;J$Z_%Re_kx@*;De;n69JeCb)O9FkV}{L^Hvy3!~ZH zS&q&52;l^fWf1z%W-T|CCiFys)%T}m-4iYq&BTkvy^F=;i?L%D?>)MgJ#c*SSZ?x; z5?n7GIXo9LP919H`8?E9vSg0gW%%WXVlNjTfjie?zf-d9LmiS7C46s*@o`U}xs(Y0 zC=?~AIVs=?5MGdE`4CkJFA!*h@UU-k(wFj0O!|hynMhf?AruP*0WfE+!xvCvAz1d8 z6m{7jkw-@4Fp6N3{xJRox3E76Yp7lcb>E4E<(=JlyQ2O|#NXAmZ(mmz@;N@yBV-G{ zLr&U7Qc&*MZTmbZBEmG^+RqWY%+KwVOH~dh&i{1luUc=E>NPS_UaJ#)5|hYYxk%UA zP8xM)N`h}{Cr6|uN{)=!=fLEL4wKNr^KEcItT=dJ!PMlRUpP=`)E6E@sx$pA9+AFp zM9t^NV~qCd$Zoi1e^5&)nGT6nEGcM8nj-BRm6Em!Zbd3bO$YCKHIk}s&NqCwlz%dq!#vtgQGM!mJ^*O~`)vTORcLSfpzTqs3N(d)imxqnQ> z4)0KG9g4kw$6}i}i?2ulk}i-vI`lEyWes|POfW$(Ty;Qb$W5TTVh;S?OOdLsDEjK` ziLPE`CwjY1%mV9AvL!oDne-`58Fyiu+&z>#D^A`xSr-ZbCz4Xd94i#Y%+R*QSf$jc z=3&yMWMRV2p|M74_w08oA7k9Gf^=x_cu zb2F!-RoXy*KieJtkGrC}qL;@Ki-Y!RLGkQ)ybx)GN-8K@A5kS*CCx$T`bWaWlJK0G z`$+7ZyYaQ7ZryzjXoCK4thPUHwv>w*_dPdz{yswz+7>a$Ml7^p86CCM>%6=C>f+++ z;=9}5Ae+i$j%PB9JG{u9<2@GSd?0Jbdz1@8yvM9c@gB>eQYlmhqp;ObiDOg1DXZ~) zqmI|g2ESvC?iTFVyE)<#*H@-OR7$9T)_ZD>%YQT5qPa=q`y3N4;6Iad&7(&*L%UV> zjmy9e!m_d6JTlr~-u~6+Vc9OPi8eb1R_#kIuQr=&$h4iST>Z*xMk5UB$?JxK9`+Ei zmOk{RAO9!e_|>B$kxWaz~#o;?~+}3eG1m;%te3^&Ji!z^d2DXx-??_GMj5H zEX_vk#B3CfTJaY`ZttSSqip5rYSyKL_=P0Z$Er{>D#x&gF4*n(s&R5(V{PAY%Jpp* zO3d{j8tg?j`ZYAX*S?X%Z@!T9sjBbKfLIAC734YWOO_*jDk4)-`P_ukE%W?nIf6^Cy@k4t?4;ss0P;q!XnHclB%8UBAHrCUf z9|VupxynswGW5V%Z*p>CI5;O-nA$yX%v!-S!!Y%S+E(p$qf%VOQ{g+qsqToddarV0 zO-f-U*R-I-PkhJF!@&dYkxoF_}3p50+Kim-gXOUb{7 z54(tu?b@OIs+JrZOPb%y6T@gEnrXtOnhJvT1W#qUvOV=AtMC_6>F-B`|k35`u-{~v&bien#-S=Fv zCHD0GNS2_Y0SnxobH`HHZ*Blb%7MBho3IS^(XsL5F#{+(6mP4M(6b&eZ2XII< zppEhg>97UxNl>BC5jpS{lMqTw+#I@819xE#_mcP%3R*8jWf$zj=l^OP^-%_yO@b6ta-oj#XuK<(;* zIZ*ZYc1OKF^$#tKF2TovEQeW&yn!)IHcggmg!jhGuX7_(qXDW@1_Ue7D15B7MMaYW zNDI43X_r)-77*QQuQbXGm^|pLl?@Pr8L)K08e6=w3P;kFE4J-H-SXB?x2%F>vW9Ad z_*HD*0d|b$qkLVlO{8!H)bN0t107uhi>VfzyFy^eZT2W}7_$~}GH+2RSu98xdnS{> zbFfBK;~()tc!3o~0oTEYiJ%n5<#wZ}kb%6LQIYI6{)v~S*o7M}u#Zv}AEwcC@8Q8r zdgv;ZcCTfxN7{m~unlXj-34{tgb|R>;cTep01}%J1VU{#!G(M)=J!WhkO4=6LH9`K zm1Q}77QqB+WuyLQp!+;L^;-y!LefJ!^GkPaG7QHjdAz~W<5Bt!^qnBnQd(6AeCeEHs zo=ZqVIU+`>KnHr-%0%l}88)WS1C0rVvI-RT3YKc{r`Qk*J_*Gopjap|WtGSgjgsW~ zN{}@kqFkIINo`7MX|;1>nIsf!*(g3S2(`ZhtM&ive$_k_>J^&f^>+JzbrrvQNob6>G~3@plJUC3 zMYMDTD9KsrWXmoF404mu2pLcx5D!ELAW>3)02>UydMd4SI{V+ z(j90XeYp;x;LCWt%u}DZ>Iqgu1>CM@m4k9EFeYiY60mh*Bp-?I9NjCYP?~48&5FGu zc^|B@@y0hHb!$K_-h47GY+s9V44u7WOrrVq$sH;p)`aAu z>6Y(uQx?5#4gQ{r)!=V!O9NC${qr@T?$Oq)y->kM(IfSc^dnC=_ur+_!Tz$`vHio= zzzL;nFlnc!+*)FR`q2FKOO!x_WbE*k5qQ7;UCX0+DrHm4*DtPKjlH)Jdv5#UD%IF~ z3bCCEY_pJK$a0d-ju_D_iMC`CZGr6^dtdaPBgJBVx%VO1;&j4p8Jj(Fk5MWb%lTOB z&~iQ*jayeFAy%|U3iFtsu)-F$foXHn3(iI;^zeH9LfOGe}Qu8)#-zh#6Mh z8eaz9kcFJmX>k!*%SaI-sZ_##Vi~H2!HUFnH1Bpvz1$Y75D~|qR_34#DKV!o-&u&Xa|KA}n~o$hbSoXb^(Gv;?wHu)Up%tt-(#Kh z4y0mJup~~!QUkqA;)(;U$E)ay+@lYrK-JMB!-=;CnjsaNbUG(vDV&WNy!URl!Twqb zS@u7kY}Nw?wHfqhpGTTWW`8L&?@Vv+mq*UT5`DqjjaxGp5;1>o*%grSa<4y@xRANk zxV6705j!&?M1rC|6+qy15}wHD+>usOK|AmY`1ZG1SSrGa(Xz-)So^$)r{dsP4atC< zWD;t%o@IRmFz5aw$suYj>``Q|@SNA&OSB~CGV8XkgVrW7`lMia*A@}j299O`HPc#~ z>R0HmjQxOSunis^4k9Ndo=+%=?^FMU=OYU>)Ar-a65oy~E8KNg%rxHvTkNinljEV~ z>?C6N5rQ*ePj2UD!EyRFWA&j&RNXW;WAklYX?wX{v>%!$Y1<_#;HT9vAz?Lerb6I* zfWN0vC88JM{U9xO`jeKCBl?z{2(5-*VG{8rtg7pZ(x@?s8b-8_c92y9MW4$ymmjrh z&P=4qBaawsYXIGBnKVO78kb)sH5)5Jwd}SPo=7HH)l_R`YmY&*)Ae`qkjVsT*jU4K zYReU75Pxv5ufqg`MM!*&DlrZB(FtAN+3R%Z(|>`x82PQ0*+0S^c+}0QT81~ONXd4@ z9*wb!@oUm!@tdD{Cicvq<9UpJdh@S68+*3R^C!+de*!Q~Z{vDHR2jaNtGcqu>n2o2 zKOa-y>~d2pmqm$1II!$! z7^brE|69-&;G50#DfjdRo~AuUHk&&06K6(g*uN6&?hbZ;{U^@+1S`_m-`|Z_NE*Yv zV5X?9wxrrtV{o$;jBZ2&+1;7U?%9KLdk^m#oSr;X z7@9dWF>z=nd(+aAV2NG z4<~eGesbEeGJ7zzIGvBj5AU6$VjtGW_e_Qo+F&R&s3k&^d&YGKyYbM>P~p(z^k8&p z>831JM*6<{57>BnASbou!z%Hs+XLsEffBon*=*-Od z_(XP>S9krp>~62_y=h@DUHj$N$L|}Wqv`a>f0$0spP&<|d(&*)$2nodogk}|IcY)K zBT057ezzU^!EJ}|m+>lGp`dRRvPb5j3FhXTVVDgaL+~>R7YT}_Lgz4?i%9V6CWX=E z?s!P4KwNydhe_)g*Pru0c&hVQ{!GHlJW_K$GO$EM|gNB86~;KLZo^l1b#@M@hrv^}PnyG>RV0>B1tbP>nh{9+c$; z!ENrfN(J~|eWOw_&3~z+*R@4wB8{}+-Z|Q(^!vsWfC5@1WT+x0i5!>D)0JPPE7v4C zVfq$%w!*am%z`J%aXd$ub>OgoJ^@YD-2Nb_B{dLvc1OZmIIJC{QdnPb5F)aspuvW_ zqtRqnGWvc^W2;n9o5U}=Rc`JUbRnA}Zuw$`g8kVfLU#&ZSQ@`NX&DBI27%o8^vG#V z{!kc6Vvb3P<-S{Xqu^#CHokZ10!VUY^djKpzXEtvR-3il}LJuYkc+HBB2vLvppP)G9@3Qrb06DqP#pZV~!H zO~b4<#18Nk)7+%#jltXDu9$@#$c&Bk^Ote{CymLl3hzd@5`IEQQY zTfOa=$8*d%wl}e_GwgKU?R3r#cAxFu)fwEINbC)Eo<8Pu9`jW3+GBYBd9Ixtj14N| zF9a7x&nn{zeBL@XKE6IW5?okY2#$3 z`FiZ@Cs%cwAVs}?I!gs7JTJyD#MbfnKRgRVj3=Cpz9Qc)$5#N=E z2jU0+M&r*e(@DB*+grb_93cq3(sT$iacypu_hqQW7?gRDDpFiuXOd7JR)fmqRe{kf zl-xxevxjmtE?Mht%Fa zi0l`N_ulgP?QnK~p${;&`}%tE##@+gJJ4N;@j5sp;-I&(NrX<$1T|`B^kt-3k@5A)o)vM5OhOq=2NVfC zBChs_k+o{97s&&M=_S)#=SAuDy3WneelR0b@EsH|>nLJhTBaFYR!A&a;A=0J7qU

wF7DI|Kx|V1sBQ9FYs>m5C)C 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 BJ$(QG literal 0 HcmV?d00001 diff --git a/test-reports/assets/MaterialIcons-Regular.woff2 b/test-reports/assets/MaterialIcons-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..9fa211252080046a23b2449dbdced6abc2b0bb34 GIT binary patch literal 44300 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 QW8}wPUeo^@jR61v08@RD2LJ#7 literal 0 HcmV?d00001 diff --git a/test-reports/assets/app.css b/test-reports/assets/app.css new file mode 100644 index 0000000..eb7c4e9 --- /dev/null +++ b/test-reports/assets/app.css @@ -0,0 +1,14 @@ +/*! mochawesome-report-generator 6.2.0 | https://github.com/adamgruber/mochawesome-report-generator */ +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.dropdown--trans-color---3ixtY{transition:color .2s ease-out;transition:var(--link-transition)}.dropdown--component---21Q9c{position:relative}.dropdown--toggle---3gdzr{white-space:nowrap}.dropdown--toggle-icon---1j9Ga:not(.dropdown--icon-only---3vq2I){margin-left:.5rem}.dropdown--list---8GPrA{padding:0;margin:0;list-style:none;text-align:left}.dropdown--list-main---3QZnQ{position:absolute;top:100%;z-index:1000;visibility:hidden;min-width:160px;overflow:auto}.dropdown--align-left---3-3Hu{left:0}.dropdown--align-right---2ZQx0{right:0}.dropdown--list-item-link---JRrOY,.dropdown--list-item-text---2COKZ{display:block;position:relative;white-space:nowrap;text-decoration:none}.dropdown--list-item-text---2COKZ{cursor:default}@-webkit-keyframes dropdown--in---FpwEb{0%{opacity:0}to{opacity:1}}@keyframes dropdown--in---FpwEb{0%{opacity:0}to{opacity:1}}@-webkit-keyframes dropdown--out---2HVe1{0%{opacity:1;visibility:visible}to{opacity:0}}@keyframes dropdown--out---2HVe1{0%{opacity:1;visibility:visible}to{opacity:0}}.dropdown--close---2LnDu{-webkit-animation:dropdown--out---2HVe1 .2s ease;animation:dropdown--out---2HVe1 .2s ease;-webkit-animation:dropdown--out---2HVe1 var(--default-transition-duration) var(--default-transition-easing);animation:dropdown--out---2HVe1 var(--default-transition-duration) var(--default-transition-easing);visibility:hidden}.dropdown--open---3bwiy{-webkit-animation:dropdown--in---FpwEb .2s ease;animation:dropdown--in---FpwEb .2s ease;-webkit-animation:dropdown--in---FpwEb var(--default-transition-duration) var(--default-transition-easing);animation:dropdown--in---FpwEb var(--default-transition-duration) var(--default-transition-easing);visibility:visible} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.dropdown-selector--trans-color---3nePW{transition:color .2s ease-out;transition:var(--link-transition)}.dropdown-selector--dropdown---AT5ee{right:-8px}.dropdown-selector--menu---nW4gv{box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);font-family:robotolight;font-family:var(--font-family-light);min-width:70px;width:70px;background:#fff;top:0}.dropdown-selector--toggle---WEnEe{display:inline-block;font-family:robotoregular;font-family:var(--font-family-regular);font-size:14px;color:rgba(0,0,0,.54);color:var(--black54);vertical-align:top;line-height:24px;padding:0 22px 0 0;cursor:pointer;border:none;background:none;outline:none;width:70px}.dropdown-selector--toggle---WEnEe:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500)}.dropdown-selector--toggle-icon---10VKo{position:absolute;top:4px;right:4px}.dropdown-selector--item-link---2W1T7,.dropdown-selector--toggle-icon---10VKo{color:rgba(0,0,0,.38);color:var(--black38)}.dropdown-selector--item-link---2W1T7{border:none;cursor:pointer;padding:4px 10px;text-align:left;width:100%}.dropdown-selector--item-link---2W1T7:hover{background-color:#f5f5f5;background-color:var(--grey100)}.dropdown-selector--item-link---2W1T7:focus{box-shadow:inset 0 0 2px 0 #03a9f4;box-shadow:inset 0 0 2px 0 var(--ltblue500);outline:none}.dropdown-selector--item-selected---1q-NK .dropdown-selector--item-link---2W1T7{color:#4caf50;color:var(--green500)} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.footer--trans-color---205XF{transition:color .2s ease-out;transition:var(--link-transition)}.footer--component---1WcTR{position:absolute;bottom:0;width:100%;height:60px;height:var(--footer-height);color:rgba(0,0,0,.38);color:var(--black38);text-align:center}.footer--component---1WcTR p{font-size:12px;margin:10px 0}.footer--component---1WcTR a{color:rgba(0,0,0,.54);color:var(--black54);transition:color .2s ease-out;transition:var(--link-transition)}.footer--component---1WcTR a:hover{color:rgba(0,0,0,.87);color:var(--black87)} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.loader--trans-color---97r08{transition:color .2s ease-out;transition:var(--link-transition)}.loader--component---2grcA{position:fixed;top:0;height:100%;width:100%;background-color:color(#f2f2f2 alpha(60%));background-color:color(var(--body-bg) alpha(60%));padding-top:122px;padding-top:var(--navbar-height)}.loader--wrap---3Fhrc{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;-webkit-flex-direction:column;flex-direction:column;min-height:200px}.loader--text---3Yu3g{color:color(#000 tint(46.7%));color:var(--gray-light);text-align:center;margin:1rem 0 0}.loader--spinner---2q6MO{border-radius:50%;width:42px;height:42px;border:.25rem solid color(#000 tint(73.5%));border-top-color:color(#000 tint(33.5%));border:.25rem solid var(--gray-medium);border-top-color:var(--gray);-webkit-animation:loader--spin---K6Loh 1s linear infinite;animation:loader--spin---K6Loh 1s linear infinite}@-webkit-keyframes loader--spin---K6Loh{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes loader--spin---K6Loh{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@media (min-width:768px){.loader--component---2grcA{padding-top:56px;padding-top:var(--navbar-height-short)}} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.nav-menu--trans-color---1l-R-{transition:color .2s ease-out;transition:var(--link-transition)}.nav-menu--wrap---39S_b{position:fixed;z-index:2010;top:0;right:0;bottom:0;left:0;overflow:hidden;visibility:hidden}.nav-menu--overlay---k2Lwz{display:none;background:rgba(0,0,0,.5)}.nav-menu--close-btn---2m7W7{border:none;background:transparent;padding:0}.nav-menu--close-btn---2m7W7:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500);outline:none}.nav-menu--close-btn---2m7W7{cursor:pointer;transition:color .2s ease-out;transition:var(--link-transition);position:absolute;top:16px;right:16px;color:rgba(0,0,0,.54);color:var(--black54)}.nav-menu--close-btn---2m7W7:active,.nav-menu--close-btn---2m7W7:hover{color:rgba(0,0,0,.87);color:var(--black87)}.nav-menu--menu---lFcsl{position:absolute;transition:all .15s cubic-bezier(.25,1,.8,1);-webkit-transform:translate(-100%);transform:translate(-100%);width:100%;z-index:1;top:0;bottom:0;left:0;overflow:auto;background:#fff}.nav-menu--close-button---2_OHr{border:none;background:transparent;padding:0}.nav-menu--close-button---2_OHr:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500);outline:none}.nav-menu--close-button---2_OHr{cursor:pointer;transition:color .2s ease-out;transition:var(--link-transition);position:absolute;top:14px;right:14px;font-size:21px;width:26px;height:26px;color:color(#000 tint(33.5%));color:var(--gray)}.nav-menu--close-button---2_OHr:hover{color:color(#000 tint(20%));color:var(--gray-dark)}.nav-menu--date---3SYOi,.nav-menu--section-head---3LXPD{color:rgba(0,0,0,.54);color:var(--black54)}.nav-menu--section-head---3LXPD{text-transform:uppercase}.nav-menu--control---1JEYH{display:-webkit-flex;display:flex;position:relative;margin:8px 0;-webkit-align-items:center;align-items:center}.nav-menu--control-label---3f2XU{display:inline-block;-webkit-flex-grow:1;flex-grow:1;font-family:var(--font-family--regular);font-size:13px;vertical-align:top;line-height:24px}.nav-menu--control-label---3f2XU.nav-menu--with-icon---qF4hj{margin-left:12px}.nav-menu--control-group---32kKg{margin-bottom:10px}.nav-menu--toggle-icon-passed---132lH{color:#4caf50;color:var(--green500)}.nav-menu--toggle-icon-failed---x-XUB{color:#f44336;color:var(--red500)}.nav-menu--toggle-icon-pending---3ZJAs{color:#03a9f4;color:var(--ltblue500)}.nav-menu--toggle-icon-skipped---FyedH{color:#9e9e9e;color:var(--grey500)}.nav-menu--wrap---39S_b.nav-menu--open---3BW1O{visibility:visible}.nav-menu--wrap---39S_b.nav-menu--open---3BW1O .nav-menu--overlay---k2Lwz{opacity:1}.nav-menu--wrap---39S_b.nav-menu--open---3BW1O .nav-menu--menu---lFcsl{-webkit-transform:translate(0);transform:translate(0)}.nav-menu--section---2z7Dj{padding:0 16px;border-bottom:1px solid #e0e0e0;border-bottom:1px solid var(--grey300)}.nav-menu--list---2QMG9{list-style:none;padding-left:0}.nav-menu--main---jkqJW{margin:8px 0}.nav-menu--no-tests---2sRAg>.nav-menu--item---gXWu6:not(.nav-menu--has-tests---1ND4g)>div>.nav-menu--sub---EnSIu{padding-left:0}.nav-menu--no-tests---2sRAg>.nav-menu--item---gXWu6:not(.nav-menu--has-tests---1ND4g):not(:only-child){padding-left:22px}.nav-menu--sub---EnSIu{padding-left:24px;margin:0 0 2px}.nav-menu--link---tywPF{display:-webkit-flex;display:flex;position:relative;-webkit-align-items:center;align-items:center;padding:3px 0;color:color(#000 tint(33.5%));color:var(--gray)}.nav-menu--link---tywPF:hover{color:color(color(#428bca shade(6.5%)) shade(15%));color:var(--link-hover-color);text-decoration:none}.nav-menu--link---tywPF:active,.nav-menu--link---tywPF:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500);outline:none;text-decoration:none}.nav-menu--link---tywPF span{transition:color .2s ease-out;transition:var(--link-transition);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nav-menu--link-icon---1Q2NP{margin-right:2px}.nav-menu--link-icon---1Q2NP.nav-menu--pass---1PUeh{color:#4caf50;color:var(--green500)}.nav-menu--link-icon---1Q2NP.nav-menu--fail---3gQQa{color:#f44336;color:var(--red500)}.nav-menu--link-icon---1Q2NP.nav-menu--pending---9zAw0{color:#03a9f4;color:var(--ltblue500)}.nav-menu--link-icon---1Q2NP.nav-menu--skipped---31GPM{color:#9e9e9e;color:var(--grey500)}.nav-menu--disabled---2MoA_{opacity:.3;pointer-events:none}@media (min-width:768px){.nav-menu--menu---lFcsl{width:320px;left:auto}.nav-menu--overlay---k2Lwz{display:block;position:fixed;transition:all .2s ease-out;top:0;right:0;bottom:0;left:0;cursor:pointer;opacity:0}} +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.trans-color{transition:color .2s ease-out;transition:var(--link-transition)}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-family:var(--headings-font-family);font-weight:400;font-weight:var(--headings-font-weight);line-height:1.1;line-height:var(--headings-line-height);color:inherit;color:var(--headings-color)}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:color(#000 tint(46.7%));color:var(--headings-small-color)}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-top:var(--line-height-computed);margin-bottom:10px;margin-bottom:calc(var(--line-height-computed)/2)}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-top:calc(var(--line-height-computed)/2);margin-bottom:10px;margin-bottom:calc(var(--line-height-computed)/2)}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px;font-size:var(--font-size-h1)}.h2,h2{font-size:30px;font-size:var(--font-size-h2)}.h3,h3{font-size:24px;font-size:var(--font-size-h3)}.h4,h4{font-size:18px;font-size:var(--font-size-h4)}.h5,h5{font-size:14px;font-size:var(--font-size-h5)}.h6,h6{font-size:12px;font-size:var(--font-size-h6)}p{margin:0 0 10px;margin:0 0 calc(var(--line-height-computed)/2)}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}ol,ul{margin-top:0;margin-bottom:10px;margin-bottom:calc(var(--line-height-computed)/2);ol,ul{margin-bottom:0}}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}code{font-family:Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--font-family-mono)}.hljs{display:block;overflow-x:auto;padding:.5em;color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-addition,.hljs-attribute,.hljs-meta-string,.hljs-regexp,.hljs-string{color:#50a14f}.hljs-built_in,.hljs-class .hljs-title{color:#c18401}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#4078f2}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-align-items:flex-end;align-items:flex-end}.ct-label.ct-horizontal.ct-end,.ct-label.ct-horizontal.ct-start{-webkit-justify-content:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-align-items:flex-start;align-items:flex-start}.ct-label.ct-vertical.ct-start{-webkit-align-items:flex-end;align-items:flex-end;-webkit-justify-content:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-align-items:flex-end;align-items:flex-end;-webkit-justify-content:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-align-items:flex-end;align-items:flex-end;-webkit-justify-content:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-align-items:flex-start;align-items:flex-start;-webkit-justify-content:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-align-items:flex-end;align-items:flex-end;-webkit-justify-content:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-align-items:flex-start;align-items:flex-start;-webkit-justify-content:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-align-items:center;align-items:center;-webkit-justify-content:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-align-items:center;align-items:center;-webkit-justify-content:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-grid-background{fill:none}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{fill:none;stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{content:"";display:table;clear:both}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{content:"";display:table;clear:both}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{content:"";display:table;clear:both}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{content:"";display:table;clear:both}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{content:"";display:table;clear:both}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{content:"";display:table;clear:both}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{content:"";display:table;clear:both}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{content:"";display:table;clear:both}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{content:"";display:table;clear:both}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{content:"";display:table;clear:both}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{content:"";display:table;clear:both}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{content:"";display:table;clear:both}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{content:"";display:table;clear:both}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{content:"";display:table;clear:both}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{content:"";display:table;clear:both}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{content:"";display:table;clear:both}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{content:"";display:table;clear:both}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}@font-face{font-family:robotolight;src:url(roboto-light-webfont.woff2) format("woff2"),url(roboto-light-webfont.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:robotomedium;src:url(roboto-medium-webfont.woff2) format("woff2"),url(roboto-medium-webfont.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:robotoregular;src:url(roboto-regular-webfont.woff2) format("woff2"),url(roboto-regular-webfont.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url(MaterialIcons-Regular.woff2) format("woff2"),url(MaterialIcons-Regular.woff) format("woff")}.material-icons{display:inline-block;font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;-webkit-font-feature-settings:"liga";font-feature-settings:"liga"}.material-icons.md-18{font-size:18px}.material-icons.md-24{font-size:24px}.material-icons.md-36{font-size:36px}.material-icons.md-48{font-size:48px}.material-icons.md-dark{color:rgba(0,0,0,.54)}.material-icons.md-dark.md-inactive{color:rgba(0,0,0,.26)}.material-icons.md-light{color:#fff}.material-icons.md-light.md-inactive{color:hsla(0,0%,100%,.3)}*,:after,:before{box-sizing:border-box}html{position:relative;min-height:100%}body{font-family:robotoregular,Helvetica Neue,Helvetica,Arial,sans-serif;font-family:var(--font-family-base);font-size:14px;font-size:var(--font-size-base);line-height:1.429;line-height:var(--line-height-base);color:rgba(0,0,0,.87);color:var(--text-color);background-color:#f2f2f2;background-color:var(--body-bg);margin-bottom:60px;margin-bottom:var(--footer-height)}a{text-decoration:none;transition:color .2s ease-out;transition:var(--link-transition)}a:hover{text-decoration:underline}pre{word-break:break-all;word-wrap:break-word;border-radius:4px}.cf:before,.clearfix:before{content:" ";display:table}.cf:after,.clearfix:after{content:" ";display:table;clear:both}.container:after,.container:before{content:" ";display:table}.container:after{clear:both}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-left:calc(var(--grid-gutter-width)/2);padding-right:15px;padding-right:calc(var(--grid-gutter-width)/2)}.row:after,.row:before{content:" ";display:table}.row:after{clear:both}.row{margin-left:-15px;margin-left:calc(var(--grid-gutter-width)/-2);margin-right:-15px;margin-right:calc(var(--grid-gutter-width)/-2)}.details{padding-top:146px;padding-top:calc(var(--navbar-height) + 24px)}.z-depth-0{box-shadow:none!important}.z-depth-1{box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12)}.z-depth-1-half{box-shadow:0 5px 11px 0 rgba(0,0,0,.18),0 4px 15px 0 rgba(0,0,0,.15)}.z-depth-2{box-shadow:0 8px 17px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19)}.z-depth-3{box-shadow:0 12px 15px 0 rgba(0,0,0,.24),0 17px 50px 0 rgba(0,0,0,.19)}.z-depth-4{box-shadow:0 16px 28px 0 rgba(0,0,0,.22),0 25px 55px 0 rgba(0,0,0,.21)}.z-depth-5{box-shadow:0 27px 24px 0 rgba(0,0,0,.2),0 40px 77px 0 rgba(0,0,0,.22)}@media (min-width:768px){.container{width:750px;width:var(--container-sm)}.details{padding-top:80px;padding-top:calc(var(--navbar-height-short) + 24px)}}@media (min-width:992px){.container{width:970px;width:var(--container-md)}}@media (min-width:1200px){.container{width:1170px;width:var(--container-lg)}} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.navbar--trans-color---1tk7E{transition:color .2s ease-out;transition:var(--link-transition)}.navbar--component---2UCEi:after,.navbar--component---2UCEi:before{content:" ";display:table}.navbar--component---2UCEi:after{clear:both}.navbar--component---2UCEi{position:fixed;-webkit-flex-direction:column;flex-direction:column;top:0;right:0;left:0;z-index:1030;min-height:122px;min-height:var(--navbar-height);height:122px;height:var(--navbar-height);margin-bottom:0;border:none;background:#37474f;background:var(--bluegrey800)}.navbar--component---2UCEi,.navbar--report-info-cnt---8y9Bb{display:-webkit-flex;display:flex}.navbar--report-info-cnt---8y9Bb{overflow:hidden;padding-right:12px}.navbar--menu-button---1ZRpz{border:none;background:transparent;padding:0}.navbar--menu-button---1ZRpz:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500);outline:none}.navbar--menu-button---1ZRpz{cursor:pointer;transition:color .2s ease-out;transition:var(--link-transition);height:40px;margin:8px 8px 0;padding:8px;color:hsla(0,0%,100%,.5);color:var(--light-icon-inactive)}.navbar--menu-button---1ZRpz:hover{color:#fff;color:var(--light-icon-active)}.navbar--report-title---3bXCv{-webkit-flex-grow:1;flex-grow:1;font-family:var(--font-family--light);color:#fff;font-size:18px;line-height:52px;line-height:calc(var(--navbar-height-short) - 4px);margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.navbar--pct-bar---3EwW-:after,.navbar--pct-bar---3EwW-:before{content:" ";display:table}.navbar--pct-bar---3EwW-:after{clear:both}.navbar--pct-bar---3EwW-{display:-webkit-flex;display:flex;position:absolute;left:0;right:0;bottom:0;height:4px}.navbar--pct-bar---3EwW- .navbar--pass---2oR-w{background-color:#4caf50;background-color:var(--green500)}.navbar--pct-bar---3EwW- .navbar--fail---3mN80{background-color:#f44336;background-color:var(--red500)}.navbar--pct-bar---3EwW- .navbar--pend---2iqjh{background-color:#03a9f4;background-color:var(--ltblue500)}.navbar--pct-bar-segment---3T0_o{height:4px}@media (min-width:768px){.navbar--component---2UCEi{min-height:56px;min-height:var(--navbar-height-short);height:56px;height:var(--navbar-height-short);-webkit-flex-direction:initial;flex-direction:row}.navbar--report-info-cnt---8y9Bb{-webkit-flex-grow:1;flex-grow:1}} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.quick-summary--trans-color---HUJqE{transition:color .2s ease-out;transition:var(--link-transition)}.quick-summary--cnt---3s38x{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;padding:0 12px}.quick-summary--list---2_80W:after,.quick-summary--list---2_80W:before{content:" ";display:table}.quick-summary--list---2_80W:after{clear:both}.quick-summary--list---2_80W{list-style:none;padding-left:0;transition:opacity .2s ease-out;margin:0 0 8px}.quick-summary--item---bfSQ0,.quick-summary--list---2_80W{display:-webkit-flex;display:flex}.quick-summary--item---bfSQ0{font-family:var(--font-family--light);-webkit-align-items:flex-start;align-items:flex-start;color:#fff;font-size:16px;-webkit-flex-basis:25%;flex-basis:25%}.quick-summary--item---bfSQ0 button{border:none;background:transparent;padding:0}.quick-summary--item---bfSQ0 button:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500);outline:none}.quick-summary--item---bfSQ0 button{transition:color .2s ease-out;transition:var(--link-transition);display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;color:#fff;cursor:pointer}.quick-summary--item---bfSQ0 button:hover .quick-summary--icon---TW1oG{border-color:#fff}.quick-summary--item---bfSQ0.quick-summary--tests---2nNut{color:#fff}.quick-summary--item---bfSQ0.quick-summary--passes---3IjYH .quick-summary--icon---TW1oG{color:#388e3c;color:var(--green700);background-color:#c8e6c9;background-color:var(--green100)}.quick-summary--single-filter---31Thy .quick-summary--item---bfSQ0.quick-summary--passes---3IjYH .quick-summary--icon---TW1oG{background-color:#e0e0e0;background-color:var(--grey300);color:#9e9e9e;color:var(--grey500)}.quick-summary--single-filter--passed---3QnUL .quick-summary--item---bfSQ0.quick-summary--passes---3IjYH .quick-summary--icon---TW1oG{color:#fff;background-color:#388e3c;background-color:var(--green700)}.quick-summary--item---bfSQ0.quick-summary--failures---14s29 .quick-summary--icon---TW1oG{color:#d32f2f;color:var(--red700);background-color:#ffcdd2;background-color:var(--red100)}.quick-summary--single-filter---31Thy .quick-summary--item---bfSQ0.quick-summary--failures---14s29 .quick-summary--icon---TW1oG{background-color:#e0e0e0;background-color:var(--grey300);color:#9e9e9e;color:var(--grey500)}.quick-summary--single-filter--failed---3_tAw .quick-summary--item---bfSQ0.quick-summary--failures---14s29 .quick-summary--icon---TW1oG{color:#fff;background-color:#d32f2f;background-color:var(--red700)}.quick-summary--item---bfSQ0.quick-summary--pending---261aV .quick-summary--icon---TW1oG{color:#0288d1;color:var(--ltblue700);background-color:#b3e5fc;background-color:var(--ltblue100)}.quick-summary--single-filter---31Thy .quick-summary--item---bfSQ0.quick-summary--pending---261aV .quick-summary--icon---TW1oG{background-color:#e0e0e0;background-color:var(--grey300);color:#9e9e9e;color:var(--grey500)}.quick-summary--single-filter--pending---21lZM .quick-summary--item---bfSQ0.quick-summary--pending---261aV .quick-summary--icon---TW1oG{color:#fff;background-color:#0288d1;background-color:var(--ltblue700)}.quick-summary--item---bfSQ0.quick-summary--skipped---tyOc4 .quick-summary--icon---TW1oG{color:#616161;color:var(--grey700);background-color:#f5f5f5;background-color:var(--grey100)}.quick-summary--single-filter---31Thy .quick-summary--item---bfSQ0.quick-summary--skipped---tyOc4 .quick-summary--icon---TW1oG{background-color:#e0e0e0;background-color:var(--grey300);color:#9e9e9e;color:var(--grey500)}.quick-summary--single-filter--skipped---1AdZA .quick-summary--item---bfSQ0.quick-summary--skipped---tyOc4 .quick-summary--icon---TW1oG{color:#fff;background-color:#616161;background-color:var(--grey700)}.quick-summary--icon---TW1oG{position:relative;top:2px;font-size:18px;margin-right:4px}.quick-summary--circle-icon---1HDS7{font-size:12px;border-radius:50%;padding:2px;border:1px solid transparent;transition:border-color .2s ease-out}@media (min-width:768px){.quick-summary--cnt---3s38x{-webkit-flex-direction:initial;flex-direction:row;padding:14px 12px 0 0}.quick-summary--list---2_80W{margin:0}.quick-summary--item---bfSQ0{font-size:18px;-webkit-flex-basis:initial;flex-basis:auto;margin:0 12px}.quick-summary--icon---TW1oG{font-size:24px;width:24px;top:0}.quick-summary--circle-icon---1HDS7{font-size:18px}} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.radio-button--trans-color---egsik{transition:color .2s ease-out;transition:var(--link-transition)}.radio-button--component---1ix3c:after,.radio-button--component---1ix3c:before{content:" ";display:table}.radio-button--component---1ix3c:after{clear:both}.radio-button--component---1ix3c{position:relative;height:24px}.radio-button--outer---a_NqL{position:absolute;top:50%;right:0;margin-top:-9px;width:18px;height:18px;border:2px solid #4caf50;border:2px solid var(--green500);border-radius:12px;cursor:pointer;transition:border-color .2s ease-out}.radio-button--off---dBAOK{border-color:color(#000 tint(73.5%));border-color:var(--gray-medium)}.radio-button--inner---3bo9Q{display:block;position:absolute;top:2px;right:2px;width:10px;height:10px;border-radius:100%;background-color:#4caf50;background-color:var(--green500)}.radio-button--off---dBAOK .radio-button--inner---3bo9Q{background-color:#fff;-webkit-transform:scale(0);transform:scale(0)}.radio-button--inner---3bo9Q{transition:all .15s cubic-bezier(.23,1,.32,1)} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.test--trans-color---3sP2r{transition:color .2s ease-out;transition:var(--link-transition)}.test--component---1mwsi{border-bottom:1px solid #e0e0e0;border-bottom:1px solid var(--grey300)}.test--component---1mwsi.test--expanded---3hI0z.test--passed---38wAs .test--body-wrap---3EGPT,.test--component---1mwsi.test--expanded---3hI0z.test--passed---38wAs .test--header-btn---mI0Oy{border-left-color:#4caf50;border-left-color:var(--green500)}.test--component---1mwsi.test--expanded---3hI0z.test--failed---2PZhW .test--body-wrap---3EGPT,.test--component---1mwsi.test--expanded---3hI0z.test--failed---2PZhW .test--header-btn---mI0Oy{border-left-color:#f44336;border-left-color:var(--red500)}.test--list---24Hjy{list-style-type:none;margin:0;padding:0}.test--header-btn---mI0Oy{display:-webkit-flex;display:flex;position:relative;background:#fff;border:none;border-left:3px solid transparent;cursor:pointer;-webkit-flex-wrap:wrap;flex-wrap:wrap;padding:10px 16px 10px 13px;transition:border-color .2s ease-out;width:100%}.test--header-btn---mI0Oy[disabled]{cursor:default}.test--header-btn---mI0Oy:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500);outline:none}.test--header-btn---mI0Oy:focus:not([disabled]),.test--header-btn---mI0Oy:hover:not([disabled]){border-left-color:#9e9e9e;border-left-color:var(--grey500)}.test--title---4c0rg{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;-webkit-flex-grow:1;flex-grow:1;font-family:var(--font-family--regular);font-size:13px;line-height:24px;margin:0;padding-right:12px;text-align:left}.test--hook---3T4lI .test--title---4c0rg{color:rgba(0,0,0,.54);color:var(--black54)}.test--expanded---3hI0z .test--title---4c0rg{line-height:1.5;padding-top:3px;white-space:normal}.test--icon---2jgH_{-webkit-align-self:flex-start;align-self:flex-start;padding:3px;border-radius:50%;color:#fff;margin-right:16px}.test--icon---2jgH_.test--pass---C1Mk7{color:#c8e6c9;color:var(--green100);background-color:#4caf50;background-color:var(--green500)}.test--icon---2jgH_.test--fail---3u2w0{color:#ffcdd2;color:var(--red100);background-color:#f44336;background-color:var(--red500)}.test--icon---2jgH_.test--pending---3Ctfm{color:#b3e5fc;color:var(--ltblue100);background-color:#03a9f4;background-color:var(--ltblue500)}.test--icon---2jgH_.test--skipped---3aU0Y{color:#f5f5f5;color:var(--grey100);background-color:#9e9e9e;background-color:var(--grey500)}.test--icon---2jgH_.test--hook---3T4lI{color:rgba(0,0,0,.38);color:var(--black38);padding:0}.test--failed---2PZhW .test--icon---2jgH_.test--hook---3T4lI{color:#f44336;color:var(--red500)}.test--info---1UQNw{display:-webkit-flex;display:flex}.test--duration---2tVp5{font-family:var(--font-family--regular);line-height:24px;color:rgba(0,0,0,.54);color:var(--black54)}.test--component---1mwsi:hover:not(.test--pending---3Ctfm) .test--duration---2tVp5,.test--expanded---3hI0z .test--duration---2tVp5{color:rgba(0,0,0,.87);color:var(--black87)}.test--duration---2tVp5{transition:color .2s ease-out}.test--duration-icon---2KnOU{margin-left:4px;line-height:24px!important;color:rgba(0,0,0,.38);color:var(--black38)}.test--duration-icon---2KnOU.test--slow---MQOnF{color:#e57373;color:var(--red300)}.test--duration-icon---2KnOU.test--medium---5j890{color:#fbc02d;color:var(--yellow700)}.test--context-icon---2POzC{position:relative;line-height:24px!important;color:rgba(0,0,0,.38);color:var(--black38);margin-right:8px;top:1px}.test--body-wrap---3EGPT{border-left:3px solid transparent;transition:border-color .2s ease-out}.test--expanded---3hI0z .test--body-wrap---3EGPT{display:block;padding-bottom:10px}.test--body---Ox0q_{display:none;background-color:#fafafa;border:1px solid #eceff1;border:1px solid var(--grey50);border-radius:4px}.test--expanded---3hI0z .test--body---Ox0q_{display:block;margin:0 16px 0 13px}.test--error-message---3Grn0{color:#f44336;color:var(--red500);font-size:12px;margin:10px 0 0;text-align:left;width:100%;word-break:break-word}.test--code-snippet---3H5Xj{position:relative;font-size:11px;margin:0;border-radius:0}.test--code-snippet---3H5Xj+.test--code-snippet---3H5Xj{border-top:1px solid #fff}.test--code-snippet---3H5Xj.hljs{padding:1em;background:none}.test--code-diff---2XQsb code>span:first-child{margin-right:11px}.test--code-diff-expected---1QWLl span{color:#859900}.test--inline-diff---3OmYO .test--code-diff-expected---1QWLl{background-color:#859900;color:#fff}.test--code-diff-actual---3MMxN span{color:#dc322f}.test--inline-diff---3OmYO .test--code-diff-actual---3MMxN{background-color:#dc322f;color:#fff}.test--code-label---1QEUY{position:absolute;font-family:var(--font-family--regular);top:0;right:0;padding:.2em .6em;background-color:#9e9e9e;background-color:var(--grey500);color:#fff}.test--context---1YYgX{background-color:#fff;border-top:1px solid #eceff1;border-top:1px solid var(--grey50);border-bottom-left-radius:4px;border-bottom-right-radius:4px}.test--context-title---HHH10{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-family--regular);font-size:13px;color:rgba(0,0,0,.54);color:var(--black54);margin:0;padding:11px 11px 0}.test--context-item---R1NNU{padding-top:11px}.test--context-item---R1NNU .test--code-snippet---3H5Xj{padding-top:0}.test--context-item-title---1KxIO{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-family--medium);font-size:13px;margin:0;padding:0 11px 11px}.test--text-link---2_cSn{display:inline-block;padding:0 1em 1em;font-family:Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--font-family-mono);font-size:11px;color:#0288d1;color:var(--ltblue700)}.test--text-link---2_cSn:hover{color:#03a9f4;color:var(--ltblue500)}.test--image-link---PUFPJ,.test--video-link---1L-2D{display:inline-block;font-size:11px;padding:0 1em 1em}.test--image---2Z5X2,.test--video---2JK7O{display:block;max-width:100%;height:auto} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.suite--trans-color---2pu6T{transition:color .2s ease-out;transition:var(--link-transition)}.suite--component---22Vxk:after,.suite--component---22Vxk:before{content:" ";display:table}.suite--component---22Vxk:after{clear:both}.suite--component---22Vxk{position:relative;background-color:#fff;margin-bottom:20px}.suite--component---22Vxk>.suite--body---1itCO>ul>li>.suite--component---22Vxk{border:1px solid #e0e0e0;border:1px solid var(--grey300);border-right:none;border-bottom:none;margin:16px 0 16px 16px}.suite--component---22Vxk>.suite--body---1itCO>ul>li>.suite--component---22Vxk.suite--no-tests---l47BS{border-bottom:1px solid #e0e0e0;border-bottom:1px solid var(--grey300)}.suite--list---3WtMK{list-style-type:none;margin:0;padding:0}.suite--list-main---3KCXR>li>.suite--component---22Vxk,.suite--root-suite---ZDRuj{box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);margin:0 0 24px}.suite--list-main---3KCXR>.suite--no-tests---l47BS>.suite--body---1itCO>ul>li>.suite--component---22Vxk:not(.suite--no-suites---2PQFQ){border-bottom:1px solid #e0e0e0;border-bottom:1px solid var(--grey300)}.suite--header---TddSn:after,.suite--header---TddSn:before{content:" ";display:table}.suite--header---TddSn:after{clear:both}.suite--header---TddSn{border-bottom:1px solid #e0e0e0;border-bottom:1px solid var(--grey300)}.suite--no-tests---l47BS>.suite--header---TddSn{padding-bottom:0;border-bottom:none}.suite--header-btn---25qLz{background:#fff;border:none;cursor:pointer;padding:12px 16px;text-align:left;width:100%}.suite--header-btn---25qLz:focus{box-shadow:0 0 2px 0 #03a9f4;box-shadow:0 0 2px 0 var(--ltblue500);outline:none}.suite--title---3T6OR{display:-webkit-flex;display:flex;font-family:var(--font-family--light);font-size:21px;margin:0}.suite--title---3T6OR span{margin-right:auto}.suite--title---3T6OR .suite--icon---2KPe5{margin-left:58px}.suite--filename---1u8oo{color:rgba(0,0,0,.54);color:var(--black54);font-family:var(--font-family--regular);margin:6px 0 0}.suite--body---1itCO:after,.suite--body---1itCO:before{content:" ";display:table}.suite--body---1itCO:after{clear:both}.suite--body---1itCO.suite--hide---2i8QF{display:none}.suite--has-suites---3OYDf>.suite--body---1itCO{border-bottom:1px solid #e0e0e0;border-bottom:1px solid var(--grey300)}.suite--chart-wrap---7hvUh{display:none;position:absolute;top:12px;right:36px;width:50px;height:50px}.suite--chart-slice---1XN2j{stroke:#fff;stroke-width:2px}.ct-series-a .suite--chart-slice---1XN2j{fill:#4caf50;fill:var(--green500)}.ct-series-b .suite--chart-slice---1XN2j{fill:#f44336;fill:var(--red500)}.ct-series-c .suite--chart-slice---1XN2j{fill:#03a9f4;fill:var(--ltblue500)}.ct-series-d .suite--chart-slice---1XN2j{fill:rgba(0,0,0,.38);fill:var(--black38)}@media (min-width:768px){.suite--chart-wrap---7hvUh{display:block}.suite--chart-enabled---1N-VF:not(.suite--no-tests---l47BS) .suite--header---TddSn{min-height:66px}} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.suite-summary--trans-color---14JXk{transition:color .2s ease-out;transition:var(--link-transition)}.suite-summary--component---cFAkx:after,.suite-summary--component---cFAkx:before{content:" ";display:table}.suite-summary--component---cFAkx:after{clear:both}.suite-summary--component---cFAkx{list-style:none;padding-left:0;display:-webkit-flex;display:flex;font-family:var(--font-family--regular);font-size:15px;margin:16px 0 0}.suite-summary--component---cFAkx.suite-summary--no-margin---3WX9n{margin:0}.suite-summary--summary-item---JHYFN{display:-webkit-flex;display:flex;line-height:18px;margin:0 8px;color:rgba(0,0,0,.54);color:var(--black54)}.suite-summary--summary-item---JHYFN:first-child{margin-left:0}.suite-summary--summary-item---JHYFN.suite-summary--duration---AzGUQ,.suite-summary--summary-item---JHYFN.suite-summary--tests---3Zhct{color:rgba(0,0,0,.54);color:var(--black54)}.suite-summary--summary-item---JHYFN.suite-summary--passed---24BnC{color:#4caf50;color:var(--green500)}.suite-summary--summary-item---JHYFN.suite-summary--failed---205C4{color:#f44336;color:var(--red500)}.suite-summary--summary-item---JHYFN.suite-summary--pending---3_Nkj{color:#03a9f4;color:var(--ltblue500)}.suite-summary--summary-item---JHYFN.suite-summary--skipped---TovqF{color:rgba(0,0,0,.38);color:var(--black38)}.suite-summary--icon---3rZ6G{margin-right:2px} +:root{--screen-sm-min:768px;--screen-md-min:992px;--screen-lg-min:1200px;--grid-gutter-width:30px;--container-sm:calc(720px + var(--grid-gutter-width));--container-md:calc(940px + var(--grid-gutter-width));--container-lg:calc(1140px + var(--grid-gutter-width));--navbar-height:122px;--navbar-height-short:56px;--summary-height-stacked:82px;--statusbar-height-stacked:54px;--footer-height:60px;--default-transition-duration:0.2s;--default-transition-easing:ease;--gray-base:#000;--gray-darker-faded:color(var(--gray-darker) alpha(95%));--gray-darker:color(var(--gray-base) tint(13.5%));--gray-dark:color(var(--gray-base) tint(20%));--gray:color(var(--gray-base) tint(33.5%));--gray-light:color(var(--gray-base) tint(46.7%));--gray-medium:color(var(--gray-base) tint(73.5%));--gray-lighter:color(var(--gray-base) tint(93.5%));--gray-lighter-faded:color(var(--gray-lighter) alpha(95%));--gray-border:color(var(--gray-base) tint(80%));--grey50:#eceff1;--grey100:#f5f5f5;--grey300:#e0e0e0;--grey500:#9e9e9e;--grey700:#616161;--green100:#c8e6c9;--green200:#a5d6a7;--green300:#81c784;--green500:#4caf50;--green700:#388e3c;--red100:#ffcdd2;--red300:#e57373;--red500:#f44336;--red700:#d32f2f;--ltblue100:#b3e5fc;--ltblue300:#4fc3f7;--ltblue500:#03a9f4;--ltblue700:#0288d1;--black87:rgba(0,0,0,0.87);--black54:rgba(0,0,0,0.54);--black38:rgba(0,0,0,0.38);--bluegrey500:#607d8b;--bluegrey800:#37474f;--bluegrey900:#263238;--light-icon-active:#fff;--light-icon-inactive:hsla(0,0%,100%,0.5);--dark-icon-active:var(--black54);--dark-icon-inactive:var(--black38);--amber300:#ffd54f;--amber400:#ffca28;--amber500:#ffc107;--yellow700:#fbc02d;--yellow800:#f9a825;--brand-primary:color(#428bca shade(6.5%));--brand-success:#4caf50;--brand-info:#5bc0de;--brand-warning:#f0ad4e;--brand-danger:#d9534f;--text-color:var(--black87);--body-bg:#f2f2f2;--link-color:var(--brand-primary);--link-hover-color:color(var(--link-color) shade(15%));--list-group-border:#ddd;--font-family-sans-serif:"robotoregular","Helvetica Neue",Helvetica,Arial,sans-serif;--font-family-base:var(--font-family-sans-serif);--font-family-mono:"Menlo","Monaco","Consolas","Courier New",monospace;--font-size-base:14px;--line-height-base:1.429;--line-height-computed:20px;--headings-font-family:inherit;--headings-font-weight:400;--headings-line-height:1.1;--headings-color:inherit;--headings-small-color:var(--gray-light);--font-size-h1:36px;--font-size-h2:30px;--font-size-h3:24px;--font-size-h4:18px;--font-size-h5:var(--font-size-base);--font-size-h6:12px;--font-family-light:"robotolight";--font-family-regular:"robotoregular";--font-family-medium:"robotomedium";--link-transition:color 0.2s ease-out}.toggle-switch--trans-color---16in9{transition:color .2s ease-out;transition:var(--link-transition)}.toggle-switch--component---3vjvh:after,.toggle-switch--component---3vjvh:before{content:" ";display:table}.toggle-switch--component---3vjvh:after{clear:both}.toggle-switch--component---3vjvh{height:24px}.toggle-switch--label---1Lu8U{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.toggle-switch--toggle-input---3BB7e{position:absolute;opacity:0}.toggle-switch--toggle-input---3BB7e:checked+.toggle-switch--toggle---2kPqc{background-color:#a5d6a7;background-color:var(--green200)}.toggle-switch--toggle-input---3BB7e:checked+.toggle-switch--toggle---2kPqc:before{background-color:#4caf50;background-color:var(--green500);-webkit-transform:translateX(14px);transform:translateX(14px)}.toggle-switch--toggle-input---3BB7e:focus+.toggle-switch--toggle---2kPqc:before{box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12),0 0 2px 0 #03a9f4;box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12),0 0 2px 0 var(--ltblue500)}.toggle-switch--toggle---2kPqc{display:inline-block;position:relative;background-color:#e0e0e0;background-color:var(--grey300);border-radius:7px;cursor:pointer;height:14px;margin-left:auto;transition:background-color .15s cubic-bezier(.4,0,.2,1) 0s;width:34px}.toggle-switch--toggle---2kPqc:before{box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);content:"";position:absolute;background-color:#9e9e9e;background-color:var(--grey500);border-radius:100%;height:20px;left:0;top:-3px;width:20px;transition:-webkit-transform .15s cubic-bezier(.4,0,.2,1) 0s;transition:transform .15s cubic-bezier(.4,0,.2,1) 0s;transition:transform .15s cubic-bezier(.4,0,.2,1) 0s,-webkit-transform .15s cubic-bezier(.4,0,.2,1) 0s}.toggle-switch--disabled---1qDLf{opacity:.6}.toggle-switch--disabled---1qDLf .toggle-switch--icon---348nT{color:rgba(0,0,0,.38);color:var(--black38)}.toggle-switch--disabled---1qDLf .toggle-switch--toggle---2kPqc{cursor:default} diff --git a/test-reports/assets/app.js b/test-reports/assets/app.js new file mode 100644 index 0000000..23de443 --- /dev/null +++ b/test-reports/assets/app.js @@ -0,0 +1,2 @@ +/*! mochawesome-report-generator 6.2.0 | https://github.com/adamgruber/mochawesome-report-generator */ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=320)}([function(e,t,n){"use strict";e.exports=n(126)},function(e,t,n){e.exports=n(130)()},function(e,t,n){var r=n(198),o=n(51),i=36e5,a=6e4,s=/[T ]/,l=/:/,u=/^(\d{2})$/,c=[/^([+-]\d{2})$/,/^([+-]\d{3})$/,/^([+-]\d{4})$/],f=/^(\d{4})/,d=[/^([+-]\d{4})/,/^([+-]\d{5})/,/^([+-]\d{6})/],p=/^-(\d{2})$/,h=/^-?(\d{3})$/,m=/^-?(\d{2})-?(\d{2})$/,v=/^-?W(\d{2})$/,g=/^-?W(\d{2})-?(\d{1})$/,y=/^(\d{2}([.,]\d*)?)$/,b=/^(\d{2}):?(\d{2}([.,]\d*)?)$/,_=/^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/,w=/([Z+-].*)$/,x=/^(Z)$/,E=/^([+-])(\d{2})$/,k=/^([+-])(\d{2}):?(\d{2})$/;function S(e,t,n){t=t||0,n=n||0;var r=new Date(0);r.setUTCFullYear(e,0,4);var o=7*t+n+1-(r.getUTCDay()||7);return r.setUTCDate(r.getUTCDate()+o),r}e.exports=function(e,t){if(o(e))return new Date(e.getTime());if("string"!=typeof e)return new Date(e);var n=(t||{}).additionalDigits;n=null==n?2:Number(n);var O=function(e){var t,n={},r=e.split(s);l.test(r[0])?(n.date=null,t=r[0]):(n.date=r[0],t=r[1]);if(t){var o=w.exec(t);o?(n.time=t.replace(o[1],""),n.timezone=o[1]):n.time=t}return n}(e),T=function(e,t){var n,r=c[t],o=d[t];if(n=f.exec(e)||o.exec(e)){var i=n[1];return{year:parseInt(i,10),restDateString:e.slice(i.length)}}if(n=u.exec(e)||r.exec(e)){var a=n[1];return{year:100*parseInt(a,10),restDateString:e.slice(a.length)}}return{year:null}}(O.date,n),N=T.year,C=function(e,t){if(null===t)return null;var n,r,o;if(0===e.length)return(r=new Date(0)).setUTCFullYear(t),r;if(n=p.exec(e))return r=new Date(0),o=parseInt(n[1],10)-1,r.setUTCFullYear(t,o),r;if(n=h.exec(e)){r=new Date(0);var i=parseInt(n[1],10);return r.setUTCFullYear(t,0,i),r}if(n=m.exec(e)){r=new Date(0),o=parseInt(n[1],10)-1;var a=parseInt(n[2],10);return r.setUTCFullYear(t,o,a),r}if(n=v.exec(e))return S(t,parseInt(n[1],10)-1);if(n=g.exec(e)){return S(t,parseInt(n[1],10)-1,parseInt(n[2],10)-1)}return null}(T.restDateString,N);if(C){var P,M=C.getTime(),j=0;if(O.time&&(j=function(e){var t,n,r;if(t=y.exec(e))return(n=parseFloat(t[1].replace(",",".")))%24*i;if(t=b.exec(e))return n=parseInt(t[1],10),r=parseFloat(t[2].replace(",",".")),n%24*i+r*a;if(t=_.exec(e)){n=parseInt(t[1],10),r=parseInt(t[2],10);var o=parseFloat(t[3].replace(",","."));return n%24*i+r*a+1e3*o}return null}(O.time)),O.timezone)P=function(e){var t,n;if(t=x.exec(e))return 0;if(t=E.exec(e))return n=60*parseInt(t[2],10),"+"===t[1]?-n:n;if(t=k.exec(e))return n=60*parseInt(t[2],10)+parseInt(t[3],10),"+"===t[1]?-n:n;return 0}(O.timezone)*a;else{var D=M+j,A=new Date(D);P=r(A);var I=new Date(D);I.setDate(A.getDate()+1);var R=r(I)-r(A);R>0&&(P+=R)}return new Date(M+j+P)}return new Date(e)}},function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}}function s(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a}var l=[];Object.freeze(l);var u={};function c(){return++_e.mobxGuid}function f(e){throw d(!1,e),"X"}function d(e,t){if(!e)throw new Error("[mobx] "+(t||"An invariant failed, however the error is obfuscated because this is an production build."))}Object.freeze(u);function p(e){var t=!1;return function(){if(!t)return t=!0,e.apply(this,arguments)}}var h=function(){};function m(e){return null!==e&&"object"==typeof e}function v(e){if(null===e||"object"!=typeof e)return!1;var t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function g(e,t,n){Object.defineProperty(e,t,{enumerable:!1,writable:!0,configurable:!0,value:n})}function y(e,t){var n="isMobX"+e;return t.prototype[n]=!0,function(e){return m(e)&&!0===e[n]}}function b(e){return e instanceof Map}function _(e){return e instanceof Set}function w(e){return null===e?null:"object"==typeof e?""+e:e}var x=Symbol("mobx administration"),E=function(){function e(e){void 0===e&&(e="Atom@"+c()),this.name=e,this.isPendingUnobservation=!1,this.isBeingObserved=!1,this.observers=new Set,this.diffValue=0,this.lastAccessedBy=0,this.lowestObserverState=te.NOT_TRACKING}return e.prototype.onBecomeObserved=function(){this.onBecomeObservedListeners&&this.onBecomeObservedListeners.forEach((function(e){return e()}))},e.prototype.onBecomeUnobserved=function(){this.onBecomeUnobservedListeners&&this.onBecomeUnobservedListeners.forEach((function(e){return e()}))},e.prototype.reportObserved=function(){return Te(this)},e.prototype.reportChanged=function(){Se(),function(e){if(e.lowestObserverState===te.STALE)return;e.lowestObserverState=te.STALE,e.observers.forEach((function(t){t.dependenciesState===te.UP_TO_DATE&&(t.isTracing!==re.NONE&&Ne(t,e),t.onBecomeStale()),t.dependenciesState=te.STALE}))}(this),Oe()},e.prototype.toString=function(){return this.name},e}(),k=y("Atom",E);function S(e,t,n){void 0===t&&(t=h),void 0===n&&(n=h);var r,o=new E(e);return t!==h&&$e("onBecomeObserved",o,t,r),n!==h&&function(e,t,n){$e("onBecomeUnobserved",e,t,n)}(o,n),o}var O={identity:function(e,t){return e===t},structural:function(e,t){return zt(e,t)},default:function(e,t){return Object.is(e,t)}},T=Symbol("mobx did run lazy initializers"),N=Symbol("mobx pending decorators"),C={},P={};function M(e,t){var n=t?C:P;return n[e]||(n[e]={configurable:!0,enumerable:t,get:function(){return j(this),this[e]},set:function(t){j(this),this[e]=t}})}function j(e){if(!0!==e[T]){var t=e[N];if(t)for(var n in g(e,T,!0),t){var r=t[n];r.propertyCreator(e,r.prop,r.descriptor,r.decoratorTarget,r.decoratorArguments)}}}function D(e,t){return function(){var n,r=function(r,o,a,s){if(!0===s)return t(r,o,a,r,n),null;if(!Object.prototype.hasOwnProperty.call(r,N)){var l=r[N];g(r,N,i({},l))}return r[N][o]={prop:o,propertyCreator:t,descriptor:a,decoratorTarget:r,decoratorArguments:n},M(o,e)};return A(arguments)?(n=l,r.apply(null,arguments)):(n=Array.prototype.slice.call(arguments),r)}}function A(e){return(2===e.length||3===e.length)&&"string"==typeof e[1]||4===e.length&&!0===e[3]}function I(e,t,n){return Ze(e)?e:Array.isArray(e)?$.array(e,{name:n}):v(e)?$.object(e,void 0,{name:n}):b(e)?$.map(e,{name:n}):_(e)?$.set(e,{name:n}):e}function R(e){return e}function z(t){d(t);var n=D(!0,(function(e,n,r,o,i){var a=r?r.initializer?r.initializer.call(e):r.value:void 0;Tt(e).addObservableProp(n,a,t)})),r=(void 0!==e&&e.env,n);return r.enhancer=t,r}var F={deep:!0,name:void 0,defaultDecorator:void 0,proxy:!0};function L(e){return null==e?F:"string"==typeof e?{name:e,deep:!0,proxy:!0}:e}Object.freeze(F);var U=z(I),B=z((function(e,t,n){return null==e||jt(e)||yt(e)||xt(e)||St(e)?e:Array.isArray(e)?$.array(e,{name:n,deep:!1}):v(e)?$.object(e,void 0,{name:n,deep:!1}):b(e)?$.map(e,{name:n,deep:!1}):_(e)?$.set(e,{name:n,deep:!1}):f(!1)})),H=z(R),V=z((function(e,t,n){return zt(e,t)?t:e}));function W(e){return e.defaultDecorator?e.defaultDecorator.enhancer:!1===e.deep?R:I}var Y={box:function(e,t){arguments.length>2&&q("box");var n=L(t);return new oe(e,W(n),n.name,!0,n.equals)},array:function(e,t){arguments.length>2&&q("array");var n=L(t);return pt(e,W(n),n.name)},map:function(e,t){arguments.length>2&&q("map");var n=L(t);return new wt(e,W(n),n.name)},set:function(e,t){arguments.length>2&&q("set");var n=L(t);return new kt(e,W(n),n.name)},object:function(e,t,n){"string"==typeof arguments[1]&&q("object");var r=L(n);if(!1===r.proxy)return Qe({},e,t,r);var o=Ge(r),i=Qe({},void 0,void 0,r),a=it(i);return Xe(a,e,t,o),a},ref:H,shallow:B,deep:U,struct:V},$=function(e,t,n){if("string"==typeof arguments[1])return U.apply(null,arguments);if(Ze(e))return e;var r=v(e)?$.object(e,t,n):Array.isArray(e)?$.array(e,t):b(e)?$.map(e,t):_(e)?$.set(e,t):e;if(r!==e)return r;f(!1)};function q(e){f("Expected one or two arguments to observable."+e+". Did you accidentally try to use observable."+e+" as decorator?")}Object.keys(Y).forEach((function(e){return $[e]=Y[e]}));var Q=D(!1,(function(e,t,n,r,o){var a=n.get,s=n.set,l=o[0]||{};Tt(e).addComputedProp(e,t,i({get:a,set:s,context:e},l))}));Q({equals:O.structural});function G(e,t){var n=function(){return X(e,t,this,arguments)};return n.isMobxAction=!0,n}function X(e,t,n,r){var o=function(e,t,n,r){var o=!1,i=0;var a=he();Se();var s=Z(!0);return{prevDerivation:a,prevAllowStateChanges:s,notifySpy:o,startTime:i}}(),i=!0;try{var a=t.apply(n,r);return i=!1,a}finally{i?(_e.suppressReactionErrors=i,K(o),_e.suppressReactionErrors=!1):K(o)}}function K(e){ee(e.prevAllowStateChanges),Oe(),me(e.prevDerivation),e.notifySpy}function J(e,t){var n,r=Z(e);try{n=t()}finally{ee(r)}return n}function Z(e){var t=_e.allowStateChanges;return _e.allowStateChanges=e,t}function ee(e){_e.allowStateChanges=e}var te,ne,re,oe=function(e){function t(t,n,r,o,i){void 0===r&&(r="ObservableValue@"+c()),void 0===o&&(o=!0),void 0===i&&(i=O.default);var a=e.call(this,r)||this;return a.enhancer=n,a.name=r,a.equals=i,a.hasUnreportedChange=!1,a.value=n(t,void 0,r),a}return function(e,t){function n(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}(t,e),t.prototype.dehanceValue=function(e){return void 0!==this.dehancer?this.dehancer(e):e},t.prototype.set=function(e){this.value;if((e=this.prepareNewValue(e))!==_e.UNCHANGED){false,this.setNewValue(e)}},t.prototype.prepareNewValue=function(e){if(ce(this),at(this)){var t=lt(this,{object:this,type:"update",newValue:e});if(!t)return _e.UNCHANGED;e=t.newValue}return e=this.enhancer(e,this.value,this.name),this.equals(this.value,e)?_e.UNCHANGED:e},t.prototype.setNewValue=function(e){var t=this.value;this.value=e,this.reportChanged(),ut(this)&&ft(this,{type:"update",object:this,newValue:e,oldValue:t})},t.prototype.get=function(){return this.reportObserved(),this.dehanceValue(this.value)},t.prototype.intercept=function(e){return st(this,e)},t.prototype.observe=function(e,t){return t&&e({object:this,type:"update",newValue:this.value,oldValue:void 0}),ct(this,e)},t.prototype.toJSON=function(){return this.get()},t.prototype.toString=function(){return this.name+"["+this.value+"]"},t.prototype.valueOf=function(){return w(this.get())},t.prototype[Symbol.toPrimitive]=function(){return this.valueOf()},t}(E),ie=(y("ObservableValue",oe),function(){function e(e){this.dependenciesState=te.NOT_TRACKING,this.observing=[],this.newObserving=null,this.isBeingObserved=!1,this.isPendingUnobservation=!1,this.observers=new Set,this.diffValue=0,this.runId=0,this.lastAccessedBy=0,this.lowestObserverState=te.UP_TO_DATE,this.unboundDepsCount=0,this.__mapid="#"+c(),this.value=new se(null),this.isComputing=!1,this.isRunningSetter=!1,this.isTracing=re.NONE,this.derivation=e.get,this.name=e.name||"ComputedValue@"+c(),e.set&&(this.setter=G(this.name+"-setter",e.set)),this.equals=e.equals||(e.compareStructural||e.struct?O.structural:O.default),this.scope=e.context,this.requiresReaction=!!e.requiresReaction,this.keepAlive=!!e.keepAlive}return e.prototype.onBecomeStale=function(){!function(e){if(e.lowestObserverState!==te.UP_TO_DATE)return;e.lowestObserverState=te.POSSIBLY_STALE,e.observers.forEach((function(t){t.dependenciesState===te.UP_TO_DATE&&(t.dependenciesState=te.POSSIBLY_STALE,t.isTracing!==re.NONE&&Ne(t,e),t.onBecomeStale())}))}(this)},e.prototype.onBecomeObserved=function(){this.onBecomeObservedListeners&&this.onBecomeObservedListeners.forEach((function(e){return e()}))},e.prototype.onBecomeUnobserved=function(){this.onBecomeUnobservedListeners&&this.onBecomeUnobservedListeners.forEach((function(e){return e()}))},e.prototype.get=function(){this.isComputing&&f("Cycle detected in computation "+this.name+": "+this.derivation),0!==_e.inBatch||0!==this.observers.size||this.keepAlive?(Te(this),ue(this)&&this.trackAndCompute()&&function(e){if(e.lowestObserverState===te.STALE)return;e.lowestObserverState=te.STALE,e.observers.forEach((function(t){t.dependenciesState===te.POSSIBLY_STALE?t.dependenciesState=te.STALE:t.dependenciesState===te.UP_TO_DATE&&(e.lowestObserverState=te.UP_TO_DATE)}))}(this)):ue(this)&&(this.warnAboutUntrackedRead(),Se(),this.value=this.computeValue(!1),Oe());var e=this.value;if(le(e))throw e.cause;return e},e.prototype.peek=function(){var e=this.computeValue(!1);if(le(e))throw e.cause;return e},e.prototype.set=function(e){if(this.setter){d(!this.isRunningSetter,"The setter of computed value '"+this.name+"' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?"),this.isRunningSetter=!0;try{this.setter.call(this.scope,e)}finally{this.isRunningSetter=!1}}else d(!1,!1)},e.prototype.trackAndCompute=function(){var e=this.value,t=this.dependenciesState===te.NOT_TRACKING,n=this.computeValue(!0),r=t||le(e)||le(n)||!this.equals(e,n);return r&&(this.value=n),r},e.prototype.computeValue=function(e){var t;if(this.isComputing=!0,_e.computationDepth++,e)t=fe(this,this.derivation,this.scope);else if(!0===_e.disableErrorBoundaries)t=this.derivation.call(this.scope);else try{t=this.derivation.call(this.scope)}catch(e){t=new se(e)}return _e.computationDepth--,this.isComputing=!1,t},e.prototype.suspend=function(){this.keepAlive||(de(this),this.value=void 0)},e.prototype.observe=function(e,t){var n=this,r=!0,o=void 0;return He((function(){var i=n.get();if(!r||t){var a=he();e({type:"update",object:n,newValue:i,oldValue:o}),me(a)}r=!1,o=i}))},e.prototype.warnAboutUntrackedRead=function(){},e.prototype.toJSON=function(){return this.get()},e.prototype.toString=function(){return this.name+"["+this.derivation.toString()+"]"},e.prototype.valueOf=function(){return w(this.get())},e.prototype[Symbol.toPrimitive]=function(){return this.valueOf()},e}()),ae=y("ComputedValue",ie);(ne=te||(te={}))[ne.NOT_TRACKING=-1]="NOT_TRACKING",ne[ne.UP_TO_DATE=0]="UP_TO_DATE",ne[ne.POSSIBLY_STALE=1]="POSSIBLY_STALE",ne[ne.STALE=2]="STALE",function(e){e[e.NONE=0]="NONE",e[e.LOG=1]="LOG",e[e.BREAK=2]="BREAK"}(re||(re={}));var se=function(e){this.cause=e};function le(e){return e instanceof se}function ue(e){switch(e.dependenciesState){case te.UP_TO_DATE:return!1;case te.NOT_TRACKING:case te.STALE:return!0;case te.POSSIBLY_STALE:for(var t=he(),n=e.observing,r=n.length,o=0;o0;_e.computationDepth>0&&t&&f(!1),_e.allowStateChanges||!t&&"strict"!==_e.enforceActions||f(!1)}function fe(e,t,n){ve(e),e.newObserving=new Array(e.observing.length+100),e.unboundDepsCount=0,e.runId=++_e.runId;var r,o=_e.trackingDerivation;if(_e.trackingDerivation=e,!0===_e.disableErrorBoundaries)r=t.call(n);else try{r=t.call(n)}catch(e){r=new se(e)}return _e.trackingDerivation=o,function(e){for(var t=e.observing,n=e.observing=e.newObserving,r=te.UP_TO_DATE,o=0,i=e.unboundDepsCount,a=0;ar&&(r=s.dependenciesState)}n.length=o,e.newObserving=null,i=t.length;for(;i--;){0===(s=t[i]).diffValue&&Ee(s,e),s.diffValue=0}for(;o--;){var s;1===(s=n[o]).diffValue&&(s.diffValue=0,xe(s,e))}r!==te.UP_TO_DATE&&(e.dependenciesState=r,e.onBecomeStale())}(e),r}function de(e){var t=e.observing;e.observing=[];for(var n=t.length;n--;)Ee(t[n],e);e.dependenciesState=te.NOT_TRACKING}function pe(e){var t=he();try{return e()}finally{me(t)}}function he(){var e=_e.trackingDerivation;return _e.trackingDerivation=null,e}function me(e){_e.trackingDerivation=e}function ve(e){if(e.dependenciesState!==te.UP_TO_DATE){e.dependenciesState=te.UP_TO_DATE;for(var t=e.observing,n=t.length;n--;)t[n].lowestObserverState=te.UP_TO_DATE}}var ge=function(){this.version=5,this.UNCHANGED={},this.trackingDerivation=null,this.computationDepth=0,this.runId=0,this.mobxGuid=0,this.inBatch=0,this.pendingUnobservations=[],this.pendingReactions=[],this.isRunningReactions=!1,this.allowStateChanges=!0,this.enforceActions=!1,this.spyListeners=[],this.globalReactionErrorHandlers=[],this.computedRequiresReaction=!1,this.disableErrorBoundaries=!1,this.suppressReactionErrors=!1},ye=!0,be=!1,_e=function(){var e=we();return e.__mobxInstanceCount>0&&!e.__mobxGlobals&&(ye=!1),e.__mobxGlobals&&e.__mobxGlobals.version!==(new ge).version&&(ye=!1),ye?e.__mobxGlobals?(e.__mobxInstanceCount+=1,e.__mobxGlobals.UNCHANGED||(e.__mobxGlobals.UNCHANGED={}),e.__mobxGlobals):(e.__mobxInstanceCount=1,e.__mobxGlobals=new ge):(setTimeout((function(){be||f("There are multiple, different versions of MobX active. Make sure MobX is loaded only once or use `configure({ isolateGlobalState: true })`")}),1),new ge)}();function we(){return"undefined"!=typeof window?window:r}function xe(e,t){e.observers.add(t),e.lowestObserverState>t.dependenciesState&&(e.lowestObserverState=t.dependenciesState)}function Ee(e,t){e.observers.delete(t),0===e.observers.size&&ke(e)}function ke(e){!1===e.isPendingUnobservation&&(e.isPendingUnobservation=!0,_e.pendingUnobservations.push(e))}function Se(){_e.inBatch++}function Oe(){if(0==--_e.inBatch){je();for(var e=_e.pendingUnobservations,t=0;t0&&ke(e),!1)}function Ne(e,t){if(console.log("[mobx.trace] '"+e.name+"' is invalidated due to a change in: '"+t.name+"'"),e.isTracing===re.BREAK){var n=[];Ce(Ke(Dt(e,r)),n,1),new Function("debugger;\n/*\nTracing '"+e.name+"'\n\nYou are entering this break point because derivation '"+e.name+"' is being traced and '"+t.name+"' is now forcing it to update.\nJust follow the stacktrace you should now see in the devtools to see precisely what piece of your code is causing this update\nThe stackframe you are looking for is at least ~6-8 stack-frames up.\n\n"+(e instanceof ie?e.derivation.toString().replace(/[*]\//g,"/"):"")+"\n\nThe dependencies for this derivation are:\n\n"+n.join("\n")+"\n*/\n ")()}var r}function Ce(e,t,n){t.length>=1e3?t.push("(and many more)"):(t.push(""+new Array(n).join("\t")+e.name),e.dependencies&&e.dependencies.forEach((function(e){return Ce(e,t,n+1)})))}var Pe=function(){function e(e,t,n){void 0===e&&(e="Reaction@"+c()),this.name=e,this.onInvalidate=t,this.errorHandler=n,this.observing=[],this.newObserving=[],this.dependenciesState=te.NOT_TRACKING,this.diffValue=0,this.runId=0,this.unboundDepsCount=0,this.__mapid="#"+c(),this.isDisposed=!1,this._isScheduled=!1,this._isTrackPending=!1,this._isRunning=!1,this.isTracing=re.NONE}return e.prototype.onBecomeStale=function(){this.schedule()},e.prototype.schedule=function(){this._isScheduled||(this._isScheduled=!0,_e.pendingReactions.push(this),je())},e.prototype.isScheduled=function(){return this._isScheduled},e.prototype.runReaction=function(){if(!this.isDisposed){if(Se(),this._isScheduled=!1,ue(this)){this._isTrackPending=!0;try{this.onInvalidate(),this._isTrackPending}catch(e){this.reportExceptionInDerivation(e)}}Oe()}},e.prototype.track=function(e){Se();this._isRunning=!0;var t=fe(this,e,void 0);this._isRunning=!1,this._isTrackPending=!1,this.isDisposed&&de(this),le(t)&&this.reportExceptionInDerivation(t.cause),Oe()},e.prototype.reportExceptionInDerivation=function(e){var t=this;if(this.errorHandler)this.errorHandler(e,this);else{if(_e.disableErrorBoundaries)throw e;var n="[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '"+this+"'";_e.suppressReactionErrors?console.warn("[mobx] (error in reaction '"+this.name+"' suppressed, fix error of causing action below)"):console.error(n,e),_e.globalReactionErrorHandlers.forEach((function(n){return n(e,t)}))}},e.prototype.dispose=function(){this.isDisposed||(this.isDisposed=!0,this._isRunning||(Se(),de(this),Oe()))},e.prototype.getDisposer=function(){var e=this.dispose.bind(this);return e[x]=this,e},e.prototype.toString=function(){return"Reaction["+this.name+"]"},e.prototype.trace=function(e){void 0===e&&(e=!1),function(){for(var e=[],t=0;t0||_e.isRunningReactions||Me(De)}function De(){_e.isRunningReactions=!0;for(var e=_e.pendingReactions,t=0;e.length>0;){100==++t&&(console.error("Reaction doesn't converge to a stable state after 100 iterations. Probably there is a cycle in the reactive function: "+e[0]),e.splice(0));for(var n=e.splice(0),r=0,o=n.length;r",e):2===arguments.length&&"function"==typeof t?G(e,t):1===arguments.length&&"string"==typeof e?Fe(e):!0!==r?Fe(t).apply(null,arguments):void g(e,t,G(e.name||t,n.value))};function Be(e,t,n){g(e,t,G(t,n.bind(e)))}function He(e,t){void 0===t&&(t=u);var n,r=t&&t.name||e.name||"Autorun@"+c();if(!t.scheduler&&!t.delay)n=new Pe(r,(function(){this.track(a)}),t.onError);else{var o=We(t),i=!1;n=new Pe(r,(function(){i||(i=!0,o((function(){i=!1,n.isDisposed||n.track(a)})))}),t.onError)}function a(){e(n)}return n.schedule(),n.getDisposer()}Ue.bound=function(e,t,n,r){return!0===r?(Be(e,t,n.value),null):n?{configurable:!0,enumerable:!1,get:function(){return Be(this,t,n.value||n.initializer.call(this)),this[t]},set:ze}:{enumerable:!1,configurable:!0,set:function(e){Be(this,t,e)},get:function(){}}};var Ve=function(e){return e()};function We(e){return e.scheduler?e.scheduler:e.delay?function(t){return setTimeout(t,e.delay)}:Ve}function Ye(e,t,n){void 0===n&&(n=u);var r,o,i,a=n.name||"Reaction@"+c(),s=Ue(a,n.onError?(r=n.onError,o=t,function(){try{return o.apply(this,arguments)}catch(e){r.call(this,e)}}):t),l=!n.scheduler&&!n.delay,f=We(n),d=!0,p=!1,h=n.compareStructural?O.structural:n.equals||O.default,m=new Pe(a,(function(){d||l?v():p||(p=!0,f(v))}),n.onError);function v(){if(p=!1,!m.isDisposed){var t=!1;m.track((function(){var n=e(m);t=d||!h(i,n),i=n})),d&&n.fireImmediately&&s(i,m),d||!0!==t||s(i,m),d&&(d=!1)}}return m.schedule(),m.getDisposer()}function $e(e,t,n,r){var o="string"==typeof n?Dt(t,n):Dt(t),i="string"==typeof n?r:n,a=e+"Listeners";return o[a]?o[a].add(i):o[a]=new Set([i]),"function"!=typeof o[e]?f(!1):function(){var e=o[a];e&&(e.delete(i),0===e.size&&delete o[a])}}function qe(e){var t=e.enforceActions,n=e.computedRequiresReaction,r=e.disableErrorBoundaries,o=e.reactionScheduler;if(!0===e.isolateGlobalState&&((_e.pendingReactions.length||_e.inBatch||_e.isRunningReactions)&&f("isolateGlobalState should be called before MobX is running any reactions"),be=!0,ye&&(0==--we().__mobxInstanceCount&&(we().__mobxGlobals=void 0),_e=new ge)),void 0!==t){var i=void 0;switch(t){case!0:case"observed":i=!0;break;case!1:case"never":i=!1;break;case"strict":case"always":i="strict";break;default:f("Invalid value for 'enforceActions': '"+t+"', expected 'never', 'always' or 'observed'")}_e.enforceActions=i,_e.allowStateChanges=!0!==i&&"strict"!==i}void 0!==n&&(_e.computedRequiresReaction=!!n),void 0!==r&&(!0===r&&console.warn("WARNING: Debug feature only. MobX will NOT recover from errors when `disableErrorBoundaries` is enabled."),_e.disableErrorBoundaries=!!r),o&&Ie(o)}function Qe(e,t,n,r){var o=Ge(r=L(r));return j(e),Tt(e,r.name,o.enhancer),t&&Xe(e,t,n,o),e}function Ge(e){return e.defaultDecorator||(!1===e.deep?H:U)}function Xe(e,t,n,r){Se();try{for(var o in t){var i=Object.getOwnPropertyDescriptor(t,o);0;var a=(n&&o in n?n[o]:i.get?Q:r)(e,o,i,!0);a&&Object.defineProperty(e,o,a)}}finally{Oe()}}function Ke(e){var t,n,r={name:e.name};return e.observing&&e.observing.length>0&&(r.dependencies=(t=e.observing,n=[],t.forEach((function(e){-1===n.indexOf(e)&&n.push(e)})),n).map(Ke)),r}function Je(e,t){return null!=e&&(void 0!==t?!!jt(e)&&e[x].values.has(t):jt(e)||!!e[x]||k(e)||Ae(e)||ae(e))}function Ze(e){return 1!==arguments.length&&f(!1),Je(e)}function et(e,t,n){if(2!==arguments.length)if(jt(e)){var r=e[x],o=r.values.get(t);o?r.write(t,n):r.addObservableProp(t,n,r.defaultEnhancer)}else if(xt(e))e.set(t,n);else{if(!yt(e))return f(!1);"number"!=typeof t&&(t=parseInt(t,10)),d(t>=0,"Not a valid index: '"+t+"'"),Se(),t>=e.length&&(e.length=t+1),e[t]=n,Oe()}else{Se();var i=t;try{for(var a in i)et(e,a,i[a])}finally{Oe()}}}function tt(e){switch(e.length){case 0:return _e.trackingDerivation;case 1:return Dt(e[0]);case 2:return Dt(e[0],e[1])}}function nt(e,t){void 0===t&&(t=void 0),Se();try{return e.apply(t)}finally{Oe()}}function rt(e){return e[x]}var ot={has:function(e,t){if(t===x||"constructor"===t||t===T)return!0;var n=rt(e);return"string"==typeof t?n.has(t):t in e},get:function(e,t){if(t===x||"constructor"===t||t===T)return e[t];var n=rt(e),r=n.values.get(t);if(r instanceof E){var o=r.get();return void 0===o&&n.has(t),o}return"string"==typeof t&&n.has(t),e[t]},set:function(e,t,n){return"string"==typeof t&&(et(e,t,n),!0)},deleteProperty:function(e,t){return"string"==typeof t&&(rt(e).remove(t),!0)},ownKeys:function(e){return rt(e).keysAtom.reportObserved(),Reflect.ownKeys(e)},preventExtensions:function(e){return f("Dynamic observable objects cannot be frozen"),!1}};function it(e){var t=new Proxy(e,ot);return e[x].proxy=t,t}function at(e){return void 0!==e.interceptors&&e.interceptors.length>0}function st(e,t){var n=e.interceptors||(e.interceptors=[]);return n.push(t),p((function(){var e=n.indexOf(t);-1!==e&&n.splice(e,1)}))}function lt(e,t){var n=he();try{var r=e.interceptors;if(r)for(var o=0,i=r.length;o0}function ct(e,t){var n=e.changeListeners||(e.changeListeners=[]);return n.push(t),p((function(){var e=n.indexOf(t);-1!==e&&n.splice(e,1)}))}function ft(e,t){var n=he(),r=e.changeListeners;if(r){for(var o=0,i=(r=r.slice()).length;o0?e.map(this.dehancer):e},e.prototype.intercept=function(e){return st(this,e)},e.prototype.observe=function(e,t){return void 0===t&&(t=!1),t&&e({object:this.proxy,type:"splice",index:0,added:this.values.slice(),addedCount:this.values.length,removed:[],removedCount:0}),ct(this,e)},e.prototype.getArrayLength=function(){return this.atom.reportObserved(),this.values.length},e.prototype.setArrayLength=function(e){if("number"!=typeof e||e<0)throw new Error("[mobx.array] Out of range: "+e);var t=this.values.length;if(e!==t)if(e>t){for(var n=new Array(e-t),r=0;ro?e=o:e<0&&(e=Math.max(0,o+e)),t=1===arguments.length?o-e:null==t?0:Math.max(0,Math.min(t,o-e)),void 0===n&&(n=l),at(this)){var i=lt(this,{object:this.proxy,type:"splice",index:e,removedCount:t,added:n});if(!i)return l;t=i.removedCount,n=i.added}n=0===n.length?n:n.map((function(e){return r.enhancer(e,void 0)}));var a=this.spliceItemsIntoValues(e,t,n);return 0===t&&0===n.length||this.notifyArraySplice(e,n,a),this.dehanceValues(a)},e.prototype.spliceItemsIntoValues=function(e,t,n){var r;if(n.length<1e4)return(r=this.values).splice.apply(r,function(){for(var e=[],t=0;t-1&&(this.splice(n,1),!0)},get:function(e){var t=this[x];if(t){if(e=a.getTime()?n+1:t.getTime()>=l.getTime()?n:n-1}},function(e,t,n){var r=n(34);e.exports=function(e){return r(e,{weekStartsOn:1})}},function(e,t,n){var r=n(2);e.exports=function(e){var t=r(e);return t.setHours(0,0,0,0),t}},function(e,t,n){"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}(),e.exports=n(127)},function(e,t,n){var r=n(27),o=n(132),i=n(133),a=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":a&&a in Object(e)?o(e):i(e)}},function(e,t){e.exports=function(e){return null!=e&&"object"==typeof e}},function(e,t,n){var r=n(140),o=n(143);e.exports=function(e,t){var n=o(e,t);return r(n)?n:void 0}},function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;to?1:0}},function(e,t,n){var r=n(62);e.exports=function(e,t,n){var o=null==e?void 0:r(e,t);return void 0===o?n:o}},function(e,t,n){!function(e){"object"==typeof window&&window||"object"==typeof self&&self;(function(e){var t,n=[],r=Object.keys,o={},i={},a=/^(no-?highlight|plain|text)$/i,s=/\blang(?:uage)?-([\w-]+)\b/i,l=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,u="",c={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function f(e){return e.replace(/&/g,"&").replace(//g,">")}function d(e){return e.nodeName.toLowerCase()}function p(e,t){var n=e&&e.exec(t);return n&&0===n.index}function h(e){return a.test(e)}function m(e){var t,n,r,o,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",n=s.exec(i))return j(n[1])?n[1]:"no-highlight";for(t=0,r=(i=i.split(/\s+/)).length;t"}function u(e){i+=""}function c(e){("start"===e.event?l:u)(e.node)}for(;e.length||t.length;){var p=s();if(i+=f(r.substring(o,p[0].offset)),o=p[0].offset,p===e){a.reverse().forEach(u);do{c(p.splice(0,1)[0]),p=s()}while(p===e&&p.length&&p[0].offset===o);a.reverse().forEach(l)}else"start"===p[0].event?a.push(p[0].node):a.pop(),c(p.splice(0,1)[0])}return i+f(r.substr(o))}function b(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(t){return v(e,{variants:null},t)}))),e.cached_variants||e.endsWithParent&&[v(e)]||[e]}function _(e){if(t&&!e.langApiRestored){for(var n in e.langApiRestored=!0,t)e[n]&&(e[t[n]]=e[n]);(e.contains||[]).concat(e.variants||[]).forEach(_)}}function w(e){function t(e){return e&&e.source||e}function n(n,r){return new RegExp(t(n),"m"+(e.case_insensitive?"i":"")+(r?"g":""))}function o(e,n){for(var r=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,o=0,i="",a=0;a0&&(i+=n);l.length>0;){var u=r.exec(l);if(null==u){i+=l;break}i+=l.substring(0,u.index),l=l.substring(u.index+u[0].length),"\\"==u[0][0]&&u[1]?i+="\\"+String(Number(u[1])+s):(i+=u[0],"("==u[0]&&o++)}}return i}function i(a,s){if(!a.compiled){if(a.compiled=!0,a.keywords=a.keywords||a.beginKeywords,a.keywords){var l={},u=function(t,n){e.case_insensitive&&(n=n.toLowerCase()),n.split(" ").forEach((function(e){var n=e.split("|");l[n[0]]=[t,n[1]?Number(n[1]):1]}))};"string"==typeof a.keywords?u("keyword",a.keywords):r(a.keywords).forEach((function(e){u(e,a.keywords[e])})),a.keywords=l}a.lexemesRe=n(a.lexemes||/\w+/,!0),s&&(a.beginKeywords&&(a.begin="\\b("+a.beginKeywords.split(" ").join("|")+")\\b"),a.begin||(a.begin=/\B|\b/),a.beginRe=n(a.begin),a.endSameAsBegin&&(a.end=a.begin),a.end||a.endsWithParent||(a.end=/\B|\b/),a.end&&(a.endRe=n(a.end)),a.terminator_end=t(a.end)||"",a.endsWithParent&&s.terminator_end&&(a.terminator_end+=(a.end?"|":"")+s.terminator_end)),a.illegal&&(a.illegalRe=n(a.illegal)),null==a.relevance&&(a.relevance=1),a.contains||(a.contains=[]),a.contains=Array.prototype.concat.apply([],a.contains.map((function(e){return b("self"===e?a:e)}))),a.contains.forEach((function(e){i(e,a)})),a.starts&&i(a.starts,s);var c=a.contains.map((function(e){return e.beginKeywords?"\\.?(?:"+e.begin+")\\.?":e.begin})).concat([a.terminator_end,a.illegal]).map(t).filter(Boolean);a.terminators=c.length?n(o(c,"|"),!0):{exec:function(){return null}}}}i(e)}function x(e,t,n,r){function i(e){return new RegExp(e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")}function a(e,t){var n,r;for(n=0,r=t.contains.length;n')+t+(n?"":u)}function m(){var e,t,n,r;if(!S.keywords)return f(N);for(r="",t=0,S.lexemesRe.lastIndex=0,n=S.lexemesRe.exec(N);n;)r+=f(N.substring(t,n.index)),(e=d(S,n))?(C+=e[1],r+=h(e[0],f(n[0]))):r+=f(n[0]),t=S.lexemesRe.lastIndex,n=S.lexemesRe.exec(N);return r+f(N.substr(t))}function v(){var e="string"==typeof S.subLanguage;if(e&&!o[S.subLanguage])return f(N);var t=e?x(S.subLanguage,N,!0,O[S.subLanguage]):E(N,S.subLanguage.length?S.subLanguage:void 0);return S.relevance>0&&(C+=t.relevance),e&&(O[S.subLanguage]=t.top),h(t.language,t.value,!1,!0)}function g(){T+=null!=S.subLanguage?v():m(),N=""}function y(e){T+=e.className?h(e.className,"",!0):"",S=Object.create(e,{parent:{value:S}})}function b(e,t){if(N+=e,null==t)return g(),0;var n=a(t,S);if(n)return n.skip?N+=t:(n.excludeBegin&&(N+=t),g(),n.returnBegin||n.excludeBegin||(N=t)),y(n,t),n.returnBegin?0:t.length;var r=s(S,t);if(r){var o=S;o.skip?N+=t:(o.returnEnd||o.excludeEnd||(N+=t),g(),o.excludeEnd&&(N=t));do{S.className&&(T+=u),S.skip||S.subLanguage||(C+=S.relevance),S=S.parent}while(S!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.endRe=r.endRe),y(r.starts,"")),o.returnEnd?0:t.length}if(l(t,S))throw new Error('Illegal lexeme "'+t+'" for mode "'+(S.className||"")+'"');return N+=t,t.length||1}var _=j(e);if(!_)throw new Error('Unknown language: "'+e+'"');w(_);var k,S=r||_,O={},T="";for(k=S;k!==_;k=k.parent)k.className&&(T=h(k.className,"",!0)+T);var N="",C=0;try{for(var P,M,D=0;S.terminators.lastIndex=D,P=S.terminators.exec(t);)M=b(t.substring(D,P.index),P[0]),D=P.index+M;for(b(t.substr(D)),k=S;k.parent;k=k.parent)k.className&&(T+=u);return{relevance:C,value:T,language:e,top:S}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{relevance:0,value:f(t)};throw e}}function E(e,t){t=t||c.languages||r(o);var n={relevance:0,value:f(e)},i=n;return t.filter(j).filter(D).forEach((function(t){var r=x(t,e,!1);r.language=t,r.relevance>i.relevance&&(i=r),r.relevance>n.relevance&&(i=n,n=r)})),i.language&&(n.second_best=i),n}function k(e){return c.tabReplace||c.useBR?e.replace(l,(function(e,t){return c.useBR&&"\n"===e?"
":c.tabReplace?t.replace(/\t/g,c.tabReplace):""})):e}function S(e,t,n){var r=t?i[t]:n,o=[e.trim()];return e.match(/\bhljs\b/)||o.push("hljs"),-1===e.indexOf(r)&&o.push(r),o.join(" ").trim()}function O(e){var t,n,r,o,i,a=m(e);h(a)||(c.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"):t=e,i=t.textContent,r=a?x(a,i,!0):E(i),(n=g(t)).length&&((o=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=r.value,r.value=y(n,g(o),i)),r.value=k(r.value),e.innerHTML=r.value,e.className=S(e.className,a,r.language),e.result={language:r.language,re:r.relevance},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.relevance}))}function T(e){c=v(c,e)}function N(){if(!N.called){N.called=!0;var e=document.querySelectorAll("pre code");n.forEach.call(e,O)}}function C(){addEventListener("DOMContentLoaded",N,!1),addEventListener("load",N,!1)}function P(t,n){var r=o[t]=n(e);_(r),r.aliases&&r.aliases.forEach((function(e){i[e]=t}))}function M(){return r(o)}function j(e){return e=(e||"").toLowerCase(),o[e]||o[i[e]]}function D(e){var t=j(e);return t&&!t.disableAutodetect}e.highlight=x,e.highlightAuto=E,e.fixMarkup=k,e.highlightBlock=O,e.configure=T,e.initHighlighting=N,e.initHighlightingOnLoad=C,e.registerLanguage=P,e.listLanguages=M,e.getLanguage=j,e.autoDetection=D,e.inherit=v,e.IDENT_RE="[a-zA-Z]\\w*",e.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",e.NUMBER_RE="\\b\\d+(\\.\\d+)?",e.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BINARY_NUMBER_RE="\\b(0b[01]+)",e.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BACKSLASH_ESCAPE={begin:"\\\\[\\s\\S]",relevance:0},e.APOS_STRING_MODE={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},e.QUOTE_STRING_MODE={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},e.PHRASAL_WORDS_MODE={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.COMMENT=function(t,n,r){var o=e.inherit({className:"comment",begin:t,end:n,contains:[]},r||{});return o.contains.push(e.PHRASAL_WORDS_MODE),o.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|XXX):",relevance:0}),o},e.C_LINE_COMMENT_MODE=e.COMMENT("//","$"),e.C_BLOCK_COMMENT_MODE=e.COMMENT("/\\*","\\*/"),e.HASH_COMMENT_MODE=e.COMMENT("#","$"),e.NUMBER_MODE={className:"number",begin:e.NUMBER_RE,relevance:0},e.C_NUMBER_MODE={className:"number",begin:e.C_NUMBER_RE,relevance:0},e.BINARY_NUMBER_MODE={className:"number",begin:e.BINARY_NUMBER_RE,relevance:0},e.CSS_NUMBER_MODE={className:"number",begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},e.REGEXP_MODE={className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0,contains:[e.BACKSLASH_ESCAPE]}]},e.TITLE_MODE={className:"title",begin:e.IDENT_RE,relevance:0},e.UNDERSCORE_TITLE_MODE={className:"title",begin:e.UNDERSCORE_IDENT_RE,relevance:0},e.METHOD_GUARD={begin:"\\.\\s*"+e.UNDERSCORE_IDENT_RE,relevance:0}})(t)}()},function(e,t,n){var r=n(14),o=n(15);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},function(e,t,n){var r=n(8).Symbol;e.exports=r},function(e,t,n){var r=n(16)(Object,"create");e.exports=r},function(e,t){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},function(e,t,n){var r=n(148),o=n(149),i=n(150),a=n(151),s=n(152);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e<=9007199254740991}},function(e,t,n){var r=n(38),o=n(49);e.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},function(e,t){e.exports=function(e){return e instanceof Date}},function(e,t,n){var r=n(2);e.exports=function(e){var t=r(e),n=t.getFullYear(),o=t.getMonth(),i=new Date(0);return i.setFullYear(n,o+1,0),i.setHours(0,0,0,0),i.getDate()}},function(e,t,n){var r=n(20);e.exports=function(e,t){var n=Number(t);return r(e,7*n)}},function(e,t,n){var r=n(2);e.exports=function(e,t){var n=r(e).getTime(),o=r(t).getTime();return n>o?-1:n0?Math.floor(n):Math.ceil(n)}},function(e,t,n){var r=n(211),o=n(212);e.exports={distanceInWords:r(),format:o()}},function(e,t,n){var r=n(2);e.exports=function(e){var t=r(e);return t.setHours(23,59,59,999),t}},function(e,t,n){var r=n(2),o=n(11),i=n(22);e.exports=function(e){var t=r(e),n=o(t).getTime()-i(t).getTime();return Math.round(n/6048e5)+1}},function(e,t,n){var r=n(34);e.exports=function(e,t,n){var o=r(e,n),i=r(t,n);return o.getTime()===i.getTime()}},function(e,t,n){"use strict";var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,s,l=a(e),u=1;uc))return!1;var d=l.get(e);if(d&&l.get(t))return d==t;var p=-1,h=!0,m=2&n?new r:void 0;for(l.set(e,t),l.set(t,e);++p-1&&e%1==0&&e0?(p=o(e),h=o(t)):(p=o(t),h=o(e));var v,g=i(h,p),y=h.getTimezoneOffset()-p.getTimezoneOffset(),b=Math.round(g/60)-y;if(b<2)return u.includeSeconds?g<5?d("lessThanXSeconds",5,m):g<10?d("lessThanXSeconds",10,m):g<20?d("lessThanXSeconds",20,m):g<40?d("halfAMinute",null,m):d(g<60?"lessThanXMinutes":"xMinutes",1,m):0===b?d("lessThanXMinutes",1,m):d("xMinutes",b,m);if(b<45)return d("xMinutes",b,m);if(b<90)return d("aboutXHours",1,m);if(b<1440)return d("aboutXHours",Math.round(b/60),m);if(b<2520)return d("xDays",1,m);if(b{if(!Number.isFinite(e))throw new TypeError("Expected a finite number");t.colonNotation&&(t.compact=!1,t.formatSubMilliseconds=!1,t.separateMilliseconds=!1,t.verbose=!1),t.compact&&(t.secondsDecimalDigits=0,t.millisecondsDecimalDigits=0);const n=[],o=(e,r,o,i)=>{if(!(0!==n.length&&t.colonNotation||0!==e||t.colonNotation&&"m"===o))return;let a,s;if(i=(i||e||"0").toString(),t.colonNotation){a=n.length>0?":":"",s="";const e=i.includes(".")?i.split(".")[0].length:i.length,t=n.length>0?2:1;i="0".repeat(Math.max(0,t-e))+i}else a="",s=t.verbose?" "+(l=r,1===e?l:`${l}s`):o;var l;n.push(a+i+s)},i=r(e);if(o(Math.trunc(i.days/365),"year","y"),o(i.days%365,"day","d"),o(i.hours,"hour","h"),o(i.minutes,"minute","m"),t.separateMilliseconds||t.formatSubMilliseconds||e<1e3)if(o(i.seconds,"second","s"),t.formatSubMilliseconds)o(i.milliseconds,"millisecond","ms"),o(i.microseconds,"microsecond","µs"),o(i.nanoseconds,"nanosecond","ns");else{const e=i.milliseconds+i.microseconds/1e3+i.nanoseconds/1e6,n="number"==typeof t.millisecondsDecimalDigits?t.millisecondsDecimalDigits:0,r=e>=1?Math.round(e):Math.ceil(e),a=n?e.toFixed(n):r;o(Number.parseFloat(a,10),"millisecond","ms",a)}else{const n=((e,t)=>{const n=Math.floor(e*10**t+1e-7);return(Math.round(n)/10**t).toFixed(t)})(e/1e3%60,"number"==typeof t.secondsDecimalDigits?t.secondsDecimalDigits:1),r=t.keepDecimalsOnWholeSeconds?n:n.replace(/\.0+$/,"");o(Number.parseFloat(r,10),"second","s",r)}if(0===n.length)return"0"+(t.verbose?" milliseconds":"ms");if(t.compact)return n[0];if("number"==typeof t.unitCount){const e=t.colonNotation?"":" ";return n.slice(0,Math.max(t.unitCount,1)).join(e)}return t.colonNotation?n.join(""):n.join(" ")}},function(e,t,n){e.exports={"trans-color":"footer--trans-color---205XF",component:"footer--component---1WcTR"}},function(e){e.exports={"3d_rotation":"e84d",ac_unit:"eb3b",access_alarm:"e190",access_alarms:"e191",access_time:"e192",accessibility:"e84e",accessible:"e914",account_balance:"e84f",account_balance_wallet:"e850",account_box:"e851",account_circle:"e853",adb:"e60e",add:"e145",add_a_photo:"e439",add_alarm:"e193",add_alert:"e003",add_box:"e146",add_circle:"e147",add_circle_outline:"e148",add_location:"e567",add_shopping_cart:"e854",add_to_photos:"e39d",add_to_queue:"e05c",adjust:"e39e",airline_seat_flat:"e630",airline_seat_flat_angled:"e631",airline_seat_individual_suite:"e632",airline_seat_legroom_extra:"e633",airline_seat_legroom_normal:"e634",airline_seat_legroom_reduced:"e635",airline_seat_recline_extra:"e636",airline_seat_recline_normal:"e637",airplanemode_active:"e195",airplanemode_inactive:"e194",airplay:"e055",airport_shuttle:"eb3c",alarm:"e855",alarm_add:"e856",alarm_off:"e857",alarm_on:"e858",album:"e019",all_inclusive:"eb3d",all_out:"e90b",android:"e859",announcement:"e85a",apps:"e5c3",archive:"e149",arrow_back:"e5c4",arrow_downward:"e5db",arrow_drop_down:"e5c5",arrow_drop_down_circle:"e5c6",arrow_drop_up:"e5c7",arrow_forward:"e5c8",arrow_upward:"e5d8",art_track:"e060",aspect_ratio:"e85b",assessment:"e85c",assignment:"e85d",assignment_ind:"e85e",assignment_late:"e85f",assignment_return:"e860",assignment_returned:"e861",assignment_turned_in:"e862",assistant:"e39f",assistant_photo:"e3a0",attach_file:"e226",attach_money:"e227",attachment:"e2bc",audiotrack:"e3a1",autorenew:"e863",av_timer:"e01b",backspace:"e14a",backup:"e864",battery_alert:"e19c",battery_charging_full:"e1a3",battery_full:"e1a4",battery_std:"e1a5",battery_unknown:"e1a6",beach_access:"eb3e",beenhere:"e52d",block:"e14b",bluetooth:"e1a7",bluetooth_audio:"e60f",bluetooth_connected:"e1a8",bluetooth_disabled:"e1a9",bluetooth_searching:"e1aa",blur_circular:"e3a2",blur_linear:"e3a3",blur_off:"e3a4",blur_on:"e3a5",book:"e865",bookmark:"e866",bookmark_border:"e867",border_all:"e228",border_bottom:"e229",border_clear:"e22a",border_color:"e22b",border_horizontal:"e22c",border_inner:"e22d",border_left:"e22e",border_outer:"e22f",border_right:"e230",border_style:"e231",border_top:"e232",border_vertical:"e233",branding_watermark:"e06b",brightness_1:"e3a6",brightness_2:"e3a7",brightness_3:"e3a8",brightness_4:"e3a9",brightness_5:"e3aa",brightness_6:"e3ab",brightness_7:"e3ac",brightness_auto:"e1ab",brightness_high:"e1ac",brightness_low:"e1ad",brightness_medium:"e1ae",broken_image:"e3ad",brush:"e3ae",bubble_chart:"e6dd",bug_report:"e868",build:"e869",burst_mode:"e43c",business:"e0af",business_center:"eb3f",cached:"e86a",cake:"e7e9",call:"e0b0",call_end:"e0b1",call_made:"e0b2",call_merge:"e0b3",call_missed:"e0b4",call_missed_outgoing:"e0e4",call_received:"e0b5",call_split:"e0b6",call_to_action:"e06c",camera:"e3af",camera_alt:"e3b0",camera_enhance:"e8fc",camera_front:"e3b1",camera_rear:"e3b2",camera_roll:"e3b3",cancel:"e5c9",card_giftcard:"e8f6",card_membership:"e8f7",card_travel:"e8f8",casino:"eb40",cast:"e307",cast_connected:"e308",center_focus_strong:"e3b4",center_focus_weak:"e3b5",change_history:"e86b",chat:"e0b7",chat_bubble:"e0ca",chat_bubble_outline:"e0cb",check:"e5ca",check_box:"e834",check_box_outline_blank:"e835",check_circle:"e86c",chevron_left:"e5cb",chevron_right:"e5cc",child_care:"eb41",child_friendly:"eb42",chrome_reader_mode:"e86d",class:"e86e",clear:"e14c",clear_all:"e0b8",close:"e5cd",closed_caption:"e01c",cloud:"e2bd",cloud_circle:"e2be",cloud_done:"e2bf",cloud_download:"e2c0",cloud_off:"e2c1",cloud_queue:"e2c2",cloud_upload:"e2c3",code:"e86f",collections:"e3b6",collections_bookmark:"e431",color_lens:"e3b7",colorize:"e3b8",comment:"e0b9",compare:"e3b9",compare_arrows:"e915",computer:"e30a",confirmation_number:"e638",contact_mail:"e0d0",contact_phone:"e0cf",contacts:"e0ba",content_copy:"e14d",content_cut:"e14e",content_paste:"e14f",control_point:"e3ba",control_point_duplicate:"e3bb",copyright:"e90c",create:"e150",create_new_folder:"e2cc",credit_card:"e870",crop:"e3be",crop_16_9:"e3bc",crop_3_2:"e3bd",crop_5_4:"e3bf",crop_7_5:"e3c0",crop_din:"e3c1",crop_free:"e3c2",crop_landscape:"e3c3",crop_original:"e3c4",crop_portrait:"e3c5",crop_rotate:"e437",crop_square:"e3c6",dashboard:"e871",data_usage:"e1af",date_range:"e916",dehaze:"e3c7",delete:"e872",delete_forever:"e92b",delete_sweep:"e16c",description:"e873",desktop_mac:"e30b",desktop_windows:"e30c",details:"e3c8",developer_board:"e30d",developer_mode:"e1b0",device_hub:"e335",devices:"e1b1",devices_other:"e337",dialer_sip:"e0bb",dialpad:"e0bc",directions:"e52e",directions_bike:"e52f",directions_boat:"e532",directions_bus:"e530",directions_car:"e531",directions_railway:"e534",directions_run:"e566",directions_subway:"e533",directions_transit:"e535",directions_walk:"e536",disc_full:"e610",dns:"e875",do_not_disturb:"e612",do_not_disturb_alt:"e611",do_not_disturb_off:"e643",do_not_disturb_on:"e644",dock:"e30e",domain:"e7ee",done:"e876",done_all:"e877",donut_large:"e917",donut_small:"e918",drafts:"e151",drag_handle:"e25d",drive_eta:"e613",dvr:"e1b2",edit:"e3c9",edit_location:"e568",eject:"e8fb",email:"e0be",enhanced_encryption:"e63f",equalizer:"e01d",error:"e000",error_outline:"e001",euro_symbol:"e926",ev_station:"e56d",event:"e878",event_available:"e614",event_busy:"e615",event_note:"e616",event_seat:"e903",exit_to_app:"e879",expand_less:"e5ce",expand_more:"e5cf",explicit:"e01e",explore:"e87a",exposure:"e3ca",exposure_neg_1:"e3cb",exposure_neg_2:"e3cc",exposure_plus_1:"e3cd",exposure_plus_2:"e3ce",exposure_zero:"e3cf",extension:"e87b",face:"e87c",fast_forward:"e01f",fast_rewind:"e020",favorite:"e87d",favorite_border:"e87e",featured_play_list:"e06d",featured_video:"e06e",feedback:"e87f",fiber_dvr:"e05d",fiber_manual_record:"e061",fiber_new:"e05e",fiber_pin:"e06a",fiber_smart_record:"e062",file_download:"e2c4",file_upload:"e2c6",filter:"e3d3",filter_1:"e3d0",filter_2:"e3d1",filter_3:"e3d2",filter_4:"e3d4",filter_5:"e3d5",filter_6:"e3d6",filter_7:"e3d7",filter_8:"e3d8",filter_9:"e3d9",filter_9_plus:"e3da",filter_b_and_w:"e3db",filter_center_focus:"e3dc",filter_drama:"e3dd",filter_frames:"e3de",filter_hdr:"e3df",filter_list:"e152",filter_none:"e3e0",filter_tilt_shift:"e3e2",filter_vintage:"e3e3",find_in_page:"e880",find_replace:"e881",fingerprint:"e90d",first_page:"e5dc",fitness_center:"eb43",flag:"e153",flare:"e3e4",flash_auto:"e3e5",flash_off:"e3e6",flash_on:"e3e7",flight:"e539",flight_land:"e904",flight_takeoff:"e905",flip:"e3e8",flip_to_back:"e882",flip_to_front:"e883",folder:"e2c7",folder_open:"e2c8",folder_shared:"e2c9",folder_special:"e617",font_download:"e167",format_align_center:"e234",format_align_justify:"e235",format_align_left:"e236",format_align_right:"e237",format_bold:"e238",format_clear:"e239",format_color_fill:"e23a",format_color_reset:"e23b",format_color_text:"e23c",format_indent_decrease:"e23d",format_indent_increase:"e23e",format_italic:"e23f",format_line_spacing:"e240",format_list_bulleted:"e241",format_list_numbered:"e242",format_paint:"e243",format_quote:"e244",format_shapes:"e25e",format_size:"e245",format_strikethrough:"e246",format_textdirection_l_to_r:"e247",format_textdirection_r_to_l:"e248",format_underlined:"e249",forum:"e0bf",forward:"e154",forward_10:"e056",forward_30:"e057",forward_5:"e058",free_breakfast:"eb44",fullscreen:"e5d0",fullscreen_exit:"e5d1",functions:"e24a",g_translate:"e927",gamepad:"e30f",games:"e021",gavel:"e90e",gesture:"e155",get_app:"e884",gif:"e908",golf_course:"eb45",gps_fixed:"e1b3",gps_not_fixed:"e1b4",gps_off:"e1b5",grade:"e885",gradient:"e3e9",grain:"e3ea",graphic_eq:"e1b8",grid_off:"e3eb",grid_on:"e3ec",group:"e7ef",group_add:"e7f0",group_work:"e886",hd:"e052",hdr_off:"e3ed",hdr_on:"e3ee",hdr_strong:"e3f1",hdr_weak:"e3f2",headset:"e310",headset_mic:"e311",healing:"e3f3",hearing:"e023",help:"e887",help_outline:"e8fd",high_quality:"e024",highlight:"e25f",highlight_off:"e888",history:"e889",home:"e88a",hot_tub:"eb46",hotel:"e53a",hourglass_empty:"e88b",hourglass_full:"e88c",http:"e902",https:"e88d",image:"e3f4",image_aspect_ratio:"e3f5",import_contacts:"e0e0",import_export:"e0c3",important_devices:"e912",inbox:"e156",indeterminate_check_box:"e909",info:"e88e",info_outline:"e88f",input:"e890",insert_chart:"e24b",insert_comment:"e24c",insert_drive_file:"e24d",insert_emoticon:"e24e",insert_invitation:"e24f",insert_link:"e250",insert_photo:"e251",invert_colors:"e891",invert_colors_off:"e0c4",iso:"e3f6",keyboard:"e312",keyboard_arrow_down:"e313",keyboard_arrow_left:"e314",keyboard_arrow_right:"e315",keyboard_arrow_up:"e316",keyboard_backspace:"e317",keyboard_capslock:"e318",keyboard_hide:"e31a",keyboard_return:"e31b",keyboard_tab:"e31c",keyboard_voice:"e31d",kitchen:"eb47",label:"e892",label_outline:"e893",landscape:"e3f7",language:"e894",laptop:"e31e",laptop_chromebook:"e31f",laptop_mac:"e320",laptop_windows:"e321",last_page:"e5dd",launch:"e895",layers:"e53b",layers_clear:"e53c",leak_add:"e3f8",leak_remove:"e3f9",lens:"e3fa",library_add:"e02e",library_books:"e02f",library_music:"e030",lightbulb_outline:"e90f",line_style:"e919",line_weight:"e91a",linear_scale:"e260",link:"e157",linked_camera:"e438",list:"e896",live_help:"e0c6",live_tv:"e639",local_activity:"e53f",local_airport:"e53d",local_atm:"e53e",local_bar:"e540",local_cafe:"e541",local_car_wash:"e542",local_convenience_store:"e543",local_dining:"e556",local_drink:"e544",local_florist:"e545",local_gas_station:"e546",local_grocery_store:"e547",local_hospital:"e548",local_hotel:"e549",local_laundry_service:"e54a",local_library:"e54b",local_mall:"e54c",local_movies:"e54d",local_offer:"e54e",local_parking:"e54f",local_pharmacy:"e550",local_phone:"e551",local_pizza:"e552",local_play:"e553",local_post_office:"e554",local_printshop:"e555",local_see:"e557",local_shipping:"e558",local_taxi:"e559",location_city:"e7f1",location_disabled:"e1b6",location_off:"e0c7",location_on:"e0c8",location_searching:"e1b7",lock:"e897",lock_open:"e898",lock_outline:"e899",looks:"e3fc",looks_3:"e3fb",looks_4:"e3fd",looks_5:"e3fe",looks_6:"e3ff",looks_one:"e400",looks_two:"e401",loop:"e028",loupe:"e402",low_priority:"e16d",loyalty:"e89a",mail:"e158",mail_outline:"e0e1",map:"e55b",markunread:"e159",markunread_mailbox:"e89b",memory:"e322",menu:"e5d2",merge_type:"e252",message:"e0c9",mic:"e029",mic_none:"e02a",mic_off:"e02b",mms:"e618",mode_comment:"e253",mode_edit:"e254",monetization_on:"e263",money_off:"e25c",monochrome_photos:"e403",mood:"e7f2",mood_bad:"e7f3",more:"e619",more_horiz:"e5d3",more_vert:"e5d4",motorcycle:"e91b",mouse:"e323",move_to_inbox:"e168",movie:"e02c",movie_creation:"e404",movie_filter:"e43a",multiline_chart:"e6df",music_note:"e405",music_video:"e063",my_location:"e55c",nature:"e406",nature_people:"e407",navigate_before:"e408",navigate_next:"e409",navigation:"e55d",near_me:"e569",network_cell:"e1b9",network_check:"e640",network_locked:"e61a",network_wifi:"e1ba",new_releases:"e031",next_week:"e16a",nfc:"e1bb",no_encryption:"e641",no_sim:"e0cc",not_interested:"e033",note:"e06f",note_add:"e89c",notifications:"e7f4",notifications_active:"e7f7",notifications_none:"e7f5",notifications_off:"e7f6",notifications_paused:"e7f8",offline_pin:"e90a",ondemand_video:"e63a",opacity:"e91c",open_in_browser:"e89d",open_in_new:"e89e",open_with:"e89f",pages:"e7f9",pageview:"e8a0",palette:"e40a",pan_tool:"e925",panorama:"e40b",panorama_fish_eye:"e40c",panorama_horizontal:"e40d",panorama_vertical:"e40e",panorama_wide_angle:"e40f",party_mode:"e7fa",pause:"e034",pause_circle_filled:"e035",pause_circle_outline:"e036",payment:"e8a1",people:"e7fb",people_outline:"e7fc",perm_camera_mic:"e8a2",perm_contact_calendar:"e8a3",perm_data_setting:"e8a4",perm_device_information:"e8a5",perm_identity:"e8a6",perm_media:"e8a7",perm_phone_msg:"e8a8",perm_scan_wifi:"e8a9",person:"e7fd",person_add:"e7fe",person_outline:"e7ff",person_pin:"e55a",person_pin_circle:"e56a",personal_video:"e63b",pets:"e91d",phone:"e0cd",phone_android:"e324",phone_bluetooth_speaker:"e61b",phone_forwarded:"e61c",phone_in_talk:"e61d",phone_iphone:"e325",phone_locked:"e61e",phone_missed:"e61f",phone_paused:"e620",phonelink:"e326",phonelink_erase:"e0db",phonelink_lock:"e0dc",phonelink_off:"e327",phonelink_ring:"e0dd",phonelink_setup:"e0de",photo:"e410",photo_album:"e411",photo_camera:"e412",photo_filter:"e43b",photo_library:"e413",photo_size_select_actual:"e432",photo_size_select_large:"e433",photo_size_select_small:"e434",picture_as_pdf:"e415",picture_in_picture:"e8aa",picture_in_picture_alt:"e911",pie_chart:"e6c4",pie_chart_outlined:"e6c5",pin_drop:"e55e",place:"e55f",play_arrow:"e037",play_circle_filled:"e038",play_circle_outline:"e039",play_for_work:"e906",playlist_add:"e03b",playlist_add_check:"e065",playlist_play:"e05f",plus_one:"e800",poll:"e801",polymer:"e8ab",pool:"eb48",portable_wifi_off:"e0ce",portrait:"e416",power:"e63c",power_input:"e336",power_settings_new:"e8ac",pregnant_woman:"e91e",present_to_all:"e0df",print:"e8ad",priority_high:"e645",public:"e80b",publish:"e255",query_builder:"e8ae",question_answer:"e8af",queue:"e03c",queue_music:"e03d",queue_play_next:"e066",radio:"e03e",radio_button_checked:"e837",radio_button_unchecked:"e836",rate_review:"e560",receipt:"e8b0",recent_actors:"e03f",record_voice_over:"e91f",redeem:"e8b1",redo:"e15a",refresh:"e5d5",remove:"e15b",remove_circle:"e15c",remove_circle_outline:"e15d",remove_from_queue:"e067",remove_red_eye:"e417",remove_shopping_cart:"e928",reorder:"e8fe",repeat:"e040",repeat_one:"e041",replay:"e042",replay_10:"e059",replay_30:"e05a",replay_5:"e05b",reply:"e15e",reply_all:"e15f",report:"e160",report_problem:"e8b2",restaurant:"e56c",restaurant_menu:"e561",restore:"e8b3",restore_page:"e929",ring_volume:"e0d1",room:"e8b4",room_service:"eb49",rotate_90_degrees_ccw:"e418",rotate_left:"e419",rotate_right:"e41a",rounded_corner:"e920",router:"e328",rowing:"e921",rss_feed:"e0e5",rv_hookup:"e642",satellite:"e562",save:"e161",scanner:"e329",schedule:"e8b5",school:"e80c",screen_lock_landscape:"e1be",screen_lock_portrait:"e1bf",screen_lock_rotation:"e1c0",screen_rotation:"e1c1",screen_share:"e0e2",sd_card:"e623",sd_storage:"e1c2",search:"e8b6",security:"e32a",select_all:"e162",send:"e163",sentiment_dissatisfied:"e811",sentiment_neutral:"e812",sentiment_satisfied:"e813",sentiment_very_dissatisfied:"e814",sentiment_very_satisfied:"e815",settings:"e8b8",settings_applications:"e8b9",settings_backup_restore:"e8ba",settings_bluetooth:"e8bb",settings_brightness:"e8bd",settings_cell:"e8bc",settings_ethernet:"e8be",settings_input_antenna:"e8bf",settings_input_component:"e8c0",settings_input_composite:"e8c1",settings_input_hdmi:"e8c2",settings_input_svideo:"e8c3",settings_overscan:"e8c4",settings_phone:"e8c5",settings_power:"e8c6",settings_remote:"e8c7",settings_system_daydream:"e1c3",settings_voice:"e8c8",share:"e80d",shop:"e8c9",shop_two:"e8ca",shopping_basket:"e8cb",shopping_cart:"e8cc",short_text:"e261",show_chart:"e6e1",shuffle:"e043",signal_cellular_4_bar:"e1c8",signal_cellular_connected_no_internet_4_bar:"e1cd",signal_cellular_no_sim:"e1ce",signal_cellular_null:"e1cf",signal_cellular_off:"e1d0",signal_wifi_4_bar:"e1d8",signal_wifi_4_bar_lock:"e1d9",signal_wifi_off:"e1da",sim_card:"e32b",sim_card_alert:"e624",skip_next:"e044",skip_previous:"e045",slideshow:"e41b",slow_motion_video:"e068",smartphone:"e32c",smoke_free:"eb4a",smoking_rooms:"eb4b",sms:"e625",sms_failed:"e626",snooze:"e046",sort:"e164",sort_by_alpha:"e053",spa:"eb4c",space_bar:"e256",speaker:"e32d",speaker_group:"e32e",speaker_notes:"e8cd",speaker_notes_off:"e92a",speaker_phone:"e0d2",spellcheck:"e8ce",star:"e838",star_border:"e83a",star_half:"e839",stars:"e8d0",stay_current_landscape:"e0d3",stay_current_portrait:"e0d4",stay_primary_landscape:"e0d5",stay_primary_portrait:"e0d6",stop:"e047",stop_screen_share:"e0e3",storage:"e1db",store:"e8d1",store_mall_directory:"e563",straighten:"e41c",streetview:"e56e",strikethrough_s:"e257",style:"e41d",subdirectory_arrow_left:"e5d9",subdirectory_arrow_right:"e5da",subject:"e8d2",subscriptions:"e064",subtitles:"e048",subway:"e56f",supervisor_account:"e8d3",surround_sound:"e049",swap_calls:"e0d7",swap_horiz:"e8d4",swap_vert:"e8d5",swap_vertical_circle:"e8d6",switch_camera:"e41e",switch_video:"e41f",sync:"e627",sync_disabled:"e628",sync_problem:"e629",system_update:"e62a",system_update_alt:"e8d7",tab:"e8d8",tab_unselected:"e8d9",tablet:"e32f",tablet_android:"e330",tablet_mac:"e331",tag_faces:"e420",tap_and_play:"e62b",terrain:"e564",text_fields:"e262",text_format:"e165",textsms:"e0d8",texture:"e421",theaters:"e8da",thumb_down:"e8db",thumb_up:"e8dc",thumbs_up_down:"e8dd",time_to_leave:"e62c",timelapse:"e422",timeline:"e922",timer:"e425",timer_10:"e423",timer_3:"e424",timer_off:"e426",title:"e264",toc:"e8de",today:"e8df",toll:"e8e0",tonality:"e427",touch_app:"e913",toys:"e332",track_changes:"e8e1",traffic:"e565",train:"e570",tram:"e571",transfer_within_a_station:"e572",transform:"e428",translate:"e8e2",trending_down:"e8e3",trending_flat:"e8e4",trending_up:"e8e5",tune:"e429",turned_in:"e8e6",turned_in_not:"e8e7",tv:"e333",unarchive:"e169",undo:"e166",unfold_less:"e5d6",unfold_more:"e5d7",update:"e923",usb:"e1e0",verified_user:"e8e8",vertical_align_bottom:"e258",vertical_align_center:"e259",vertical_align_top:"e25a",vibration:"e62d",video_call:"e070",video_label:"e071",video_library:"e04a",videocam:"e04b",videocam_off:"e04c",videogame_asset:"e338",view_agenda:"e8e9",view_array:"e8ea",view_carousel:"e8eb",view_column:"e8ec",view_comfy:"e42a",view_compact:"e42b",view_day:"e8ed",view_headline:"e8ee",view_list:"e8ef",view_module:"e8f0",view_quilt:"e8f1",view_stream:"e8f2",view_week:"e8f3",vignette:"e435",visibility:"e8f4",visibility_off:"e8f5",voice_chat:"e62e",voicemail:"e0d9",volume_down:"e04d",volume_mute:"e04e",volume_off:"e04f",volume_up:"e050",vpn_key:"e0da",vpn_lock:"e62f",wallpaper:"e1bc",warning:"e002",watch:"e334",watch_later:"e924",wb_auto:"e42c",wb_cloudy:"e42d",wb_incandescent:"e42e",wb_iridescent:"e436",wb_sunny:"e430",wc:"e63d",web:"e051",web_asset:"e069",weekend:"e16b",whatshot:"e80e",widgets:"e1bd",wifi:"e63e",wifi_lock:"e1e1",wifi_tethering:"e1e2",work:"e8f9",wrap_text:"e25b",youtube_searched_for:"e8fa",zoom_in:"e8ff",zoom_out:"e900",zoom_out_map:"e56b"}},function(e,t,n){e.exports={"trans-color":"loader--trans-color---97r08",component:"loader--component---2grcA",wrap:"loader--wrap---3Fhrc",text:"loader--text---3Yu3g",spinner:"loader--spinner---2q6MO",spin:"loader--spin---K6Loh"}},function(e,t,n){e.exports={addDays:n(20),addHours:n(75),addISOYears:n(76),addMilliseconds:n(21),addMinutes:n(78),addMonths:n(36),addQuarters:n(79),addSeconds:n(80),addWeeks:n(53),addYears:n(81),areRangesOverlapping:n(199),closestIndexTo:n(200),closestTo:n(201),compareAsc:n(23),compareDesc:n(54),differenceInCalendarDays:n(35),differenceInCalendarISOWeeks:n(202),differenceInCalendarISOYears:n(82),differenceInCalendarMonths:n(83),differenceInCalendarQuarters:n(203),differenceInCalendarWeeks:n(204),differenceInCalendarYears:n(85),differenceInDays:n(86),differenceInHours:n(205),differenceInISOYears:n(206),differenceInMilliseconds:n(37),differenceInMinutes:n(207),differenceInMonths:n(55),differenceInQuarters:n(208),differenceInSeconds:n(56),differenceInWeeks:n(209),differenceInYears:n(210),distanceInWords:n(88),distanceInWordsStrict:n(214),distanceInWordsToNow:n(215),eachDay:n(216),endOfDay:n(58),endOfHour:n(217),endOfISOWeek:n(218),endOfISOYear:n(219),endOfMinute:n(220),endOfMonth:n(90),endOfQuarter:n(221),endOfSecond:n(222),endOfToday:n(223),endOfTomorrow:n(224),endOfWeek:n(89),endOfYear:n(225),endOfYesterday:n(226),format:n(227),getDate:n(228),getDay:n(229),getDayOfYear:n(91),getDaysInMonth:n(52),getDaysInYear:n(230),getHours:n(231),getISODay:n(95),getISOWeek:n(59),getISOWeeksInYear:n(232),getISOYear:n(10),getMilliseconds:n(233),getMinutes:n(234),getMonth:n(235),getOverlappingDaysInRanges:n(236),getQuarter:n(84),getSeconds:n(237),getTime:n(238),getYear:n(239),isAfter:n(240),isBefore:n(241),isDate:n(51),isEqual:n(242),isFirstDayOfMonth:n(243),isFriday:n(244),isFuture:n(245),isLastDayOfMonth:n(246),isLeapYear:n(94),isMonday:n(247),isPast:n(248),isSameDay:n(249),isSameHour:n(96),isSameISOWeek:n(98),isSameISOYear:n(99),isSameMinute:n(100),isSameMonth:n(102),isSameQuarter:n(103),isSameSecond:n(105),isSameWeek:n(60),isSameYear:n(107),isSaturday:n(250),isSunday:n(251),isThisHour:n(252),isThisISOWeek:n(253),isThisISOYear:n(254),isThisMinute:n(255),isThisMonth:n(256),isThisQuarter:n(257),isThisSecond:n(258),isThisWeek:n(259),isThisYear:n(260),isThursday:n(261),isToday:n(262),isTomorrow:n(263),isTuesday:n(264),isValid:n(93),isWednesday:n(265),isWeekend:n(266),isWithinRange:n(267),isYesterday:n(268),lastDayOfISOWeek:n(269),lastDayOfISOYear:n(270),lastDayOfMonth:n(271),lastDayOfQuarter:n(272),lastDayOfWeek:n(108),lastDayOfYear:n(273),max:n(274),min:n(275),parse:n(2),setDate:n(276),setDay:n(277),setDayOfYear:n(278),setHours:n(279),setISODay:n(280),setISOWeek:n(281),setISOYear:n(77),setMilliseconds:n(282),setMinutes:n(283),setMonth:n(109),setQuarter:n(284),setSeconds:n(285),setYear:n(286),startOfDay:n(12),startOfHour:n(97),startOfISOWeek:n(11),startOfISOYear:n(22),startOfMinute:n(101),startOfMonth:n(287),startOfQuarter:n(104),startOfSecond:n(106),startOfToday:n(288),startOfTomorrow:n(289),startOfWeek:n(34),startOfYear:n(92),startOfYesterday:n(290),subDays:n(291),subHours:n(292),subISOYears:n(87),subMilliseconds:n(293),subMinutes:n(294),subMonths:n(295),subQuarters:n(296),subSeconds:n(297),subWeeks:n(298),subYears:n(299)}},function(e,t,n){var r=n(300)(n(312));e.exports=r},function(e,t,n){e.exports={"trans-color":"navbar--trans-color---1tk7E",component:"navbar--component---2UCEi","report-info-cnt":"navbar--report-info-cnt---8y9Bb","menu-button":"navbar--menu-button---1ZRpz","report-title":"navbar--report-title---3bXCv","pct-bar":"navbar--pct-bar---3EwW-",pass:"navbar--pass---2oR-w",fail:"navbar--fail---3mN80",pend:"navbar--pend---2iqjh","pct-bar-segment":"navbar--pct-bar-segment---3T0_o"}},function(e,t,n){e.exports={"trans-color":"quick-summary--trans-color---HUJqE",cnt:"quick-summary--cnt---3s38x",list:"quick-summary--list---2_80W",item:"quick-summary--item---bfSQ0",icon:"quick-summary--icon---TW1oG",tests:"quick-summary--tests---2nNut",passes:"quick-summary--passes---3IjYH","single-filter":"quick-summary--single-filter---31Thy","single-filter--passed":"quick-summary--single-filter--passed---3QnUL",failures:"quick-summary--failures---14s29","single-filter--failed":"quick-summary--single-filter--failed---3_tAw",pending:"quick-summary--pending---261aV","single-filter--pending":"quick-summary--single-filter--pending---21lZM",skipped:"quick-summary--skipped---tyOc4","single-filter--skipped":"quick-summary--single-filter--skipped---1AdZA","circle-icon":"quick-summary--circle-icon---1HDS7"}},function(e,t,n){e.exports={"trans-color":"radio-button--trans-color---egsik",component:"radio-button--component---1ix3c",outer:"radio-button--outer---a_NqL",off:"radio-button--off---dBAOK",inner:"radio-button--inner---3bo9Q"}},function(e,t,n){var r,o;o=this,void 0===(r=function(){return o.Chartist=(e={version:"0.11.0"},function(e,t,n){"use strict";n.namespaces={svg:"http://www.w3.org/2000/svg",xmlns:"http://www.w3.org/2000/xmlns/",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",ct:"http://gionkunz.github.com/chartist-js/ct"},n.noop=function(e){return e},n.alphaNumerate=function(e){return String.fromCharCode(97+e%26)},n.extend=function(e){var t,r,o;for(e=e||{},t=1;t":">",'"':""","'":"'"},n.serialize=function(e){return null==e?e:("number"==typeof e?e=""+e:"object"==typeof e&&(e=JSON.stringify({data:e})),Object.keys(n.escapingMap).reduce((function(e,t){return n.replaceAll(e,t,n.escapingMap[t])}),e))},n.deserialize=function(e){if("string"!=typeof e)return e;e=Object.keys(n.escapingMap).reduce((function(e,t){return n.replaceAll(e,n.escapingMap[t],t)}),e);try{e=void 0!==(e=JSON.parse(e)).data?e.data:e}catch(e){}return e},n.createSvg=function(e,t,r,o){var i;return t=t||"100%",r=r||"100%",Array.prototype.slice.call(e.querySelectorAll("svg")).filter((function(e){return e.getAttributeNS(n.namespaces.xmlns,"ct")})).forEach((function(t){e.removeChild(t)})),(i=new n.Svg("svg").attr({width:t,height:r}).addClass(o))._node.style.width=t,i._node.style.height=r,e.appendChild(i._node),i},n.normalizeData=function(e,t,r){var o,i={raw:e,normalized:{}};return i.normalized.series=n.getDataArray({series:e.series||[]},t,r),o=i.normalized.series.every((function(e){return e instanceof Array}))?Math.max.apply(null,i.normalized.series.map((function(e){return e.length}))):i.normalized.series.length,i.normalized.labels=(e.labels||[]).slice(),Array.prototype.push.apply(i.normalized.labels,n.times(Math.max(0,o-i.normalized.labels.length)).map((function(){return""}))),t&&n.reverseData(i.normalized),i},n.safeHasProperty=function(e,t){return null!==e&&"object"==typeof e&&e.hasOwnProperty(t)},n.isDataHoleValue=function(e){return null==e||"number"==typeof e&&isNaN(e)},n.reverseData=function(e){e.labels.reverse(),e.series.reverse();for(var t=0;to.high&&(o.high=n),a&&n0||(o.high=1),o.low=0)),o},n.isNumeric=function(e){return null!==e&&isFinite(e)},n.isFalseyButZero=function(e){return!e&&0!==e},n.getNumberOrUndefined=function(e){return n.isNumeric(e)?+e:void 0},n.isMultiValue=function(e){return"object"==typeof e&&("x"in e||"y"in e)},n.getMultiValue=function(e,t){return n.isMultiValue(e)?n.getNumberOrUndefined(e[t||"y"]):n.getNumberOrUndefined(e)},n.rho=function(e){if(1===e)return e;function t(e,n){return e%n==0?n:t(n,e%n)}function n(e){return e*e+1}var r,o=2,i=2;if(e%2==0)return 2;do{o=n(o)%e,i=n(n(i))%e,r=t(Math.abs(o-i),e)}while(1===r);return r},n.getBounds=function(e,t,r,o){var i,a,s,l=0,u={high:t.high,low:t.low};u.valueRange=u.high-u.low,u.oom=n.orderOfMagnitude(u.valueRange),u.step=Math.pow(10,u.oom),u.min=Math.floor(u.low/u.step)*u.step,u.max=Math.ceil(u.high/u.step)*u.step,u.range=u.max-u.min,u.numberOfSteps=Math.round(u.range/u.step);var c=n.projectLength(e,u.step,u)=r)u.step=1;else if(o&&f=r)u.step=f;else for(;;){if(c&&n.projectLength(e,u.step,u)<=r)u.step*=2;else{if(c||!(n.projectLength(e,u.step/2,u)>=r))break;if(u.step/=2,o&&u.step%1!=0){u.step*=2;break}}if(l++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}var d=2221e-19;function p(e,t){return e===(e+=t)&&(e*=1+(t>0?d:-d)),e}for(u.step=Math.max(u.step,d),a=u.min,s=u.max;a+u.step<=u.low;)a=p(a,u.step);for(;s-u.step>=u.high;)s=p(s,-u.step);u.min=a,u.max=s,u.range=u.max-u.min;var h=[];for(i=u.min;i<=u.max;i=p(i,u.step)){var m=n.roundWithPrecision(i);m!==h[h.length-1]&&h.push(m)}return u.values=h,u},n.polarToCartesian=function(e,t,n,r){var o=(r-90)*Math.PI/180;return{x:e+n*Math.cos(o),y:t+n*Math.sin(o)}},n.createChartRect=function(e,t,r){var o=!(!t.axisX&&!t.axisY),i=o?t.axisY.offset:0,a=o?t.axisX.offset:0,s=e.width()||n.quantity(t.width).value||0,l=e.height()||n.quantity(t.height).value||0,u=n.normalizePadding(t.chartPadding,r);s=Math.max(s,i+u.left+u.right),l=Math.max(l,a+u.top+u.bottom);var c={padding:u,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return o?("start"===t.axisX.position?(c.y2=u.top+a,c.y1=Math.max(l-u.bottom,c.y2+1)):(c.y2=u.top,c.y1=Math.max(l-u.bottom-a,c.y2+1)),"start"===t.axisY.position?(c.x1=u.left+i,c.x2=Math.max(s-u.right,c.x1+1)):(c.x1=u.left,c.x2=Math.max(s-u.right-i,c.x1+1))):(c.x1=u.left,c.x2=Math.max(s-u.right,c.x1+1),c.y2=u.top,c.y1=Math.max(l-u.bottom,c.y2+1)),c},n.createGrid=function(e,t,r,o,i,a,s,l){var u={};u[r.units.pos+"1"]=e,u[r.units.pos+"2"]=e,u[r.counterUnits.pos+"1"]=o,u[r.counterUnits.pos+"2"]=o+i;var c=a.elem("line",u,s.join(" "));l.emit("draw",n.extend({type:"grid",axis:r,index:t,group:a,element:c},u))},n.createGridBackground=function(e,t,n,r){var o=e.elem("rect",{x:t.x1,y:t.y2,width:t.width(),height:t.height()},n,!0);r.emit("draw",{type:"gridBackground",group:e,element:o})},n.createLabel=function(e,r,o,i,a,s,l,u,c,f,d){var p,h={};if(h[a.units.pos]=e+l[a.units.pos],h[a.counterUnits.pos]=l[a.counterUnits.pos],h[a.units.len]=r,h[a.counterUnits.len]=Math.max(0,s-10),f){var m=t.createElement("span");m.className=c.join(" "),m.setAttribute("xmlns",n.namespaces.xhtml),m.innerText=i[o],m.style[a.units.len]=Math.round(h[a.units.len])+"px",m.style[a.counterUnits.len]=Math.round(h[a.counterUnits.len])+"px",p=u.foreignObject(m,n.extend({style:"overflow: visible;"},h))}else p=u.elem("text",h,c.join(" ")).text(i[o]);d.emit("draw",n.extend({type:"label",axis:a,index:o,group:u,element:p,text:i[o]},h))},n.getSeriesOption=function(e,t,n){if(e.name&&t.series&&t.series[e.name]){var r=t.series[e.name];return r.hasOwnProperty(n)?r[n]:t[n]}return t[n]},n.optionsProvider=function(t,r,o){var i,a,s=n.extend({},t),l=[];function u(t){var l=i;if(i=n.extend({},s),r)for(a=0;a=2&&e[s]<=e[s-2]&&(a=!0),a&&(i.push({pathCoordinates:[],valueData:[]}),a=!1),i[i.length-1].pathCoordinates.push(e[s],e[s+1]),i[i.length-1].valueData.push(t[s/2]));return i}}(window,document,e),function(e,t,n){"use strict";n.Interpolation={},n.Interpolation.none=function(e){var t={fillHoles:!1};return e=n.extend({},t,e),function(t,r){for(var o=new n.Svg.Path,i=!0,a=0;a1){var l=[];return s.forEach((function(e){l.push(t(e.pathCoordinates,e.valueData))})),n.Svg.Path.join(l)}if(i=s[0].pathCoordinates,a=s[0].valueData,i.length<=4)return n.Interpolation.none()(i,a);for(var u,c=(new n.Svg.Path).move(i[0],i[1],!1,a[0]),f=0,d=i.length;d-2*!u>f;f+=2){var p=[{x:+i[f-2],y:+i[f-1]},{x:+i[f],y:+i[f+1]},{x:+i[f+2],y:+i[f+3]},{x:+i[f+4],y:+i[f+5]}];u?f?d-4===f?p[3]={x:+i[0],y:+i[1]}:d-2===f&&(p[2]={x:+i[0],y:+i[1]},p[3]={x:+i[2],y:+i[3]}):p[0]={x:+i[d-2],y:+i[d-1]}:d-4===f?p[3]=p[2]:f||(p[0]={x:+i[f],y:+i[f+1]}),c.curve(r*(-p[0].x+6*p[1].x+p[2].x)/6+o*p[2].x,r*(-p[0].y+6*p[1].y+p[2].y)/6+o*p[2].y,r*(p[1].x+6*p[2].x-p[3].x)/6+o*p[2].x,r*(p[1].y+6*p[2].y-p[3].y)/6+o*p[2].y,p[2].x,p[2].y,!1,a[(f+2)/2])}return c}return n.Interpolation.none()([])}},n.Interpolation.monotoneCubic=function(e){var t={fillHoles:!1};return e=n.extend({},t,e),function t(r,o){var i=n.splitIntoSegments(r,o,{fillHoles:e.fillHoles,increasingX:!0});if(i.length){if(i.length>1){var a=[];return i.forEach((function(e){a.push(t(e.pathCoordinates,e.valueData))})),n.Svg.Path.join(a)}if(r=i[0].pathCoordinates,o=i[0].valueData,r.length<=4)return n.Interpolation.none()(r,o);var s,l,u=[],c=[],f=r.length/2,d=[],p=[],h=[],m=[];for(s=0;s0!=p[s]>0?d[s]=0:(d[s]=3*(m[s-1]+m[s])/((2*m[s]+m[s-1])/p[s-1]+(m[s]+2*m[s-1])/p[s]),isFinite(d[s])||(d[s]=0));for(l=(new n.Svg.Path).move(u[0],c[0],!1,o[0]),s=0;s1})).map((function(e){var t=e.pathElements[0],n=e.pathElements[e.pathElements.length-1];return e.clone(!0).position(0).remove(1).move(t.x,v).line(t.x,t.y).position(e.pathElements.length+1).line(n.x,v)})).forEach(function(n){var s=l.elem("path",{d:n.stringify()},e.classNames.area,!0);this.eventEmitter.emit("draw",{type:"area",values:t.normalized.series[a],path:n.clone(),series:r,seriesIndex:a,axisX:o,axisY:i,chartRect:u,index:a,group:l,element:s})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:i.bounds,chartRect:u,axisX:o,axisY:i,svg:this.svg,options:e})}function i(e,t,o,i){n.Line.super.constructor.call(this,e,t,r,n.extend({},r,o),i)}n.Line=n.Base.extend({constructor:i,createChart:o})}(window,document,e),function(e,t,n){"use strict";var r={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:n.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:n.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,referenceValue:0,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,stackMode:"accumulate",horizontalBars:!1,distributeSeries:!1,reverseData:!1,showGridBackground:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",gridBackground:"ct-grid-background",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};function o(e){var t,o;e.distributeSeries?(t=n.normalizeData(this.data,e.reverseData,e.horizontalBars?"x":"y")).normalized.series=t.normalized.series.map((function(e){return[e]})):t=n.normalizeData(this.data,e.reverseData,e.horizontalBars?"x":"y"),this.svg=n.createSvg(this.container,e.width,e.height,e.classNames.chart+(e.horizontalBars?" "+e.classNames.horizontalBars:""));var i=this.svg.elem("g").addClass(e.classNames.gridGroup),a=this.svg.elem("g"),s=this.svg.elem("g").addClass(e.classNames.labelGroup);if(e.stackBars&&0!==t.normalized.series.length){var l=n.serialMap(t.normalized.series,(function(){return Array.prototype.slice.call(arguments).map((function(e){return e})).reduce((function(e,t){return{x:e.x+(t&&t.x)||0,y:e.y+(t&&t.y)||0}}),{x:0,y:0})}));o=n.getHighLow([l],e,e.horizontalBars?"x":"y")}else o=n.getHighLow(t.normalized.series,e,e.horizontalBars?"x":"y");o.high=+e.high||(0===e.high?0:o.high),o.low=+e.low||(0===e.low?0:o.low);var u,c,f,d,p,h=n.createChartRect(this.svg,e,r.padding);c=e.distributeSeries&&e.stackBars?t.normalized.labels.slice(0,1):t.normalized.labels,e.horizontalBars?(u=d=void 0===e.axisX.type?new n.AutoScaleAxis(n.Axis.units.x,t.normalized.series,h,n.extend({},e.axisX,{highLow:o,referenceValue:0})):e.axisX.type.call(n,n.Axis.units.x,t.normalized.series,h,n.extend({},e.axisX,{highLow:o,referenceValue:0})),f=p=void 0===e.axisY.type?new n.StepAxis(n.Axis.units.y,t.normalized.series,h,{ticks:c}):e.axisY.type.call(n,n.Axis.units.y,t.normalized.series,h,e.axisY)):(f=d=void 0===e.axisX.type?new n.StepAxis(n.Axis.units.x,t.normalized.series,h,{ticks:c}):e.axisX.type.call(n,n.Axis.units.x,t.normalized.series,h,e.axisX),u=p=void 0===e.axisY.type?new n.AutoScaleAxis(n.Axis.units.y,t.normalized.series,h,n.extend({},e.axisY,{highLow:o,referenceValue:0})):e.axisY.type.call(n,n.Axis.units.y,t.normalized.series,h,n.extend({},e.axisY,{highLow:o,referenceValue:0})));var m=e.horizontalBars?h.x1+u.projectValue(0):h.y1-u.projectValue(0),v=[];f.createGridAndLabels(i,s,this.supportsForeignObject,e,this.eventEmitter),u.createGridAndLabels(i,s,this.supportsForeignObject,e,this.eventEmitter),e.showGridBackground&&n.createGridBackground(i,h,e.classNames.gridBackground,this.eventEmitter),t.raw.series.forEach(function(r,o){var i,s,l=o-(t.raw.series.length-1)/2;i=e.distributeSeries&&!e.stackBars?f.axisLength/t.normalized.series.length/2:e.distributeSeries&&e.stackBars?f.axisLength/2:f.axisLength/t.normalized.series[o].length/2,(s=a.elem("g")).attr({"ct:series-name":r.name,"ct:meta":n.serialize(r.meta)}),s.addClass([e.classNames.series,r.className||e.classNames.series+"-"+n.alphaNumerate(o)].join(" ")),t.normalized.series[o].forEach(function(a,c){var g,y,b,_;if(_=e.distributeSeries&&!e.stackBars?o:e.distributeSeries&&e.stackBars?0:c,g=e.horizontalBars?{x:h.x1+u.projectValue(a&&a.x?a.x:0,c,t.normalized.series[o]),y:h.y1-f.projectValue(a&&a.y?a.y:0,_,t.normalized.series[o])}:{x:h.x1+f.projectValue(a&&a.x?a.x:0,_,t.normalized.series[o]),y:h.y1-u.projectValue(a&&a.y?a.y:0,c,t.normalized.series[o])},f instanceof n.StepAxis&&(f.options.stretch||(g[f.units.pos]+=i*(e.horizontalBars?-1:1)),g[f.units.pos]+=e.stackBars||e.distributeSeries?0:l*e.seriesBarDistance*(e.horizontalBars?-1:1)),b=v[c]||m,v[c]=b-(m-g[f.counterUnits.pos]),void 0!==a){var w={};w[f.units.pos+"1"]=g[f.units.pos],w[f.units.pos+"2"]=g[f.units.pos],!e.stackBars||"accumulate"!==e.stackMode&&e.stackMode?(w[f.counterUnits.pos+"1"]=m,w[f.counterUnits.pos+"2"]=g[f.counterUnits.pos]):(w[f.counterUnits.pos+"1"]=b,w[f.counterUnits.pos+"2"]=v[c]),w.x1=Math.min(Math.max(w.x1,h.x1),h.x2),w.x2=Math.min(Math.max(w.x2,h.x1),h.x2),w.y1=Math.min(Math.max(w.y1,h.y2),h.y1),w.y2=Math.min(Math.max(w.y2,h.y2),h.y1);var x=n.getMetaData(r,c);y=s.elem("line",w,e.classNames.bar).attr({"ct:value":[a.x,a.y].filter(n.isNumeric).join(","),"ct:meta":n.serialize(x)}),this.eventEmitter.emit("draw",n.extend({type:"bar",value:a,index:c,meta:x,series:r,seriesIndex:o,axisX:d,axisY:p,chartRect:h,group:s,element:y},w))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:u.bounds,chartRect:h,axisX:d,axisY:p,svg:this.svg,options:e})}function i(e,t,o,i){n.Bar.super.constructor.call(this,e,t,r,n.extend({},r,o),i)}n.Bar=n.Base.extend({constructor:i,createChart:o})}(window,document,e),function(e,t,n){"use strict";var r={width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",sliceDonutSolid:"ct-slice-donut-solid",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutSolid:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:n.noop,labelDirection:"neutral",reverseData:!1,ignoreEmptyValues:!1};function o(e,t,n){var r=t.x>e.x;return r&&"explode"===n||!r&&"implode"===n?"start":r&&"implode"===n||!r&&"explode"===n?"end":"middle"}function i(e){var t,i,a,s,l,u=n.normalizeData(this.data),c=[],f=e.startAngle;this.svg=n.createSvg(this.container,e.width,e.height,e.donut?e.classNames.chartDonut:e.classNames.chartPie),i=n.createChartRect(this.svg,e,r.padding),a=Math.min(i.width()/2,i.height()/2),l=e.total||u.normalized.series.reduce((function(e,t){return e+t}),0);var d=n.quantity(e.donutWidth);"%"===d.unit&&(d.value*=a/100),a-=e.donut&&!e.donutSolid?d.value/2:0,s="outside"===e.labelPosition||e.donut&&!e.donutSolid?a:"center"===e.labelPosition?0:e.donutSolid?a-d.value/2:a/2,s+=e.labelOffset;var p={x:i.x1+i.width()/2,y:i.y2+i.height()/2},h=1===u.raw.series.filter((function(e){return e.hasOwnProperty("value")?0!==e.value:0!==e})).length;u.raw.series.forEach(function(e,t){c[t]=this.svg.elem("g",null,null)}.bind(this)),e.showLabel&&(t=this.svg.elem("g",null,null)),u.raw.series.forEach(function(r,i){if(0!==u.normalized.series[i]||!e.ignoreEmptyValues){c[i].attr({"ct:series-name":r.name}),c[i].addClass([e.classNames.series,r.className||e.classNames.series+"-"+n.alphaNumerate(i)].join(" "));var m=l>0?f+u.normalized.series[i]/l*360:0,v=Math.max(0,f-(0===i||h?0:.2));m-v>=359.99&&(m=v+359.99);var g,y,b,_=n.polarToCartesian(p.x,p.y,a,v),w=n.polarToCartesian(p.x,p.y,a,m),x=new n.Svg.Path(!e.donut||e.donutSolid).move(w.x,w.y).arc(a,a,0,m-f>180,0,_.x,_.y);e.donut?e.donutSolid&&(b=a-d.value,g=n.polarToCartesian(p.x,p.y,b,f-(0===i||h?0:.2)),y=n.polarToCartesian(p.x,p.y,b,m),x.line(g.x,g.y),x.arc(b,b,0,m-f>180,1,y.x,y.y)):x.line(p.x,p.y);var E=e.classNames.slicePie;e.donut&&(E=e.classNames.sliceDonut,e.donutSolid&&(E=e.classNames.sliceDonutSolid));var k=c[i].elem("path",{d:x.stringify()},E);if(k.attr({"ct:value":u.normalized.series[i],"ct:meta":n.serialize(r.meta)}),e.donut&&!e.donutSolid&&(k._node.style.strokeWidth=d.value+"px"),this.eventEmitter.emit("draw",{type:"slice",value:u.normalized.series[i],totalDataSum:l,index:i,meta:r.meta,series:r,group:c[i],element:k,path:x.clone(),center:p,radius:a,startAngle:f,endAngle:m}),e.showLabel){var S,O;S=1===u.raw.series.length?{x:p.x,y:p.y}:n.polarToCartesian(p.x,p.y,s,f+(m-f)/2),O=u.normalized.labels&&!n.isFalseyButZero(u.normalized.labels[i])?u.normalized.labels[i]:u.normalized.series[i];var T=e.labelInterpolationFnc(O,i);if(T||0===T){var N=t.elem("text",{dx:S.x,dy:S.y,"text-anchor":o(p,S,e.labelDirection)},e.classNames.label).text(""+T);this.eventEmitter.emit("draw",{type:"label",index:i,group:t,element:N,text:""+T,x:S.x,y:S.y})}}f=m}}.bind(this)),this.eventEmitter.emit("created",{chartRect:i,svg:this.svg,options:e})}function a(e,t,o,i){n.Pie.super.constructor.call(this,e,t,r,n.extend({},r,o),i)}n.Pie=n.Base.extend({constructor:a,createChart:i,determineAnchorPosition:o})}(window,document,e),e);var e}.apply(t,[]))||(e.exports=r)},function(e,t,n){e.exports={"trans-color":"suite-summary--trans-color---14JXk",component:"suite-summary--component---cFAkx","no-margin":"suite-summary--no-margin---3WX9n","summary-item":"suite-summary--summary-item---JHYFN",duration:"suite-summary--duration---AzGUQ",tests:"suite-summary--tests---3Zhct",passed:"suite-summary--passed---24BnC",failed:"suite-summary--failed---205C4",pending:"suite-summary--pending---3_Nkj",skipped:"suite-summary--skipped---TovqF",icon:"suite-summary--icon---3rZ6G"}},function(e,t,n){e.exports={"trans-color":"toggle-switch--trans-color---16in9",component:"toggle-switch--component---3vjvh",label:"toggle-switch--label---1Lu8U","toggle-input":"toggle-switch--toggle-input---3BB7e",toggle:"toggle-switch--toggle---2kPqc",disabled:"toggle-switch--disabled---1qDLf",icon:"toggle-switch--icon---348nT"}},function(e,t,n){"use strict";var r=n(61),o="function"==typeof Symbol&&Symbol.for,i=o?Symbol.for("react.element"):60103,a=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,l=o?Symbol.for("react.strict_mode"):60108,u=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,d=o?Symbol.for("react.forward_ref"):60112,p=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,m=o?Symbol.for("react.lazy"):60116,v="function"==typeof Symbol&&Symbol.iterator;function g(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;nP.length&&P.push(e)}function D(e,t,n,r){var o=typeof e;"undefined"!==o&&"boolean"!==o||(e=null);var s=!1;if(null===e)s=!0;else switch(o){case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case i:case a:s=!0}}if(s)return n(r,e,""===t?"."+I(e,0):t),1;if(s=0,t=""===t?".":t+":",Array.isArray(e))for(var l=0;l

kgYV&=aTZp6v>HirW%!Tl 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 literal 0 HcmV?d00001 diff --git a/test-reports/assets/roboto-medium-webfont.woff b/test-reports/assets/roboto-medium-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..38aebe506e576991c27a659b12d7be9d71534618 GIT binary patch literal 26292 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 literal 0 HcmV?d00001 diff --git a/test-reports/assets/roboto-medium-webfont.woff2 b/test-reports/assets/roboto-medium-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..6b22807f64e95721daccc8fb8a670f4b7c2cea7f GIT binary patch literal 19944 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 literal 0 HcmV?d00001 diff --git a/test-reports/assets/roboto-regular-webfont.woff b/test-reports/assets/roboto-regular-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..d0890af2110f6be98594dc5f96f1c950a1d58ecd GIT binary patch literal 26280 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 +Mochawesome Report

\ No newline at end of file diff --git a/test-reports/pass_07-16-2024_065057_sdk-test-report.json b/test-reports/pass_07-16-2024_065057_sdk-test-report.json new file mode 100644 index 0000000..62aa366 --- /dev/null +++ b/test-reports/pass_07-16-2024_065057_sdk-test-report.json @@ -0,0 +1,9368 @@ +{ + "stats": { + "suites": 62, + "tests": 401, + "passes": 401, + "pending": 0, + "failures": 0, + "start": "2024-07-16T06:38:31.983Z", + "end": "2024-07-16T06:50:57.557Z", + "duration": 745574, + "testsRegistered": 401, + "passPercent": 100, + "pendingPercent": 0, + "other": 0, + "hasOther": false, + "skipped": 0, + "hasSkipped": false + }, + "results": [ + { + "uuid": "0db8d69d-56af-4df1-a9b3-68084aac8784", + "title": "", + "fullFile": "", + "file": "", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register License Terms in \"{root}\"", + "fullTitle": "\"before all\" hook: Register License Terms in \"{root}\"", + "timedOut": false, + "duration": 1, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "it(\"Register Non-Commercial Social Remixing License Terms\", async function () {\n const responseNonComLicenseTerms = await (0, chai_1.expect)((0, sdkUtils_1.registerNonComSocialRemixingPIL)(\"A\", true)).to.not.be.rejected;\n (0, chai_1.expect)(responseNonComLicenseTerms.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\n exports.nonComLicenseTermsId = nonComLicenseTermsId = responseNonComLicenseTerms.licenseTermsId;\n});\nit(\"Register Commercial Use License Terms\", async function () {\n const responseComUseLicenseTerms1 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialUsePIL)(\"A\", mintingFee1, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n (0, chai_1.expect)(responseComUseLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\n exports.comUseLicenseTermsId1 = comUseLicenseTermsId1 = responseComUseLicenseTerms1.licenseTermsId;\n const responseComUseLicenseTerms2 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialUsePIL)(\"A\", mintingFee2, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n (0, chai_1.expect)(responseComUseLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\n exports.comUseLicenseTermsId2 = comUseLicenseTermsId2 = responseComUseLicenseTerms2.licenseTermsId;\n});\nit(\"Register Commercial Remix License Terms\", async function () {\n const responseComRemixLicenseTerms1 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee1, commercialRevShare1, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n (0, chai_1.expect)(responseComRemixLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\n exports.comRemixLicenseTermsId1 = comRemixLicenseTermsId1 = responseComRemixLicenseTerms1.licenseTermsId;\n const responseComRemixLicenseTerms2 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee2, commercialRevShare2, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n (0, chai_1.expect)(responseComRemixLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\n exports.comRemixLicenseTermsId2 = comRemixLicenseTermsId2 = responseComRemixLicenseTerms2.licenseTermsId;\n});", + "err": {}, + "uuid": "2a665bd5-68c4-4e55-a20d-2b625c5515b8", + "parentUUID": "0db8d69d-56af-4df1-a9b3-68084aac8784", + "isHook": true, + "skipped": false + }, + { + "title": "\"before each\" hook in \"{root}\"", + "fullTitle": "\"before each\" hook in \"{root}\"", + "timedOut": false, + "duration": 0, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "consoleLogs = (0, utils_1.captureConsoleLogs)(consoleLogs);", + "err": {}, + "uuid": "1a813940-670b-49d9-85f1-f9d20f748c3c", + "parentUUID": "0db8d69d-56af-4df1-a9b3-68084aac8784", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [ + { + "title": "\"after each\" hook in \"{root}\"", + "fullTitle": "\"after each\" hook in \"{root}\"", + "timedOut": false, + "duration": 0, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "if (consoleLogs.length > 0) {\n addContext(this, {\n title: 'Test Result',\n value: consoleLogs.join('\\n'),\n });\n consoleLogs = [];\n}\n;", + "err": {}, + "uuid": "20a63d7a-992b-4e7e-9803-5ad54008b731", + "parentUUID": "0db8d69d-56af-4df1-a9b3-68084aac8784", + "isHook": true, + "skipped": false + } + ], + "tests": [ + { + "title": "Register Non-Commercial Social Remixing License Terms", + "fullTitle": "Register Non-Commercial Social Remixing License Terms", + "timedOut": false, + "duration": 224, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"licenseTermsId\\\":\\\"2n\\\"}\"\n}", + "code": "const responseNonComLicenseTerms = await (0, chai_1.expect)((0, sdkUtils_1.registerNonComSocialRemixingPIL)(\"A\", true)).to.not.be.rejected;\n(0, chai_1.expect)(responseNonComLicenseTerms.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\nexports.nonComLicenseTermsId = nonComLicenseTermsId = responseNonComLicenseTerms.licenseTermsId;", + "err": {}, + "uuid": "6576355b-7358-48e0-951a-f3a1d587fe4c", + "parentUUID": "0db8d69d-56af-4df1-a9b3-68084aac8784", + "isHook": false, + "skipped": false + }, + { + "title": "Register Commercial Use License Terms", + "fullTitle": "Register Commercial Use License Terms", + "timedOut": false, + "duration": 49, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"licenseTermsId\\\":\\\"7n\\\"}\\n{\\\"licenseTermsId\\\":\\\"10n\\\"}\"\n}", + "code": "const responseComUseLicenseTerms1 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialUsePIL)(\"A\", mintingFee1, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n(0, chai_1.expect)(responseComUseLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\nexports.comUseLicenseTermsId1 = comUseLicenseTermsId1 = responseComUseLicenseTerms1.licenseTermsId;\nconst responseComUseLicenseTerms2 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialUsePIL)(\"A\", mintingFee2, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n(0, chai_1.expect)(responseComUseLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\nexports.comUseLicenseTermsId2 = comUseLicenseTermsId2 = responseComUseLicenseTerms2.licenseTermsId;", + "err": {}, + "uuid": "ddb562e0-10c8-442d-8417-74ff39cd068b", + "parentUUID": "0db8d69d-56af-4df1-a9b3-68084aac8784", + "isHook": false, + "skipped": false + }, + { + "title": "Register Commercial Remix License Terms", + "fullTitle": "Register Commercial Remix License Terms", + "timedOut": false, + "duration": 48, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"licenseTermsId\\\":\\\"57n\\\"}\\n{\\\"licenseTermsId\\\":\\\"62n\\\"}\"\n}", + "code": "const responseComRemixLicenseTerms1 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee1, commercialRevShare1, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n(0, chai_1.expect)(responseComRemixLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\nexports.comRemixLicenseTermsId1 = comRemixLicenseTermsId1 = responseComRemixLicenseTerms1.licenseTermsId;\nconst responseComRemixLicenseTerms2 = await (0, chai_1.expect)((0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee2, commercialRevShare2, config_1.mintingFeeTokenAddress, true)).to.not.be.rejected;\n(0, chai_1.expect)(responseComRemixLicenseTerms1.licenseTermsId).to.be.a(\"bigint\").and.to.be.ok;\nexports.comRemixLicenseTermsId2 = comRemixLicenseTermsId2 = responseComRemixLicenseTerms2.licenseTermsId;", + "err": {}, + "uuid": "4bc7b34e-05c2-430e-8a16-fd81137846f9", + "parentUUID": "0db8d69d-56af-4df1-a9b3-68084aac8784", + "isHook": false, + "skipped": false + } + ], + "suites": [ + { + "uuid": "88a44607-4b02-4b74-8742-4b21babc816b", + "title": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comRemixPIL.test.ts", + "file": "/test/e2e/derivativeIP.comRemixPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "title": "@smoke Register a derivative IP asset with/without license tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comRemixPIL.test.ts", + "file": "/test/e2e/derivativeIP.comRemixPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 1327, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xd06516e92cfc51e17d005f8bff85e643953e784142de2818a941360d701672db\\\"\\nMinted NFT tokenId: 7302\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "af3cf969-a8a7-41f2-bf10-e90eb9725ce6", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 397, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x1b6fd33e53892fd22eb9c43f5bfe670e793a6db3334a6500f439e9b9498e0cf6\\\",\\\"ipId\\\":\\\"0x05fA7a690641DCdBA89F1510852B4889C92aF5B3\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "093b02c4-b1de-4371-b066-4df43cf61a54", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 3481, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x414acb4f52399ff3b223df8182926f596789bccd0a658df363a291ed031a8d2c\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "501041f3-7585-47da-a412-80082604993e", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 12402, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x71599b35e3fa5b55365e701ebf24d02a1342f2324049d13655a11f8b3646f9e0\\\",\\\"licenseTokenIds\\\":[\\\"6891n\\\",\\\"6892n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3e063265-f480-419d-ad71-73f5ff73c59e", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1170, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x9bd832d5478340000175a91c78bd0c00069db539e207d49ccb882e226bf52acb\\\"\\nMinted NFT tokenId: 7303\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "1729b7e9-e95d-4718-95b6-780433b89fb1", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 77, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x47685244e4307f8970533a3c0adfc7d3cf5ee759b7c52a2b51c047cdee3a29cf\\\",\\\"ipId\\\":\\\"0x8E20D3Eff4036Ae6eAaCec99FAEb600922e08982\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "04a819cf-a144-41c0-b51e-5775937cadf2", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet B can register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 3436, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x67da7b99779bc0eded39bf33f252bccc173d2f42c5994f0eb676d34f1cbe59b5\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e943a43b-3917-41b2-a075-8adaf94e612e", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC and get a tokenId(tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Mint a NFT to WalletC and get a tokenId(tokenIdC)", + "timedOut": false, + "duration": 7235, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x641f0bde6639c8dbe9eaf94310292937999815259c7ca042cc2de34681c7465d\\\"\\nMinted NFT tokenId: 7304\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "66d2e2af-1210-432c-ab07-093c72f2fbfd", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "timedOut": false, + "duration": 88, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xeac2a20e0d770cd20e7e337925fa4af2a034b390b04072a6528e51b0cb9cdf81\\\",\\\"ipId\\\":\\\"0xC666933d009924C56d6E019924480Cd119c048BD\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a16bdb0c-82ef-4ac4-bc04-7acd2369d1ee", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can NOT register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet C can NOT register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 5, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "370014e4-3cf9-45a3-b89f-32f5e31f0b25", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can register a derivative IP asset without licenseTokenId", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL @smoke Register a derivative IP asset with/without license tokens Wallet C can register a derivative IP asset without licenseTokenId", + "timedOut": false, + "duration": 3450, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2bf024975cca7ea75f1ba1d14e085b4ec9125767d0baec7fe87186d01eb2c03f\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ae00682f-3bdf-45c5-91c6-069156d1143d", + "parentUUID": "f1b34d3e-b447-4bd5-b9ee-8e235129a432", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "af3cf969-a8a7-41f2-bf10-e90eb9725ce6", + "093b02c4-b1de-4371-b066-4df43cf61a54", + "501041f3-7585-47da-a412-80082604993e", + "3e063265-f480-419d-ad71-73f5ff73c59e", + "1729b7e9-e95d-4718-95b6-780433b89fb1", + "04a819cf-a144-41c0-b51e-5775937cadf2", + "e943a43b-3917-41b2-a075-8adaf94e612e", + "66d2e2af-1210-432c-ab07-093c72f2fbfd", + "a16bdb0c-82ef-4ac4-bc04-7acd2369d1ee", + "370014e4-3cf9-45a3-b89f-32f5e31f0b25", + "ae00682f-3bdf-45c5-91c6-069156d1143d" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 33068, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "3db801cf-e77f-456c-981e-2e785e56b480", + "title": "Register a derivative IP asset with multiple parent IP assets", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comRemixPIL.test.ts", + "file": "/test/e2e/derivativeIP.comRemixPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 140, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x9928859aedca46ca776940909b6d3481542a4da022d4f49d5785b821ee6c1292\\\"\\nMinted NFT tokenId: 7305\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0dd797d8-690f-4ebd-aacb-539cd7aa4492", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 69, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xabaea39a7d30f13d91f2860e93691d70eff0d7337cf0a01bf782e006977b851c\\\",\\\"ipId\\\":\\\"0x26de549E5C17fCe9f2EE4386d0D6f0364F01d325\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0fd8f862-67c3-4116-87c5-d15185e3c4bb", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 148, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x710e7e4df3ca79191ac6b615d985a177f775954176a786bf28453cf6bd6bfb8d\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e961c5ea-0cfa-4986-9e3c-fda0e261954f", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenidB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to WalletB, get a tokenId (tokenidB)", + "timedOut": false, + "duration": 2199, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x1d23c2cfb9ff016ad1c0f6ae931bf6c027825d8553747c02fb70b13f19a26873\\\"\\nMinted NFT tokenId: 7306\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "7664b915-acd8-4e25-a27c-f736f576db17", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 78, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb825158ce20e01a5ccfe56a23dcd5c44c20cabaf0ca4e0177e8c42a8e59580af\\\",\\\"ipId\\\":\\\"0xF6cb470BAb89d9ffBFd9cB307BCe9879B7A1dd60\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "50082b10-ed46-413a-8827-947f909fc803", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 1137, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x27a3f7eeccc772a22d938d6d18416afe644fc5c91404fb1b5a3e5a202011d9ce\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c97c82f7-5c92-4797-9bed-7c5b1f40c20b", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenidC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to WalletC, get a tokenId (tokenidC)", + "timedOut": false, + "duration": 4160, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x555993a9acb5b47d133879383872b36c94b96c8a142d96cf497697943312544d\\\"\\nMinted NFT tokenId: 7307\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8a7ae169-9077-4a75-9924-f610638a2ca8", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "timedOut": false, + "duration": 80, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x05c38efba21815ec42489bc228e47bef398f23481b585864dc3a3dee265d4742\\\",\\\"ipId\\\":\\\"0x10B83f2d9db1464C4977a665D4FaC15e92F4CB6e\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "dbc1679b-9019-4c16-9f8d-c2f28ef728df", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can register a derivative IP asset with multiple parent IP assets", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP asset with multiple parent IP assets Wallet C can register a derivative IP asset with multiple parent IP assets", + "timedOut": false, + "duration": 11029, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf2eec800d4eeb5d741f478ea30b9f064c137570d405165877b2d72904f578f6b\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ae8580f2-2eaa-4d49-b51b-306cc0336a25", + "parentUUID": "3db801cf-e77f-456c-981e-2e785e56b480", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "0dd797d8-690f-4ebd-aacb-539cd7aa4492", + "0fd8f862-67c3-4116-87c5-d15185e3c4bb", + "e961c5ea-0cfa-4986-9e3c-fda0e261954f", + "7664b915-acd8-4e25-a27c-f736f576db17", + "50082b10-ed46-413a-8827-947f909fc803", + "c97c82f7-5c92-4797-9bed-7c5b1f40c20b", + "8a7ae169-9077-4a75-9924-f610638a2ca8", + "dbc1679b-9019-4c16-9f8d-c2f28ef728df", + "ae8580f2-2eaa-4d49-b51b-306cc0336a25" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 19040, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "title": "Register a derivative IP assets with multiple license tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comRemixPIL.test.ts", + "file": "/test/e2e/derivativeIP.comRemixPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 119, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x71f907472f89667daf4b82c4256715cb7e7993b90f325d593f1455c26568a6cc\\\"\\nMinted NFT tokenId: 7308\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "7a444aa0-7b78-4849-978d-4a801f6772cb", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "timedOut": false, + "duration": 117, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x39715d04c01b92e0521947b5585a65d9ce61e24d66193806b269b56aafbb7dcf\\\",\\\"ipId\\\":\\\"0x7F48495fA628F63C196CcDca6BE8061e435f998c\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "1a6548d2-0cb0-4e6d-94de-167683dcb532", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 1161, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6601fac18d1ffcafd4ae8fa564f47da43503f38f8b9e033c9440daba4f55a1b4\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "cd57385d-9dbc-4611-8ed9-fdb591d7d612", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "timedOut": false, + "duration": 8637, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xad121f76e6a76ee9fbb48bf36815957c042bcea25f93b2850a861f8dfea4142a\\\",\\\"licenseTokenIds\\\":[\\\"6893n\\\",\\\"6894n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "feec1440-856f-4894-b21e-c082925070c1", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 126, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x4ee71e13a431db264b7d6fd7616e44b6d378783b54e4a3791be82ec944013f24\\\"\\nMinted NFT tokenId: 7309\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e396d9ff-1ad9-4a12-b3ec-cf9005d430e6", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "timedOut": false, + "duration": 223, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x74404a43acfb6e4348009f34afd682a3cb8cdbfa1aa3e3bf0401841c3d242640\\\",\\\"ipId\\\":\\\"0x37e187aB1669240A05812e7faB5b1DaD7f5CeDfE\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e9a018e5-adaf-42c2-b761-11920afd316f", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", + "timedOut": false, + "duration": 1151, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x3134cbb25dd7093e25c1ee19b4191cc6664df1d39e654f2a1a5e8b9cccb67b2b\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "eafcbcc8-1b7f-49fc-a01e-93437256cb47", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 5707, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x691b876a755d4e71ff8eb74933cf61788d648d8329e58f6e92d8e55abb175a74\\\",\\\"licenseTokenIds\\\":[\\\"6895n\\\",\\\"6896n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ab72dc0d-1088-4d51-9abc-471eb623c215", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "timedOut": false, + "duration": 1117, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xa885b844836ee43f39500a979bad5b7a1e3c8e708ee9bf509cbc0fe300085102\\\"\\nMinted NFT tokenId: 7310\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2f60700d-e609-47c2-8e6f-614048ce12c0", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 68, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x086f55331aaa7acf7b79c6c67dbab3be0a4a803d45a911c96debbe16c769eebc\\\",\\\"ipId\\\":\\\"0x20149C30c4812bA09912Ff9C12Da594BEF74bB6e\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2020c9e7-bd39-40bf-977f-3ab883d3fe5d", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", + "timedOut": false, + "duration": 4566, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x415f31aec5d250f5947f8fa5dec6726da10c5c4741fe136a876ffaeec8eb94c1\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4557aaed-d1b3-40e7-a4bc-89ba28893263", + "parentUUID": "0ac294d9-1c59-410f-9a5d-ab48cd16e25a", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "7a444aa0-7b78-4849-978d-4a801f6772cb", + "1a6548d2-0cb0-4e6d-94de-167683dcb532", + "cd57385d-9dbc-4611-8ed9-fdb591d7d612", + "feec1440-856f-4894-b21e-c082925070c1", + "e396d9ff-1ad9-4a12-b3ec-cf9005d430e6", + "e9a018e5-adaf-42c2-b761-11920afd316f", + "eafcbcc8-1b7f-49fc-a01e-93437256cb47", + "ab72dc0d-1088-4d51-9abc-471eb623c215", + "2f60700d-e609-47c2-8e6f-614048ce12c0", + "2020c9e7-bd39-40bf-977f-3ab883d3fe5d", + "4557aaed-d1b3-40e7-a4bc-89ba28893263" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 22992, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "title": "Register a derivative IP assets with multiple license tokens, the sender is not licensee", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comRemixPIL.test.ts", + "file": "/test/e2e/derivativeIP.comRemixPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 1117, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xecfeb5f4d496befd88ffaeed61cc46911623eb4417c655cb0ec7e559070180e8\\\"\\nMinted NFT tokenId: 7311\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "71c036c7-04ef-4d8e-a361-4fb765782aa2", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "timedOut": false, + "duration": 1082, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd50c92ed12975cfe0e610dc9f074c5accee7e71d74b01b36a62a8ad950b178a5\\\",\\\"ipId\\\":\\\"0x4ccC6a5C73207d035c38952BF27F6cb8Ce5AA2d6\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6c2a74df-d621-4601-9253-b6d57e167716", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 135, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x554e2954369daa79ef878324fc3d69f1d2003363a3a88c7e56ad83f4a4203c06\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2b1e6e9f-46c5-4577-b181-b78e8bb7db2c", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "timedOut": false, + "duration": 6595, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x9607c03df362804f2043a9c8fe178c76a50c919e65365cda46a69b803fa507c9\\\",\\\"licenseTokenIds\\\":[\\\"6897n\\\",\\\"6898n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "24bd2d52-e8f7-4be1-b6b8-ee8a514f0fec", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1121, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x406ea1793e93818273d8d8514f29585e5413fe52cc03a66aae2719e599f12869\\\"\\nMinted NFT tokenId: 7312\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "9fbcdea1-cd9d-4080-a13c-b18e4173345f", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "timedOut": false, + "duration": 91, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa3d80787b5474fa40198def509683b3892a60cd8e3462402a5a7621202f57998\\\",\\\"ipId\\\":\\\"0x506eA9fD77EEa5D3a02917D6D338C9D6EA0C5F2F\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "22bdb9c2-807b-4dd5-b90d-14c1c71852aa", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", + "timedOut": false, + "duration": 139, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xac7d35a5450224b1a9ced7a2092a86f1dc82cf825fad7f7317a886ed3f01e1e4\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fdd0e49f-d4fa-4b39-a95f-1abc05cd9bc2", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 4594, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x034c61d18b604ef93a63d42f24323bd3d633e8b0f6fdbf98b8af581d9b71c5b1\\\",\\\"licenseTokenIds\\\":[\\\"6899n\\\",\\\"6900n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fe3f8a1f-8a15-4a72-b008-a61005dbbf60", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "timedOut": false, + "duration": 115, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xe24b64ca797e3138f61308fec0918a303add81244f287dad41ead0e14ba815dc\\\"\\nMinted NFT tokenId: 7313\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f618dd0a-e7cd-4555-9c2f-e3b897d94315", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 68, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb24709ce38d1167366aa8910ebc64ba7195783cda4d494336bead001fefe9e55\\\",\\\"ipId\\\":\\\"0xA27bCE21Af41243FECb1C9719c3C1d82FC42463a\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "9a414a08-727f-4735-84b6-6aa64993eafb", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can NOT register derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet C can NOT register derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 6, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "398b3257-2686-4b45-958f-8cdc8b3eeb5f", + "parentUUID": "1eb17f3d-a5dc-43ad-a106-a10700c7c624", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "71c036c7-04ef-4d8e-a361-4fb765782aa2", + "6c2a74df-d621-4601-9253-b6d57e167716", + "2b1e6e9f-46c5-4577-b181-b78e8bb7db2c", + "24bd2d52-e8f7-4be1-b6b8-ee8a514f0fec", + "9fbcdea1-cd9d-4080-a13c-b18e4173345f", + "22bdb9c2-807b-4dd5-b90d-14c1c71852aa", + "fdd0e49f-d4fa-4b39-a95f-1abc05cd9bc2", + "fe3f8a1f-8a15-4a72-b008-a61005dbbf60", + "f618dd0a-e7cd-4555-9c2f-e3b897d94315", + "9a414a08-727f-4735-84b6-6aa64993eafb", + "398b3257-2686-4b45-958f-8cdc8b3eeb5f" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 15063, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "title": "Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comRemixPIL.test.ts", + "file": "/test/e2e/derivativeIP.comRemixPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 118, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x62430e9646cdefa89c7398e05b4d45af8478de6713a7c342457c731dcb0d680c\\\"\\nMinted NFT tokenId: 7314\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6df42399-10ae-4540-b484-d74da67a7b35", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 70, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xec1b7d47fd077bc0a4f9ce909faf709f2ee1b578008c44b283292f9e08886f93\\\",\\\"ipId\\\":\\\"0x13145DD730DB6cA9D772c45D2DF3000Ee7aFe5A9\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c73bc83d-3cd7-41b8-93fe-78a9cd1e2efe", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 1140, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x66f7911d3257ebc643e051e9693470f22a55b1089d7d15f9d762387eb7b7ef9a\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "19bc812f-fce3-468b-b0be-720efbd25589", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 4435, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x7add318b7e39ffb60ecca5660cf51ca0c4c28c4980f5b23255a4bb62b07d9843\\\",\\\"licenseTokenIds\\\":[\\\"6901n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f23ef169-e8fa-4ba8-b4a4-f203e2e0d2b9", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1127, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x247bf31df8de16c3dd2c288ce40ecaec43a264134268a7c975ecbfe2db8fea4e\\\"\\nMinted NFT tokenId: 7315\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "066e6710-cccb-4eb1-992e-29382f2420d2", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 62, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd205fc3046a087cfe28f77e11ccc2b98248d60bcbbe5b56b1c8763964ffcaa85\\\",\\\"ipId\\\":\\\"0x00507CE1645E11a787787Aae3895AC888d138f2D\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6aabeda8-61a9-4199-aa3b-c32c57ce80be", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B can register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 6454, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xadc25d5a3fbfd498fb743b6887dfbe39f0648ec87cc448e2c7965a4b256f0177\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "88baa7e0-f605-48d1-847b-1adf621da52d", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 130, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x1736060c86077e30f4dab8df02c1e37204f7a940d82af23e55ac9ba470eb8447\\\"\\nMinted NFT tokenId: 7316\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0ca41d2d-f162-43a9-b58f-7ab2debd080d", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 76, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x1e7a4270504d74870a204bcb9fc01d26416646920283561537bd286757e0ecb9\\\",\\\"ipId\\\":\\\"0x43909BfD5A11b5F73573901e4A60b555B7A1F027\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e92e26b8-a671-46b2-b1d0-0b914d8331a9", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c93cb1e8-532b-4989-ba2e-b619b1b00652", + "parentUUID": "83e4e8e2-52d4-4230-adf8-897e9e138d08", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "6df42399-10ae-4540-b484-d74da67a7b35", + "c73bc83d-3cd7-41b8-93fe-78a9cd1e2efe", + "19bc812f-fce3-468b-b0be-720efbd25589", + "f23ef169-e8fa-4ba8-b4a4-f203e2e0d2b9", + "066e6710-cccb-4eb1-992e-29382f2420d2", + "6aabeda8-61a9-4199-aa3b-c32c57ce80be", + "88baa7e0-f605-48d1-847b-1adf621da52d", + "0ca41d2d-f162-43a9-b58f-7ab2debd080d", + "e92e26b8-a671-46b2-b1d0-0b914d8331a9", + "c93cb1e8-532b-4989-ba2e-b619b1b00652" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 13616, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "title": "Register derivative IP asset with an IP that already has license", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comRemixPIL.test.ts", + "file": "/test/e2e/derivativeIP.comRemixPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 1124, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xea655c89042c026da5a44fd3c9784bc19be8a2a648d4ddc4538d97a94370c0c7\\\"\\nMinted NFT tokenId: 7317\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "78b26ed8-7733-4fcd-9934-189bbe0c6a21", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 73, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x65b0f56f0286348cf4f8f06a0308ea2a4f467f0002ce315a698aac887817ab09\\\",\\\"ipId\\\":\\\"0xA8ecbaa421Cf79cDc9b1819D06133730c8490A3c\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "eaa35573-8854-462c-9823-a934b2bd7b79", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 157, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd5e0b14b19491442d634dbf7445b9160f9ea4e2c083feece4981a311034aa0b4\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b00479c8-92de-4b5a-9aa5-a796f3876cc1", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 4415, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x78e505bafb5c723e5a6dabaa50b1d5dca6cebce411f2ff073d8f4dec4a41bba0\\\",\\\"licenseTokenIds\\\":[\\\"6902n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4e363f7d-9c08-4a51-8b00-528527d0663f", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1124, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xa53ec1b610d811ab79c6efbc0953740f285401bfed362a0899b8b7bf26be0c7c\\\"\\nMinted NFT tokenId: 7318\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "040838e4-6b7f-428f-b66b-8d9e507688d7", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 74, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x958a1d1883cb39c8c95135b3eff2c4ad07641c9de12171d8d336a10380bc9fe6\\\",\\\"ipId\\\":\\\"0xef28cEf44a511FcFA70d69643A8D18f2c3384Ab6\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "72e63137-af3e-40e7-b218-f9b0a43a13fa", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 2145, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xefc229a3e92c5ad7efab440519cccfd8b0d5099b41f18289d0539aa2b2c7bf6a\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "96668903-2e96-45a3-bf3b-91dd0b7cd32c", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 4454, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x157a1286aab7d5330a7bb1c7149d334624a369cbf09fe383292e5a58c462f4c9\\\",\\\"licenseTokenIds\\\":[\\\"6903n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d3ebf0b4-d93e-406d-9a46-51ae4c2e6355", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL Register derivative IP asset with an IP that already has license Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", + "timedOut": false, + "duration": 6, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b3eead49-43dc-411f-ad79-bb813cd5f9ef", + "parentUUID": "9c6761e1-c2cd-453d-aa6b-53a3c2f3e0cb", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "78b26ed8-7733-4fcd-9934-189bbe0c6a21", + "eaa35573-8854-462c-9823-a934b2bd7b79", + "b00479c8-92de-4b5a-9aa5-a796f3876cc1", + "4e363f7d-9c08-4a51-8b00-528527d0663f", + "040838e4-6b7f-428f-b66b-8d9e507688d7", + "72e63137-af3e-40e7-b218-f9b0a43a13fa", + "96668903-2e96-45a3-bf3b-91dd0b7cd32c", + "d3ebf0b4-d93e-406d-9a46-51ae4c2e6355", + "b3eead49-43dc-411f-ad79-bb813cd5f9ef" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 13572, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "511b4c9b-50ce-40d1-8fd7-9e1627f5bf47", + "title": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comUsePIL.test.ts", + "file": "/test/e2e/derivativeIP.comUsePIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "title": "[smoke]Register a derivative IP asset with/without license tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comUsePIL.test.ts", + "file": "/test/e2e/derivativeIP.comUsePIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 118, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x40bd61d8ae97f0fb21d996e953170feb0a961719f9dc46c1458be6ee05f742cd\\\"\\nMinted NFT tokenId: 7319\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "94c9b27a-048b-4c56-b626-d6f0a2355b18", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 67, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x4f1a64218a3e3172e157359d5fa4628a960115d37eba01928e0c882c018ccb85\\\",\\\"ipId\\\":\\\"0x7b3bbC37C1D94827BBEE66C2Eb06506f09572F20\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "050f3a6e-96bf-43fe-9e5b-15e0a3e6b7e1", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 132, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf8824f8ea5f1dd889f34e9dbede3b4a14b18873877839f7826f11ddd12a0be2d\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0e467ec9-d8c7-43bf-8c32-e3b3da9384d7", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 9871, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x01cf130e6601dc74d3f4425a55429f172fbcd029d31147eab0be6cadcaaf89c3\\\",\\\"licenseTokenIds\\\":[\\\"6904n\\\",\\\"6905n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "65240041-ed98-495f-9f1b-7c45c5663d06", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 113, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xb0da8614a8d063eb7d06bf9df005a46aeeaf012a99e25c1cd10a8aa6b20a93ce\\\"\\nMinted NFT tokenId: 7320\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "dddcbb82-4a41-440d-a11e-e75b5f26e053", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 70, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd04808038a4216f7c849777c0e0022ec3d2dbd861d6cd93a292715d85a738ccf\\\",\\\"ipId\\\":\\\"0x7473A480c8551Ab288E2e1cdc0410CD4877BF2d9\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2d271a83-7b1c-462a-a804-f4d695dc0755", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet B can register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 4425, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa1af697bdbde104055df20ecf6b9ef87c3547ead6bce8b3b3cbfc15cc26b4c77\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "58f20f33-c48a-4f65-97fc-66d0cffac342", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC and get a tokenId(tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Mint a NFT to WalletC and get a tokenId(tokenIdC)", + "timedOut": false, + "duration": 2134, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x7823233fd6b5ad4cc4f484349464c0e0623b23f19cb67ea7bcf9dd8da009165a\\\"\\nMinted NFT tokenId: 7321\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2d918db1-91f0-4ab1-ac55-3831e8d98fb0", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "timedOut": false, + "duration": 1075, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x38a6414442df8af6a294aae09ac2210137263e21124837646656e32754ee78c6\\\",\\\"ipId\\\":\\\"0x98D6C9938ef9EC562EdcFADbc0651FeE42f314A3\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b80be4b9-1698-4fad-bb19-32795a2c967e", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can NOT register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet C can NOT register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "28ceb362-c9bd-41b9-8c4c-271b761be88c", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can register a derivative IP asset without licenseTokenId", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL [smoke]Register a derivative IP asset with/without license tokens Wallet C can register a derivative IP asset without licenseTokenId", + "timedOut": false, + "duration": 4395, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xbba3ba2ba5f8aac06a8c71a739f655c3ff29380ef2bece1506a28efa8c302691\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5e32ebfa-f783-47fb-a43b-7fdce8a6b8fd", + "parentUUID": "d99577ca-3c7d-4c7e-8230-a2647af0fcaf", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "94c9b27a-048b-4c56-b626-d6f0a2355b18", + "050f3a6e-96bf-43fe-9e5b-15e0a3e6b7e1", + "0e467ec9-d8c7-43bf-8c32-e3b3da9384d7", + "65240041-ed98-495f-9f1b-7c45c5663d06", + "dddcbb82-4a41-440d-a11e-e75b5f26e053", + "2d271a83-7b1c-462a-a804-f4d695dc0755", + "58f20f33-c48a-4f65-97fc-66d0cffac342", + "2d918db1-91f0-4ab1-ac55-3831e8d98fb0", + "b80be4b9-1698-4fad-bb19-32795a2c967e", + "28ceb362-c9bd-41b9-8c4c-271b761be88c", + "5e32ebfa-f783-47fb-a43b-7fdce8a6b8fd" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 22402, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "title": "Register a derivative IP asset with multiple parent IP assets", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comUsePIL.test.ts", + "file": "/test/e2e/derivativeIP.comUsePIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 1133, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x605f45a1eae94c193f3f8f36b289ad62d299c87d3af99f0aedcb8081acef152d\\\"\\nMinted NFT tokenId: 7322\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f2fc2a1d-cfa2-4972-b34f-180051ef0d55", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 74, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x88c64c908437e6b1fbd085011f0641d8b0b6b556b40b914cb69433621fa869ce\\\",\\\"ipId\\\":\\\"0x4812eAD68A55329628Cc98d7D82afbB6904b726E\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "9aff93a4-7773-42d5-b5a8-43151e13eb63", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 1138, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x55403232bc869a5a748ac6b78c47df78527ae8a35a9efaafe7064d6f07b5fd6c\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d186748c-2bec-4e54-8db0-ff60f3d82b56", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenidB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to WalletB, get a tokenId (tokenidB)", + "timedOut": false, + "duration": 1134, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xc14d75504b86ee02f7832b626206fb4cd96c4f7adbb506a9fb8d3ecee9b8d959\\\"\\nMinted NFT tokenId: 7323\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "172af3db-68c5-44b6-94f1-ecf75cae1c3f", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 64, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x858429c6677399094e71ea21bd61f16a27512f9269bb4a19d003902fa606dbfb\\\",\\\"ipId\\\":\\\"0x0D7a9E45d898ccF33d2C4bFD715BDce114dB08C7\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4327eafe-c603-479c-8225-2b08a6b2ec1a", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 137, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6891204ce39f1de830dc1235608f3f9c3c9c72bac3d58a0f3236ad65e71c4193\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b8bd84a0-264c-498b-9148-df4644dd7c5d", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenidC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to WalletC, get a tokenId (tokenidC)", + "timedOut": false, + "duration": 117, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x78f5fd570f863837cd8e497068d68f60fa1459735538ef081ab7c1d4a1962343\\\"\\nMinted NFT tokenId: 7324\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "71347ccc-defd-4739-8718-073092cc7fcb", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "timedOut": false, + "duration": 64, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x40b28a9577fdeba4fa121eff95f442309090e64aa67ef1d294adffb0bc053d0c\\\",\\\"ipId\\\":\\\"0x12F320938B96E3133571f6ba4D89B8F9A72F433B\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "1b9629b5-4d48-413e-b645-20cec7950281", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can register a derivative IP asset with multiple parent IP assets (ipIdA, ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP asset with multiple parent IP assets Wallet C can register a derivative IP asset with multiple parent IP assets (ipIdA, ipIdB)", + "timedOut": false, + "duration": 18083, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x5ea30e513be86c829aff604dc70d3bfa36e4e0bac8ecde98b4e10bbeb175dd62\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f9686494-7630-4b25-857b-77c90c238eed", + "parentUUID": "2bc728ee-506c-427f-8fa5-3162b8b017bd", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "f2fc2a1d-cfa2-4972-b34f-180051ef0d55", + "9aff93a4-7773-42d5-b5a8-43151e13eb63", + "d186748c-2bec-4e54-8db0-ff60f3d82b56", + "172af3db-68c5-44b6-94f1-ecf75cae1c3f", + "4327eafe-c603-479c-8225-2b08a6b2ec1a", + "b8bd84a0-264c-498b-9148-df4644dd7c5d", + "71347ccc-defd-4739-8718-073092cc7fcb", + "1b9629b5-4d48-413e-b645-20cec7950281", + "f9686494-7630-4b25-857b-77c90c238eed" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 21944, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "title": "Register a derivative IP assets with multiple license tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comUsePIL.test.ts", + "file": "/test/e2e/derivativeIP.comUsePIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 173, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x7c780b3604902c629ebeb60890d56963b8805a4d4ce1e22b26265c857dee0931\\\"\\nMinted NFT tokenId: 7325\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "57c3fc6b-1a41-411d-a1bd-1ef6735507fe", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "timedOut": false, + "duration": 73, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x91d7fa1f4811f8b17810efb15158c56b0a573e6b99d6ad6aec1f9b5242f60936\\\",\\\"ipId\\\":\\\"0xd9C423797E69BfdbA6729Ce3Bc7CA1CDa3d5077e\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "05fd132f-f56d-4551-9d90-d685124ec8a4", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 130, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xaaffd2b7033c416e2fc198804b2701c4a7bb9a40294d9ff905873a7ccb1a6b45\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c37e2c4c-0ecf-4a8c-988e-c0f172c2ae31", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "timedOut": false, + "duration": 5583, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x72c916a3a23d6b9604952bcd0bae5e1d6267c9d22b20fbfbad6b31b0d5cec1d4\\\",\\\"licenseTokenIds\\\":[\\\"6906n\\\",\\\"6907n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5ccc5999-b2a7-44ee-882e-389645208196", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1136, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x51f25495823457a1cb07657903fa58d2aedbb2e6d882c84b4ffa7e8f6294debd\\\"\\nMinted NFT tokenId: 7326\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "7405bacc-3916-409e-bcf5-355b3581e0e1", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "timedOut": false, + "duration": 112, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x381d49c8e61b0b1d438a6f37ad47dc1e70503e35f3eb04995af35e8bb7f266ab\\\",\\\"ipId\\\":\\\"0xB6e360963a6ed20Ad2a0DE1840B28494d33BFf25\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d876ce24-4b9d-4f5b-8f90-ce696fc3620c", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", + "timedOut": false, + "duration": 123, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x1aadc42d340a651f69bd25eeb741a5e17f42f8e40d4eac83e0f681f3b959bc12\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "69875497-c84e-4b97-9ddb-ef795e8f3b7a", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 7603, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x5a0c1a81a1dd080004a0ccaf2bc14d2be82ce4791e7df7078668be184f3ff550\\\",\\\"licenseTokenIds\\\":[\\\"6908n\\\",\\\"6909n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e007be72-7eac-409a-a823-dfd87298a127", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "timedOut": false, + "duration": 131, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x96d1da95a153a1fb5f87d0fdc743f9ac720bfe6eceef5858d90fed5372545db9\\\"\\nMinted NFT tokenId: 7327\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6d79f4a0-9362-4bf7-80a1-fb1822287f80", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 73, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x0210b9e1ff35276e3ecd3abe2a1ac3902d57de01f5f4722cd65fb7df000f65ff\\\",\\\"ipId\\\":\\\"0x44bcD76C976eF48270887938Aa48Cc06cA63ACc5\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "9e46ec9c-e33f-46cc-ac67-8d2f76913958", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can register a derivative IP asset with multiple license tokens (licenseTokenIdA, licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens Wallet C can register a derivative IP asset with multiple license tokens (licenseTokenIdA, licenseTokenIdB)", + "timedOut": false, + "duration": 3513, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa1314763ca0dc4762f5bae941ae1e0dbff126848fd33d9487a83c72dce53f7fe\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e8f244dd-4512-461d-b973-25f6fde33adb", + "parentUUID": "d682a245-7db6-4548-bf69-4fce4ffa5bb0", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "57c3fc6b-1a41-411d-a1bd-1ef6735507fe", + "05fd132f-f56d-4551-9d90-d685124ec8a4", + "c37e2c4c-0ecf-4a8c-988e-c0f172c2ae31", + "5ccc5999-b2a7-44ee-882e-389645208196", + "7405bacc-3916-409e-bcf5-355b3581e0e1", + "d876ce24-4b9d-4f5b-8f90-ce696fc3620c", + "69875497-c84e-4b97-9ddb-ef795e8f3b7a", + "e007be72-7eac-409a-a823-dfd87298a127", + "6d79f4a0-9362-4bf7-80a1-fb1822287f80", + "9e46ec9c-e33f-46cc-ac67-8d2f76913958", + "e8f244dd-4512-461d-b973-25f6fde33adb" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 18650, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "title": "Register a derivative IP assets with multiple license tokens, the sender is not licensee", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comUsePIL.test.ts", + "file": "/test/e2e/derivativeIP.comUsePIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 2131, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x22baea85f82e342cfb67f2388a2ea8d5a653526d104e9bef24d72f398671bbf9\\\"\\nMinted NFT tokenId: 7328\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5e57929b-d937-4e77-a821-06681fab66ff", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "timedOut": false, + "duration": 71, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x1437a53306cfd56afba20a33363e50d519dac7888680b7847978b3cd8dfe4233\\\",\\\"ipId\\\":\\\"0x6C5F53E623F462e973142D3F41aF2D9c1976E774\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "72044e08-1317-435a-8afe-866c38c6e820", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 117, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa2215b8d299eb42f9418d0cae09cb56ff2c9867246f8962bd11c413a4f642de8\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6dd7331d-87c2-4ecc-adaa-3fb6eda87dd7", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "timedOut": false, + "duration": 7617, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x80190f39d7b84942eaf6267121ccddbd8ebdb7cda90e488ca9019b6867bbaef1\\\",\\\"licenseTokenIds\\\":[\\\"6910n\\\",\\\"6911n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "593dce44-2563-48ef-b22b-a9f8f53b2c04", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 3143, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xaae28e87359469242d0acaea7555c68d6c56c270a88de3f1dfec8059b1c7f1dd\\\"\\nMinted NFT tokenId: 7329\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "11d217f3-c847-4a49-8cae-007831273792", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "timedOut": false, + "duration": 80, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x52475350d7edac47ad0196ffce29d73787f20f7cf930eaffdfc0de8b21aa830e\\\",\\\"ipId\\\":\\\"0x40B0d0592b1EACA9a28cB9a099b6118D089e6B7D\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2382b72c-d0e2-40b2-b13e-fb6b1b9f8195", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", + "timedOut": false, + "duration": 2166, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x4fcd850b55a22af1ba2a6fa969b7e5673fbba4744b95fa6d2cc6eab6a3bd3a55\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2d55ab1a-7866-43a8-986e-62f0eb7de9e9", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 2535, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa557b0b56f6ebf2a35423b9facd30129f9168a6ff0d09854c9805e860b0ca5a3\\\",\\\"licenseTokenIds\\\":[\\\"6912n\\\",\\\"6913n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2aa659a8-92f9-4a7d-9a9a-eab59771e022", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "timedOut": false, + "duration": 1150, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x1620cc861b6d35ca04826373c24c532d5e22788611945288fe7f6faf3ae99725\\\"\\nMinted NFT tokenId: 7330\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "562036c3-79b1-4e46-9b3e-472079c2efdc", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 70, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xcfad9b0973daccf1ea2ae42039c5522790788ea77560a0a4cce818823f4f6e6c\\\",\\\"ipId\\\":\\\"0x27a07A9a63100e866aAc332dE317454F4b6AEa98\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d1923375-0e40-443d-9ba0-3eef11749fac", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can NOT register derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet C can NOT register derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 6, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8e11b716-a1fb-45f8-8818-fce108435d56", + "parentUUID": "dba88b6c-2ffe-4d32-846e-1f70c61f7b48", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "5e57929b-d937-4e77-a821-06681fab66ff", + "72044e08-1317-435a-8afe-866c38c6e820", + "6dd7331d-87c2-4ecc-adaa-3fb6eda87dd7", + "593dce44-2563-48ef-b22b-a9f8f53b2c04", + "11d217f3-c847-4a49-8cae-007831273792", + "2382b72c-d0e2-40b2-b13e-fb6b1b9f8195", + "2d55ab1a-7866-43a8-986e-62f0eb7de9e9", + "2aa659a8-92f9-4a7d-9a9a-eab59771e022", + "562036c3-79b1-4e46-9b3e-472079c2efdc", + "d1923375-0e40-443d-9ba0-3eef11749fac", + "8e11b716-a1fb-45f8-8818-fce108435d56" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 19086, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "title": "Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comUsePIL.test.ts", + "file": "/test/e2e/derivativeIP.comUsePIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 109, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xed610ae25d1f701f788b3c95f5b618a63d69cfc6b8029d707df404344c33ef92\\\"\\nMinted NFT tokenId: 7331\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d9c9375f-7488-415f-bb11-e6086e5ae079", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 64, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2fd28f2e73c31f0548fbcb0be8daac9f691d7db6cdc2d2984abea4dbdbb71a59\\\",\\\"ipId\\\":\\\"0xbDF1b76Bd9529e7B2E5f2D8fb49f216f52B322E6\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8941db01-536e-4be5-955e-7d3fb6955172", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 1147, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x5d12a760c8f943d53507a7c1d8fd49c457ede22f9b0c438c71bce61d4fdf4285\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2d6d427b-d796-40ef-8524-f9d9633de3c8", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 2455, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x8c4e0025eb28b4afb816b082339074222ff8cb72149a2a14726f678678247283\\\",\\\"licenseTokenIds\\\":[\\\"6914n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4f2a110a-0c0b-43ce-82cb-501698cac82d", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1122, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xd6221c3b2091e5424299e103b2c8e52dd0305b803bd3ad4b2a4ae2fd7adfabdd\\\"\\nMinted NFT tokenId: 7332\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "23f10054-1112-4b35-8e11-77f0f28fec80", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 126, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xdb29d21858011151db987d59212fe4a3b2e33b73ad27174529f98bb7849d4547\\\",\\\"ipId\\\":\\\"0x2f128d12a063786A8a13425D938b9f9e5F097bAA\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2879e73c-b61b-4e59-bf0c-d1a2e346e510", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B can register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 380, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x8cbf204f55dfc72bcb721706211df0acbe8b320891352902eedfbeebad622711\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0fa30ffa-c619-4c29-bb94-a29d3e7c4922", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 3132, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xdd87dd17600b54a5d92d6fb019a9fe05426601c83c7ed496884a5110878d5ee2\\\"\\nMinted NFT tokenId: 7333\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e1271534-8a9d-44ee-8b09-a85a3f17dbc0", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 1072, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x36230ad1710f084d4ec534ba1a1c437f6ee92801caea728073d0e8d06dab5f5a\\\",\\\"ipId\\\":\\\"0xbcF01e804bC539a63c3C224edd2119e93b7AE662\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "53475d54-ff31-4ab2-b8db-d46bde720a4c", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ea6a5e9c-0199-4072-9389-9134389647ba", + "parentUUID": "7e78f176-db1a-4446-a563-ef74b5d0aab1", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "d9c9375f-7488-415f-bb11-e6086e5ae079", + "8941db01-536e-4be5-955e-7d3fb6955172", + "2d6d427b-d796-40ef-8524-f9d9633de3c8", + "4f2a110a-0c0b-43ce-82cb-501698cac82d", + "23f10054-1112-4b35-8e11-77f0f28fec80", + "2879e73c-b61b-4e59-bf0c-d1a2e346e510", + "0fa30ffa-c619-4c29-bb94-a29d3e7c4922", + "e1271534-8a9d-44ee-8b09-a85a3f17dbc0", + "53475d54-ff31-4ab2-b8db-d46bde720a4c", + "ea6a5e9c-0199-4072-9389-9134389647ba" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 9610, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "title": "Register derivative IP asset with an IP that already has license", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.comUsePIL.test.ts", + "file": "/test/e2e/derivativeIP.comUsePIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 1148, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x045a52305ac694549ba1040f65e8eb3cd30ba9e1e98e0dd1e5823b40e8563280\\\"\\nMinted NFT tokenId: 7334\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c221c9b0-2982-443c-833d-e448160ff57b", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 71, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x640477e16a8cdb04c212070a41316dd0be5774217e63469dcc8b1df52ad67ec2\\\",\\\"ipId\\\":\\\"0xBb280e9E92b2136A61Ff13Fe73B0691bb520fD48\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3fd0df95-4f68-495f-a64e-6f74f25f65f5", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 2235, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x112c948c615afc9d18a46cf55d49224d6c7e59bb2334a0dbf562ed82ca4e122f\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "087bdf3c-a679-4f52-b0e5-28a8a313528b", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 2398, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6e44b330091051d44b229404efe785348e97b19ee31ba32bdca1c97d2df34f72\\\",\\\"licenseTokenIds\\\":[\\\"6915n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "935f92d6-cc34-4fc3-ac39-cecd3e4feb39", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 152, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x13bfeb5a8da51b405f62f62253f58c8526075228eff2b72d1dcfde6df7b2be23\\\"\\nMinted NFT tokenId: 7335\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5f827274-e290-447a-9e5c-3d982516bdc4", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 66, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x29e3bb8edbe3da20d3c226c48327fd69b6b5ab611bad14f28943c27aeb1eaa48\\\",\\\"ipId\\\":\\\"0x23740d70b7798B7446592980CA25995Ac2F453e1\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "cbb0705a-e933-420f-a693-e3c03f7e3d4e", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", + "timedOut": false, + "duration": 3163, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa63be098ceadf53b1483e65175490885ae118f19b02786136c26acb8ee7c4707\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "30c15e7e-755b-4b04-8f46-db3c73d41070", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 6471, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x114921d510fa63ee098b86ab6a434921e26a0189bff9f47ad480d6a2aba7335e\\\",\\\"licenseTokenIds\\\":[\\\"6916n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a7b61f61-ddf8-4082-9e24-00e750b0b308", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL Register derivative IP asset with an IP that already has license Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", + "timedOut": false, + "duration": 7, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b3e345e2-442b-4a39-9a14-1ffd2381d43e", + "parentUUID": "76339e97-a4c9-4be0-a20a-525a0033b4a3", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "c221c9b0-2982-443c-833d-e448160ff57b", + "3fd0df95-4f68-495f-a64e-6f74f25f65f5", + "087bdf3c-a679-4f52-b0e5-28a8a313528b", + "935f92d6-cc34-4fc3-ac39-cecd3e4feb39", + "5f827274-e290-447a-9e5c-3d982516bdc4", + "cbb0705a-e933-420f-a693-e3c03f7e3d4e", + "30c15e7e-755b-4b04-8f46-db3c73d41070", + "a7b61f61-ddf8-4082-9e24-00e750b0b308", + "b3e345e2-442b-4a39-9a14-1ffd2381d43e" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 15711, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "2d830022-061c-4a18-926b-ea706f21b663", + "title": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.nonComPIL.test.ts", + "file": "/test/e2e/derivativeIP.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "26eddb54-3153-4180-8840-301640609583", + "title": "[smoke]Register a derivative IP asset with/without license tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.nonComPIL.test.ts", + "file": "/test/e2e/derivativeIP.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 110, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xa2dbec4ae2930fff0904ff81272e685d42a68ae4dd4a2a79f82d1ecce86be30f\\\"\\nMinted NFT tokenId: 7336\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "efd85b6c-664a-497e-867a-15b959dece93", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 97, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd9a194fe5b78e34fb44ccdb12e1ebfe0f40aa8a01865bc88e1cf0879b866f5d5\\\",\\\"ipId\\\":\\\"0xC7ac4951212EdBC96a1157C8483a139c54DDb3A3\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f9cb6e99-7256-4974-b246-fe1063a7c8c1", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 9874, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xaba0f829c0264643ee7d380829ae3ac6ff4d0136c1daf3855215e3cde1f360c6\\\",\\\"licenseTokenIds\\\":[\\\"6917n\\\",\\\"6918n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "7f782e07-3ab9-4561-8390-76266d3a6d53", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 129, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x57eb13466e08d54ea9ff184874e6c8b1914d7e8f1b15ef13902db1a3677c4164\\\"\\nMinted NFT tokenId: 7337\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f16a8d65-d399-4ad6-a07a-571cd480d561", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 88, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x3971b6ded5cb341605304a894f28ac39f7983e1b899010a65cdb87fa1d742782\\\",\\\"ipId\\\":\\\"0xE33B3D3476e4b0d056a1BE67BAC886C1d3d71b76\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "01a7cbbd-ea93-4e57-bd44-2b31f0d76a5a", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Wallet B can register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 3243, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd670a951166c57659522c8052e9a997aac601205a833c3689d49e31439f443ec\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4f1b9dd3-3156-4e06-a805-a5fa0bf8b553", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC and get a tokenId(tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Mint a NFT to WalletC and get a tokenId(tokenIdC)", + "timedOut": false, + "duration": 3144, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x8f1c7bca4ab7bde54bcd6c29494ff375e61da25e0ece06224dfbb7a6a85eabdb\\\"\\nMinted NFT tokenId: 7338\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "dadf1235-18a1-460a-a78f-993de1d11a1d", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "timedOut": false, + "duration": 67, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xae3dd68a2fb1a00f8a7a4e56d41dbc2e76bdb9aef81e99fc5ba4990e073d4d00\\\",\\\"ipId\\\":\\\"0xCa3497baC8F19f0F062060DBCDd0379Ed7360e1F\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e5fc44de-6a02-4899-a28e-b37b1cc7d35a", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can NOT register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Wallet C can NOT register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "359d969e-9b69-4c0f-b62b-52994919c3da", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can register a derivative IP asset without licenseTokenId", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL [smoke]Register a derivative IP asset with/without license tokens Wallet C can register a derivative IP asset without licenseTokenId", + "timedOut": false, + "duration": 2241, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x9c9ef00c8577182b4d7deacaa2f1f63839a214a32ba22a1447f96470016edbb5\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ddae360b-8cf1-4aa0-975c-77983fc852ac", + "parentUUID": "26eddb54-3153-4180-8840-301640609583", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "efd85b6c-664a-497e-867a-15b959dece93", + "f9cb6e99-7256-4974-b246-fe1063a7c8c1", + "7f782e07-3ab9-4561-8390-76266d3a6d53", + "f16a8d65-d399-4ad6-a07a-571cd480d561", + "01a7cbbd-ea93-4e57-bd44-2b31f0d76a5a", + "4f1b9dd3-3156-4e06-a805-a5fa0bf8b553", + "dadf1235-18a1-460a-a78f-993de1d11a1d", + "e5fc44de-6a02-4899-a28e-b37b1cc7d35a", + "359d969e-9b69-4c0f-b62b-52994919c3da", + "ddae360b-8cf1-4aa0-975c-77983fc852ac" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 18996, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "title": "Register a derivative IP asset with multiple parent IP assets", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.nonComPIL.test.ts", + "file": "/test/e2e/derivativeIP.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 2153, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xb3502b085469a81132444116d20265c783e1609df9e9739c75fbdb59fb509dbb\\\"\\nMinted NFT tokenId: 7339\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3e6ebe89-d4fe-4788-a102-b2609a9079f7", + "parentUUID": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP asset with multiple parent IP assets Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 74, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x9213d69972cf009ba04c9621d1472f8f2ea6366119317e611b02e64767f3ca44\\\",\\\"ipId\\\":\\\"0x9A7223fE0b43aCC8F8a3F197a9d46aF95b0a66C5\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3c91c483-0476-4dd6-8b7d-de49a1c3ff6f", + "parentUUID": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenidB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to WalletB, get a tokenId (tokenidB)", + "timedOut": false, + "duration": 3192, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x40f44fe12a04797be3fc98202cf068df173bb9c275a87f3299a5490acdd0af98\\\"\\nMinted NFT tokenId: 7340\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0c9dd7d0-b003-43f4-8ebe-cb2dfee6a0c0", + "parentUUID": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP asset with multiple parent IP assets Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 67, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf0d5449f08cdb1425ccfbe83b4e00445359b1a300421501410ee2a9af925b723\\\",\\\"ipId\\\":\\\"0x69EDd1D099F848EA45780478C75C92faD690Bb13\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f0066125-3c95-497e-8436-f05a3c96970f", + "parentUUID": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenidC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP asset with multiple parent IP assets Mint a NFT to WalletC, get a tokenId (tokenidC)", + "timedOut": false, + "duration": 1123, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xd00d44f9b894420dbd29d33c788efb8ab60b3358568cf3a3893aa75956a17ecf\\\"\\nMinted NFT tokenId: 7341\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ae0e6f81-ad80-4e5d-be04-82fdc3c0c084", + "parentUUID": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP asset with multiple parent IP assets Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", + "timedOut": false, + "duration": 73, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x7e53aeb5bbe8158a0906f23988591e6c884448ad89fb59352e093de9e40791c6\\\",\\\"ipId\\\":\\\"0x54b3E4169b66727b757062E93940e841452c91e8\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e79a2e39-3628-46f2-99bc-271e41336ff6", + "parentUUID": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can register a derivative IP asset with multiple parent IP assets", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP asset with multiple parent IP assets Wallet C can register a derivative IP asset with multiple parent IP assets", + "timedOut": false, + "duration": 7652, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd9ff334c7ede2d68827bfb145743bf41af840252b6ae47a6f7d118df873babc1\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6aee6a6b-bee5-445d-b0f1-428f55414e38", + "parentUUID": "a11f791d-68d6-4ee4-a11a-117d46d4d344", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "3e6ebe89-d4fe-4788-a102-b2609a9079f7", + "3c91c483-0476-4dd6-8b7d-de49a1c3ff6f", + "0c9dd7d0-b003-43f4-8ebe-cb2dfee6a0c0", + "f0066125-3c95-497e-8436-f05a3c96970f", + "ae0e6f81-ad80-4e5d-be04-82fdc3c0c084", + "e79a2e39-3628-46f2-99bc-271e41336ff6", + "6aee6a6b-bee5-445d-b0f1-428f55414e38" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 14334, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "title": "Register a derivative IP assets with multiple license tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.nonComPIL.test.ts", + "file": "/test/e2e/derivativeIP.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 146, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xd8ba64140d6d416ed99e9bd15c7d3d878a6fcbe76177c8f281c7350b5d61995a\\\"\\nMinted NFT tokenId: 7342\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ac9cefbd-acd4-475f-98d4-da4318c0ea71", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "timedOut": false, + "duration": 92, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x572bd0f0a3da88ea94b29464c65908da3507b1bc977acbb6c06c532d1f2b1eea\\\",\\\"ipId\\\":\\\"0xFf4E72068F0859Bfb349Fae3BE0004265CcE4a8A\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fba755fb-ab98-46c4-a9f6-161f5697f39c", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "timedOut": false, + "duration": 5523, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x04310a388b6314bd89d1a96812e9cb14a58b4fd70d07e0212523ff662bffcff4\\\",\\\"licenseTokenIds\\\":[\\\"6919n\\\",\\\"6920n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b6acc9d9-c501-46e3-aa00-d6101c8a8f72", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 113, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x85fd2a962a179a5f0b1ec54849fc1f8143737bdedd4bb3dd84ebbb7ec9ca6114\\\"\\nMinted NFT tokenId: 7343\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e0029bb5-0576-4630-9173-5330a00a3f9a", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "timedOut": false, + "duration": 79, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x1cb9ecc0b872b4777515b9257354a8c92169730c2a19dcfbd5c1d76dd3840de2\\\",\\\"ipId\\\":\\\"0x9F5311ecC538439f6F0D10d6C5F7013BF0613c02\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "39da2580-0137-4c61-b479-511d7e51bd2b", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 4511, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x93cab80cb52dedba916b9afed243425c6b86a83a889293f9684aa16c65b4f2e9\\\",\\\"licenseTokenIds\\\":[\\\"6921n\\\",\\\"6922n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "423be641-8175-4e61-a1a5-0c772adaab97", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "timedOut": false, + "duration": 2140, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x68dc9b390e3a350c115e676d8d67541aca480435b0a87b4b03ccbabf499babad\\\"\\nMinted NFT tokenId: 7344\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a58c8ad0-4257-4e9c-ad09-7633b1eea7bc", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 64, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6c5e859e40fdeac6239c0afe74b128c8b260453fe7e598436ee947238eaa071c\\\",\\\"ipId\\\":\\\"0x21d613d3193c3BF5aE0969791Cf71BD394Ab6055\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d921a6fc-cf74-40e2-a120-1ad5e7f0307d", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", + "timedOut": false, + "duration": 3411, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x46848dd59ccc9c7f45c338acb5842e159a5cc68867ad286cc71d0f948ef27c9c\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ef57d5b7-a606-4b72-b674-6ee2f019c0a4", + "parentUUID": "787f0b9f-3713-4983-8d22-d5833b05bd90", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "ac9cefbd-acd4-475f-98d4-da4318c0ea71", + "fba755fb-ab98-46c4-a9f6-161f5697f39c", + "b6acc9d9-c501-46e3-aa00-d6101c8a8f72", + "e0029bb5-0576-4630-9173-5330a00a3f9a", + "39da2580-0137-4c61-b479-511d7e51bd2b", + "423be641-8175-4e61-a1a5-0c772adaab97", + "a58c8ad0-4257-4e9c-ad09-7633b1eea7bc", + "d921a6fc-cf74-40e2-a120-1ad5e7f0307d", + "ef57d5b7-a606-4b72-b674-6ee2f019c0a4" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 16079, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "title": "Register a derivative IP assets with multiple license tokens, the sender is not licensee", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.nonComPIL.test.ts", + "file": "/test/e2e/derivativeIP.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 108, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x6068e28e6f39b981d28be795161b12334a302f6cc9e220e356104a0195f6a44f\\\"\\nMinted NFT tokenId: 7345\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d326efea-42d0-42ec-908b-0b6bceb4ef5c", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", + "timedOut": false, + "duration": 72, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb0ac0afcdca1e31d0ef7a43fc696d94cbac570d9c8b7a125b255584d7e257865\\\",\\\"ipId\\\":\\\"0x1FDe7175BACB829659360f86FB504aa633292d24\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "455d0fe1-e69b-4180-9af7-5ef1d23a80cf", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", + "timedOut": false, + "duration": 5468, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6a9d95ae103870be5d97b20b02704499113b003a51dad5b0ddf6caabf066df16\\\",\\\"licenseTokenIds\\\":[\\\"6923n\\\",\\\"6924n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "dd417636-88d8-456e-830c-b315dc729678", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to WalletB, get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 122, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xae289fafc22acf9d82d92d7eb278f75f117ef778dcd0f284ce5f466fbdf96f11\\\"\\nMinted NFT tokenId: 7346\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "71eb7a9e-09d9-41e5-8439-7950803c6340", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", + "timedOut": false, + "duration": 71, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x3ee392e6dcdda62c99e7ce06b08d2fd7f7df70bd32782d0174e91c6bbd24b366\\\",\\\"ipId\\\":\\\"0x4B7C17bd916Ed22273caB2502C51D1218DB7f865\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f9b9f093-8ad2-4314-9710-7d94a8e8f632", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 11601, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x8421bb67285b6977633deb2a85b35ff227f99d4cdda526f18bf521177498cc1d\\\",\\\"licenseTokenIds\\\":[\\\"6925n\\\",\\\"6926n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "7d7e1997-ea12-4257-8499-5a3762c969d9", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Mint a NFT to WalletC, get a tokenId (tokenIdC)", + "timedOut": false, + "duration": 5170, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xcf51f30b9d1fc0af29f13d34d9d06bfa58400da8a3eea062efe8314e6a1476c9\\\"\\nMinted NFT tokenId: 7347\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e36c7c2c-ca6a-4d9e-a9a5-c1ba258c1672", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 65, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xbe239bd0c80f200f58dce2403b3649ede05d81e574ba5db7935ac61391051601\\\",\\\"ipId\\\":\\\"0x5B832625249E183E59D7500B1579F32f144bDBc1\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "9d05b7dd-16b3-4a42-afdc-c5a3fa5dc7b7", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet C can NOT register derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register a derivative IP assets with multiple license tokens, the sender is not licensee Wallet C can NOT register derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 6, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5a77c7d9-631c-470b-8883-98d9af4c5ce4", + "parentUUID": "97d2e440-acf1-4084-9b51-5228cd504ff2", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "d326efea-42d0-42ec-908b-0b6bceb4ef5c", + "455d0fe1-e69b-4180-9af7-5ef1d23a80cf", + "dd417636-88d8-456e-830c-b315dc729678", + "71eb7a9e-09d9-41e5-8439-7950803c6340", + "f9b9f093-8ad2-4314-9710-7d94a8e8f632", + "7d7e1997-ea12-4257-8499-5a3762c969d9", + "e36c7c2c-ca6a-4d9e-a9a5-c1ba258c1672", + "9d05b7dd-16b3-4a42-afdc-c5a3fa5dc7b7", + "5a77c7d9-631c-470b-8883-98d9af4c5ce4" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 22683, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "82410e94-bc65-4eb2-890d-be7ececc8826", + "title": "Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.nonComPIL.test.ts", + "file": "/test/e2e/derivativeIP.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 108, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x64414c3c5dc7e0b3eb4a8ac028fa5e41b024b9a1e27020d87c61c57bceafff8c\\\"\\nMinted NFT tokenId: 7348\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e3c35f82-a363-4aa4-a995-6365b7425bb5", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 65, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x60f3488349c708e684b12fdfdaa5fb939b8c32db3800eb8801738bc560c27564\\\",\\\"ipId\\\":\\\"0xfb2169bdebB7082821a2E5120E3013Bb64ecB3e5\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "90b17410-35a8-4cf7-a311-6a8881213b41", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 2352, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb101072a6da9614f2bf6e0303a38ce4397171f9e2d5fa04c1b4b5ee0322f17cc\\\",\\\"licenseTokenIds\\\":[\\\"6927n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2137185d-046f-4fe0-a272-d81ce0e1c21a", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 118, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x42af5a5f70c5ca938a463210b0a9a2b6f302f0f5061f77bfab11d64acea67f20\\\"\\nMinted NFT tokenId: 7349\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "89e44295-3b34-4620-a4e7-d747d1338914", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 70, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x7bcaa55431c482ff99a989df12181e167b029dfc9f43c85f3e5f852ee9daa69c\\\",\\\"ipId\\\":\\\"0x028E59C1C4125fD098515dB02B58E49cDC067Ab1\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "75b72557-f695-4003-8d93-419e45d3b7a4", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can register a derivative IP asset with licenseTokenIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B can register a derivative IP asset with licenseTokenIdA", + "timedOut": false, + "duration": 5300, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe36a2b113343e3c36853dc7122acd147982254cd7f8c4fd44787a113f200be80\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "bbc6b65b-3864-4403-b422-d820b1a5ae65", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 2136, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x08f71cb7d63ca63576bdc8a0e737d3bf91bc7164bc428fd9f2cb154f2be355e6\\\"\\nMinted NFT tokenId: 7350\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ec46cb1b-8caa-4217-8957-22f3f02df2c4", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", + "timedOut": false, + "duration": 68, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x4cc0fc44773d189091e6c033a3700f07a46f90f317a47b877ff3da7eb005a855\\\",\\\"ipId\\\":\\\"0xcA031552f970f12C434c64C3551eD2B97c2453bb\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "aba40b11-3976-46d5-aa34-5dc9dda49222", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "88d737c3-bff0-4bda-927c-fbaa346479c4", + "parentUUID": "82410e94-bc65-4eb2-890d-be7ececc8826", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "e3c35f82-a363-4aa4-a995-6365b7425bb5", + "90b17410-35a8-4cf7-a311-6a8881213b41", + "2137185d-046f-4fe0-a272-d81ce0e1c21a", + "89e44295-3b34-4620-a4e7-d747d1338914", + "75b72557-f695-4003-8d93-419e45d3b7a4", + "bbc6b65b-3864-4403-b422-d820b1a5ae65", + "ec46cb1b-8caa-4217-8957-22f3f02df2c4", + "aba40b11-3976-46d5-aa34-5dc9dda49222", + "88d737c3-bff0-4bda-927c-fbaa346479c4" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 10220, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "title": "Register derivative IP asset with an IP that already has license", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/derivativeIP.nonComPIL.test.ts", + "file": "/test/e2e/derivativeIP.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 1127, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x5af7a817fd628f6a88b742ef12d33b048ecb13374a96a83fbb5107c71c735b58\\\"\\nMinted NFT tokenId: 7351\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "81b53666-371f-43d0-8309-7e3b2ade6805", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 70, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2822f8d8131717047f95264240b752b494c86034b4a226e28f1bf3dad53632e2\\\",\\\"ipId\\\":\\\"0x672015fC3248cBBF662214547402D4207891E1EF\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "392db7cd-7851-45ba-9314-73e19d3906b8", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", + "timedOut": false, + "duration": 4356, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa6a075b88700375d6c7bd3f2fb6b95923832fcd36e3611f2b3d5352751745e73\\\",\\\"licenseTokenIds\\\":[\\\"6928n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8f2222d6-c76b-4557-b127-46d9b0bd029b", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Mint a NFT to WalletB and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 103, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x91b470771abf97992c1999537fe545de9c13438505a2c0e4372fcca0f5e38c1c\\\"\\nMinted NFT tokenId: 7352\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "81353e30-8d03-4224-8c89-25add95e07e5", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 70, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xdaa9dd6c77bff5e95a96d84c629f3d983640cbae40729cd98c8d5f741699a991\\\",\\\"ipId\\\":\\\"0xC7b147fD3948c4aDa790A1e52c0eb06Ff38BF34f\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f9ade905-1372-442e-af83-d396823b0ef1", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdB", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdB", + "timedOut": false, + "duration": 4172, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd823a7b97d5a04b1bf3e4aa7aab33b7f9be62afa410de984919d21e8fb98a276\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "598ea98a-05e4-41bd-9063-4d17aeb82409", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", + "timedOut": false, + "duration": 1486, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x879e4328d25545968cd7f1f84babf006d96798cca757061b9834d56ae7703851\\\",\\\"licenseTokenIds\\\":[\\\"6929n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "05fe0b28-7738-4385-8b89-03068c7e77b8", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL Register derivative IP asset with an IP that already has license Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", + "timedOut": false, + "duration": 6, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e4584908-1d84-4940-a281-2bfe51add6ee", + "parentUUID": "b024d201-96ac-4b28-b0ed-d7aa67b34e69", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "81b53666-371f-43d0-8309-7e3b2ade6805", + "392db7cd-7851-45ba-9314-73e19d3906b8", + "8f2222d6-c76b-4557-b127-46d9b0bd029b", + "81353e30-8d03-4224-8c89-25add95e07e5", + "f9ade905-1372-442e-af83-d396823b0ef1", + "598ea98a-05e4-41bd-9063-4d17aeb82409", + "05fe0b28-7738-4385-8b89-03068c7e77b8", + "e4584908-1d84-4940-a281-2bfe51add6ee" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 11390, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "a4dfa233-3500-423a-8d99-9e33695dfd11", + "title": "SDK E2E Test - Dispute Module", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "fb89d040-b233-4a81-aa5b-21a1861ebdd0", + "title": "IP Asset is IN_DISPUTE", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register IP assets and raise dispute in \"IP Asset is IN_DISPUTE\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE \"before all\" hook: Register IP assets and raise dispute in \"IP Asset is IN_DISPUTE\"", + "timedOut": false, + "duration": 11884, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const tokenIdA = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyA);\n(0, utils_1.checkMintResult)(tokenIdA);\nconst responseRegisterIpAsset = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"A\", config_1.nftContractAddress, tokenIdA, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseRegisterIpAsset.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responseRegisterIpAsset.ipId).to.be.a(\"string\").and.not.empty;\nipIdA = responseRegisterIpAsset.ipId;\nconst tokenIdB = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyB);\n(0, utils_1.checkMintResult)(tokenIdB);\nconst response = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"B\", config_1.nftContractAddress, tokenIdB, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.ipId).to.be.a(\"string\").and.not.empty;\nipIdB = response.ipId;\nconst responseRaiseDispute = await (0, chai_2.expect)((0, sdkUtils_1.raiseDispute)(\"B\", ipIdA, config_1.arbitrationPolicyAddress, \"test\", \"PLAGIARISM\", waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseRaiseDispute.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responseRaiseDispute.disputeId).to.be.a(\"bigint\").and.to.be.ok;", + "err": {}, + "uuid": "7172e577-98bc-4b1c-8100-342d953aaad2", + "parentUUID": "fb89d040-b233-4a81-aa5b-21a1861ebdd0", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "61db3f93-c4a1-486a-98ae-6a62044520b5", + "title": "Attach License Terms to IN_DISPUTE IP Asset", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Attach non-commerical social remixing PIL to IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Attach License Terms to IN_DISPUTE IP Asset Attach non-commerical social remixing PIL to IN_DISPUTE IP asset", + "timedOut": false, + "duration": 3152, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2fb6a5ab60c50a0fbbd957707a757d42762349fa43ec9a18489842dfaae92397\\\",\\\"success\\\":true}\"\n}", + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"A\", ipIdA, 0n, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;", + "err": {}, + "uuid": "5b986968-dc8b-426b-8515-83983ec5cf5a", + "parentUUID": "61db3f93-c4a1-486a-98ae-6a62044520b5", + "isHook": false, + "skipped": false + }, + { + "title": "Attach commercial use PIL to IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Attach License Terms to IN_DISPUTE IP Asset Attach commercial use PIL to IN_DISPUTE IP asset", + "timedOut": false, + "duration": 57, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x12d6b8f70efee2bf7229ca45dcd85f58e2104b078855c5190538122bed28bea3\\\",\\\"success\\\":true}\"\n}", + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"A\", ipIdA, setup_1.comUseLicenseTermsId1, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;", + "err": {}, + "uuid": "8bbfead7-25d3-4c73-8078-5e02ad462048", + "parentUUID": "61db3f93-c4a1-486a-98ae-6a62044520b5", + "isHook": false, + "skipped": false + }, + { + "title": "Attach commericial remix PIL to IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Attach License Terms to IN_DISPUTE IP Asset Attach commericial remix PIL to IN_DISPUTE IP asset", + "timedOut": false, + "duration": 2080, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x279fd7a07bb4308eea677c995e0f86b9cffac245e1f0e826e472d39022769ee2\\\",\\\"success\\\":true}\"\n}", + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"A\", ipIdA, setup_1.comRemixLicenseTermsId2, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;", + "err": {}, + "uuid": "92bcbf81-7457-4de6-8b82-e4b91b671cb4", + "parentUUID": "61db3f93-c4a1-486a-98ae-6a62044520b5", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "5b986968-dc8b-426b-8515-83983ec5cf5a", + "8bbfead7-25d3-4c73-8078-5e02ad462048", + "92bcbf81-7457-4de6-8b82-e4b91b671cb4" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 5289, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "ef4ebb61-d3d2-4bdd-b8ae-954800cb8a3f", + "title": "Mint License Tokens for IN_DISPUTE IP asset", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint license tokens with non-commerical social remixing PIL for IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Mint License Tokens for IN_DISPUTE IP asset Mint license tokens with non-commerical social remixing PIL for IN_DISPUTE IP asset", + "timedOut": false, + "duration": 6522, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd91ee18d4533f2de9548dc143484379d4467785dd78a044cc90717c83a07ac43\\\",\\\"licenseTokenIds\\\":[\\\"6930n\\\",\\\"6931n\\\"]}\"\n}", + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"A\", ipIdA, setup_1.nonComLicenseTermsId, 2, config_1.accountB.address, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.licenseTokenIds).to.be.a(\"array\").and.to.have.lengthOf(2);", + "err": {}, + "uuid": "1486285c-2932-4f66-a243-64acbd7b0bd4", + "parentUUID": "ef4ebb61-d3d2-4bdd-b8ae-954800cb8a3f", + "isHook": false, + "skipped": false + }, + { + "title": "Mint license tokens with commercial use PIL for IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Mint License Tokens for IN_DISPUTE IP asset Mint license tokens with commercial use PIL for IN_DISPUTE IP asset", + "timedOut": false, + "duration": 5557, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x7494acb975a45d5b7d2b999915e6b21b59b3685c0580af8a1c133dbc2c1d1268\\\",\\\"licenseTokenIds\\\":[\\\"6932n\\\",\\\"6933n\\\"]}\"\n}", + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"A\", ipIdA, setup_1.comUseLicenseTermsId1, 2, config_1.accountB.address, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.licenseTokenIds).to.be.a(\"array\").and.to.have.lengthOf(2);", + "err": {}, + "uuid": "cf13079f-56c0-49d4-8bea-00ea619df7fa", + "parentUUID": "ef4ebb61-d3d2-4bdd-b8ae-954800cb8a3f", + "isHook": false, + "skipped": false + }, + { + "title": "Mint license tokens with commericial remix PIL for IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Mint License Tokens for IN_DISPUTE IP asset Mint license tokens with commericial remix PIL for IN_DISPUTE IP asset", + "timedOut": false, + "duration": 7663, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x0a70d0b8681050a07f5c2c10351c93a9db9155e21ae4a17bc7a087865c2f6451\\\",\\\"licenseTokenIds\\\":[\\\"6934n\\\",\\\"6935n\\\"]}\"\n}", + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"A\", ipIdA, setup_1.comRemixLicenseTermsId2, 2, config_1.accountB.address, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.licenseTokenIds).to.be.a(\"array\").and.to.have.lengthOf(2);\nlicenseTokenId3 = response.licenseTokenIds[0];", + "err": {}, + "uuid": "fb6f9381-c983-4740-bb9e-3e9453108867", + "parentUUID": "ef4ebb61-d3d2-4bdd-b8ae-954800cb8a3f", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "1486285c-2932-4f66-a243-64acbd7b0bd4", + "cf13079f-56c0-49d4-8bea-00ea619df7fa", + "fb6f9381-c983-4740-bb9e-3e9453108867" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 19742, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "6f3e3d38-2c04-4507-8083-aa37a3d589c1", + "title": "Register Derivative IP Asset with License Tokens and Royalty Related Process", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with license tokens attached commercial remix PIL, parent IP is an IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset with License Tokens and Royalty Related Process Register derivative with license tokens attached commercial remix PIL, parent IP is an IN_DISPUTE IP asset", + "timedOut": false, + "duration": 1380, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6182f71ae46e00313639a7be73c33592d1341a8d45ab1fcdaed5e73c6ac628fc\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "85c87c27-70e8-4838-9fbb-0e1b150b0099", + "parentUUID": "6f3e3d38-2c04-4507-8083-aa37a3d589c1", + "isHook": false, + "skipped": false + }, + { + "title": "Pay royalty on behalf", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset with License Tokens and Royalty Related Process Pay royalty on behalf", + "timedOut": false, + "duration": 1045, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xdde28ec08da91c3e149b46f24d5db4dd71778408f1bf0b82b2302b9864d83df8\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fa76ad9f-334c-4607-9411-fab3f7e80c12", + "parentUUID": "6f3e3d38-2c04-4507-8083-aa37a3d589c1", + "isHook": false, + "skipped": false + }, + { + "title": "Collect royalty tokens", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset with License Tokens and Royalty Related Process Collect royalty tokens", + "timedOut": false, + "duration": 37, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf284d76f0a74230821ac754d794076a82b990ea57838767fc436535e808321a6\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a4882742-500f-4026-953d-cdcc784615a8", + "parentUUID": "6f3e3d38-2c04-4507-8083-aa37a3d589c1", + "isHook": false, + "skipped": false + }, + { + "title": "Captue snapshot", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset with License Tokens and Royalty Related Process Captue snapshot", + "timedOut": false, + "duration": 29, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x83a64b4c2d9fe8f3a5c0f53c858ca105c9c3cc2c6e903964c8d9ef7fbf56332b\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4e7aa488-391d-4459-8623-b767a7152ce4", + "parentUUID": "6f3e3d38-2c04-4507-8083-aa37a3d589c1", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset with License Tokens and Royalty Related Process Check claimable revenue", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"420\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f0cbe9d0-7a01-4912-aa4f-ac70c4635733", + "parentUUID": "6f3e3d38-2c04-4507-8083-aa37a3d589c1", + "isHook": false, + "skipped": false + }, + { + "title": "Claim royalty tokens", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset with License Tokens and Royalty Related Process Claim royalty tokens", + "timedOut": false, + "duration": 42, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x81f2727612ab2fc6882586552d98d0228e495215bb1152a36d567a274753183f\\\",\\\"claimableToken\\\":\\\"420n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5bcfee75-3070-4ab3-8c40-e4fb9470c826", + "parentUUID": "6f3e3d38-2c04-4507-8083-aa37a3d589c1", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "85c87c27-70e8-4838-9fbb-0e1b150b0099", + "fa76ad9f-334c-4607-9411-fab3f7e80c12", + "a4882742-500f-4026-953d-cdcc784615a8", + "4e7aa488-391d-4459-8623-b767a7152ce4", + "f0cbe9d0-7a01-4912-aa4f-ac70c4635733", + "5bcfee75-3070-4ab3-8c40-e4fb9470c826" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 2537, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "cb464c15-f1ba-4e4e-bd2f-437e2b3086e3", + "title": "Register Derivative IP Asset without License Tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "5a97cf6f-7d30-431b-a652-7306db1ec3c3", + "title": "Non-commerical social remixing PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register IP Asset in \"Non-commerical social remixing PIL\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset without License Tokens Non-commerical social remixing PIL \"before all\" hook: Register IP Asset in \"Non-commerical social remixing PIL\"", + "timedOut": false, + "duration": 188, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const tokenIdB = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyB);\n(0, utils_1.checkMintResult)(tokenIdB);\nconst response = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"B\", config_1.nftContractAddress, tokenIdB, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.ipId).to.be.a(\"string\").and.not.empty;\nipIdB = response.ipId;", + "err": {}, + "uuid": "31c46a8c-c3ab-4098-9178-aa9753351b2e", + "parentUUID": "5a97cf6f-7d30-431b-a652-7306db1ec3c3", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with non-commercial social remixing PIL, parent IP is an IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset without License Tokens Non-commerical social remixing PIL Register derivative with non-commercial social remixing PIL, parent IP is an IN_DISPUTE IP asset", + "timedOut": false, + "duration": 3473, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xeb11ad2518e371d14d193633d2a2a8fc94d3efeb8427bfa2bee128b4d23cf2e0\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2201ef4d-7f33-4ee5-9a91-53838eb5bce6", + "parentUUID": "5a97cf6f-7d30-431b-a652-7306db1ec3c3", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "2201ef4d-7f33-4ee5-9a91-53838eb5bce6" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 3473, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "5ee4c90a-7792-4b5a-812d-18dc265fc44c", + "title": "Commercial use PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register IP Asset in \"Commercial use PIL\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset without License Tokens Commercial use PIL \"before all\" hook: Register IP Asset in \"Commercial use PIL\"", + "timedOut": false, + "duration": 176, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const tokenIdB = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyB);\n(0, utils_1.checkMintResult)(tokenIdB);\nconst response = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"B\", config_1.nftContractAddress, tokenIdB, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.ipId).to.be.a(\"string\").and.not.empty;\nipIdB = response.ipId;", + "err": {}, + "uuid": "4aeb4fb3-bd71-4485-9c9d-fae4eebacbb6", + "parentUUID": "5ee4c90a-7792-4b5a-812d-18dc265fc44c", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with commercial use PIL, parent IP is an IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset without License Tokens Commercial use PIL Register derivative with commercial use PIL, parent IP is an IN_DISPUTE IP asset", + "timedOut": false, + "duration": 6423, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xaede7042eb664ca56caa1212a0d28469b24d25ff11a5779a0660adb1af73f38e\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "821eb34b-7642-4d3f-8303-86147ad4c82f", + "parentUUID": "5ee4c90a-7792-4b5a-812d-18dc265fc44c", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "821eb34b-7642-4d3f-8303-86147ad4c82f" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 6423, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "9fb49896-e0ee-4167-823a-36e69b93d756", + "title": "Commercial remix PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register IP Asset in \"Commercial remix PIL\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset without License Tokens Commercial remix PIL \"before all\" hook: Register IP Asset in \"Commercial remix PIL\"", + "timedOut": false, + "duration": 2227, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const tokenIdB = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyB);\n(0, utils_1.checkMintResult)(tokenIdB);\nconst response = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"B\", config_1.nftContractAddress, tokenIdB, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.ipId).to.be.a(\"string\").and.not.empty;\nipIdB = response.ipId;", + "err": {}, + "uuid": "b542d1b5-c63d-44dc-8a15-cc368fbc78f7", + "parentUUID": "9fb49896-e0ee-4167-823a-36e69b93d756", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with commercial remix PIL, parent IP is an IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is IN_DISPUTE Register Derivative IP Asset without License Tokens Commercial remix PIL Register derivative with commercial remix PIL, parent IP is an IN_DISPUTE IP asset", + "timedOut": false, + "duration": 1286, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x92bb431f6f90ddd33e9922d95f86d77a987189262cfebfd00f084586ed887a44\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4a1b36a9-0979-4ee9-937d-03ac66266a30", + "parentUUID": "9fb49896-e0ee-4167-823a-36e69b93d756", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "4a1b36a9-0979-4ee9-937d-03ac66266a30" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 1286, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "2bbfc5eb-890d-43ef-90b6-53a1f0b605a9", + "title": "IP Asset is DISPUTED", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register IP assets and raise dispute in \"IP Asset is DISPUTED\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED \"before all\" hook: Register IP assets and raise dispute in \"IP Asset is DISPUTED\"", + "timedOut": false, + "duration": 6609, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const tokenIdA = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyA);\n(0, utils_1.checkMintResult)(tokenIdA);\nconst responseRegisterIpAsset = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"A\", config_1.nftContractAddress, tokenIdA, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseRegisterIpAsset.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responseRegisterIpAsset.ipId).to.be.a(\"string\").and.not.empty;\nipIdA = responseRegisterIpAsset.ipId;\nconst tokenIdB = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyB);\n(0, utils_1.checkMintResult)(tokenIdB);\nconst response = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"B\", config_1.nftContractAddress, tokenIdB, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.ipId).to.be.a(\"string\").and.not.empty;\nipIdB = response.ipId;\nconst responseRaiseDispute = await (0, chai_2.expect)((0, sdkUtils_1.raiseDispute)(\"B\", ipIdA, config_1.arbitrationPolicyAddress, \"test\", \"PLAGIARISM\", waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseRaiseDispute.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responseRaiseDispute.disputeId).to.be.a(\"bigint\").and.to.be.ok;\ndisputeId1 = responseRaiseDispute.disputeId;\nawait (0, utils_1.setDisputeJudgement)(config_1.privateKeyC, disputeId1, true, \"0x\");", + "err": {}, + "uuid": "8f363ad7-2915-4c02-b184-c6ddce0c2600", + "parentUUID": "2bbfc5eb-890d-43ef-90b6-53a1f0b605a9", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "eef658a4-e9c1-4bb2-a7bc-7a60c9c5bf3c", + "title": "Attach License Terms to DISPUTED IP Asset", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Attach non-commerical social remixing PIL to a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Attach License Terms to DISPUTED IP Asset Attach non-commerical social remixing PIL to a DISPUTED IP asset", + "timedOut": false, + "duration": 18, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"A\", ipIdA, 0n, waitForTransaction)).to.be.rejectedWith(\"Failed to attach license terms: The contract function \\\"attachLicenseTerms\\\" reverted.\", \"Error: LicensingModule__DisputedIpId()\");", + "err": {}, + "uuid": "0dcdf24f-d206-4d36-91b4-7138a57162db", + "parentUUID": "eef658a4-e9c1-4bb2-a7bc-7a60c9c5bf3c", + "isHook": false, + "skipped": false + }, + { + "title": "Attach commercial use PIL to an IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Attach License Terms to DISPUTED IP Asset Attach commercial use PIL to an IN_DISPUTE IP asset", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"A\", ipIdA, setup_1.comUseLicenseTermsId1, waitForTransaction)).to.be.rejectedWith(\"Failed to attach license terms: The contract function \\\"attachLicenseTerms\\\" reverted.\", \"Error: LicensingModule__DisputedIpId()\");", + "err": {}, + "uuid": "42cfed67-ee0d-4acd-9b34-53cb96102e52", + "parentUUID": "eef658a4-e9c1-4bb2-a7bc-7a60c9c5bf3c", + "isHook": false, + "skipped": false + }, + { + "title": "Attach commericial remix PIL to an IN_DISPUTE IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Attach License Terms to DISPUTED IP Asset Attach commericial remix PIL to an IN_DISPUTE IP asset", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"A\", ipIdA, setup_1.comRemixLicenseTermsId2, waitForTransaction)).to.be.rejectedWith(\"Failed to attach license terms: The contract function \\\"attachLicenseTerms\\\" reverted.\", \"Error: LicensingModule__DisputedIpId()\");", + "err": {}, + "uuid": "812b20c0-0df3-4eba-bae6-7fb5c0ddf4d5", + "parentUUID": "eef658a4-e9c1-4bb2-a7bc-7a60c9c5bf3c", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "0dcdf24f-d206-4d36-91b4-7138a57162db", + "42cfed67-ee0d-4acd-9b34-53cb96102e52", + "812b20c0-0df3-4eba-bae6-7fb5c0ddf4d5" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 26, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "f7eb48ea-db6a-48cf-bca7-c94742d9cf4f", + "title": "Mint License Tokens for DISPUTED IP asset", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Attach license terms, raise dispute and set judgement in \"Mint License Tokens for DISPUTED IP asset\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Mint License Tokens for DISPUTED IP asset \"before all\" hook: Attach license terms, raise dispute and set judgement in \"Mint License Tokens for DISPUTED IP asset\"", + "timedOut": false, + "duration": 1369, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const responseComUsePIL = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"B\", ipIdB, setup_1.comUseLicenseTermsId1, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseComUsePIL.txHash).to.be.a(\"string\").and.not.empty;\nconst responsecomRemixPIL = await (0, chai_2.expect)((0, sdkUtils_1.attachLicenseTerms)(\"B\", ipIdB, setup_1.comRemixLicenseTermsId2, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responsecomRemixPIL.txHash).to.be.a(\"string\").and.not.empty;\nconst responseRaiseDispute = await (0, chai_2.expect)((0, sdkUtils_1.raiseDispute)(\"A\", ipIdB, config_1.arbitrationPolicyAddress, \"test\", \"PLAGIARISM\", waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseRaiseDispute.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responseRaiseDispute.disputeId).to.be.a(\"bigint\").and.to.be.ok;\ndisputeId2 = responseRaiseDispute.disputeId;\nawait (0, utils_1.setDisputeJudgement)(config_1.privateKeyC, disputeId2, true, \"0x\");", + "err": {}, + "uuid": "51f74b9e-8fa2-47b7-9316-14064a8a292a", + "parentUUID": "f7eb48ea-db6a-48cf-bca7-c94742d9cf4f", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Mint license tokens with non-commerical social remixing PIL for a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Mint License Tokens for DISPUTED IP asset Mint license tokens with non-commerical social remixing PIL for a DISPUTED IP asset", + "timedOut": false, + "duration": 5, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"B\", ipIdB, setup_1.nonComLicenseTermsId, 2, config_1.accountB.address, waitForTransaction)).to.be.rejectedWith(\"Failed to mint license tokens: The contract function \\\"mintLicenseTokens\\\" reverted.\", \"Error: LicensingModule__DisputedIpId()\");", + "err": {}, + "uuid": "92622fbe-7c32-413e-bf92-44d3b833d68c", + "parentUUID": "f7eb48ea-db6a-48cf-bca7-c94742d9cf4f", + "isHook": false, + "skipped": false + }, + { + "title": "Mint license tokens with commerical use PIL for a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Mint License Tokens for DISPUTED IP asset Mint license tokens with commerical use PIL for a DISPUTED IP asset", + "timedOut": false, + "duration": 6, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"B\", ipIdB, setup_1.comUseLicenseTermsId1, 2, config_1.accountB.address, waitForTransaction)).to.be.rejectedWith(\"Failed to mint license tokens: The contract function \\\"mintLicenseTokens\\\" reverted.\", \"Error: LicensingModule__DisputedIpId()\");", + "err": {}, + "uuid": "9b8b0c81-d2ba-4ab6-b1f7-9f2d2e450d08", + "parentUUID": "f7eb48ea-db6a-48cf-bca7-c94742d9cf4f", + "isHook": false, + "skipped": false + }, + { + "title": "Mint license tokens with commericial remix PIL for a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Mint License Tokens for DISPUTED IP asset Mint license tokens with commericial remix PIL for a DISPUTED IP asset", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "const response = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"B\", ipIdB, setup_1.comRemixLicenseTermsId2, 2, config_1.accountB.address, waitForTransaction)).to.be.rejectedWith(\"Failed to mint license tokens: The contract function \\\"mintLicenseTokens\\\" reverted.\", \"Error: LicensingModule__DisputedIpId()\");", + "err": {}, + "uuid": "38130f39-aa32-46b9-b20b-039c45d25952", + "parentUUID": "f7eb48ea-db6a-48cf-bca7-c94742d9cf4f", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "92622fbe-7c32-413e-bf92-44d3b833d68c", + "9b8b0c81-d2ba-4ab6-b1f7-9f2d2e450d08", + "38130f39-aa32-46b9-b20b-039c45d25952" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 15, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "6f15bece-7b14-4769-93bb-7b2e576e3c57", + "title": "Register Derivative IP Asset without License Tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register IP Asset in \"Register Derivative IP Asset without License Tokens\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset without License Tokens \"before all\" hook: Register IP Asset in \"Register Derivative IP Asset without License Tokens\"", + "timedOut": false, + "duration": 2194, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const tokenIdC = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyA);\n(0, utils_1.checkMintResult)(tokenIdC);\nconst response = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"A\", config_1.nftContractAddress, tokenIdC, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.ipId).to.be.a(\"string\").and.not.empty;\nipIdC = response.ipId;", + "err": {}, + "uuid": "8b6a97bc-89c0-4c10-9811-c03f76153bef", + "parentUUID": "6f15bece-7b14-4769-93bb-7b2e576e3c57", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "e7baa07c-d2e2-40cb-8ad8-1a0b73ed01af", + "title": "Non-commerical social remixing PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with non-commercial social remixing PIL, parent IP is a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset without License Tokens Non-commerical social remixing PIL Register derivative with non-commercial social remixing PIL, parent IP is a DISPUTED IP asset", + "timedOut": false, + "duration": 2067, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f0c7e565-faf1-4d4f-8f0e-bcea4ed46431", + "parentUUID": "e7baa07c-d2e2-40cb-8ad8-1a0b73ed01af", + "isHook": false, + "skipped": false + }, + { + "title": "Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset without License Tokens Non-commerical social remixing PIL Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", + "timedOut": false, + "duration": 1120, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe545c5ad0cd2107e713b824ef5d75769112cdff1130222e479ff98a885e55f7d\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a45e6a31-ae8e-45db-936e-36a60bc64ac7", + "parentUUID": "e7baa07c-d2e2-40cb-8ad8-1a0b73ed01af", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "f0c7e565-faf1-4d4f-8f0e-bcea4ed46431", + "a45e6a31-ae8e-45db-936e-36a60bc64ac7" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 3187, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "bc79bfd0-2500-4877-b3dc-dea5f9d232d8", + "title": "Commercial use PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with commercial use PIL, parent IP is a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset without License Tokens Commercial use PIL Register derivative with commercial use PIL, parent IP is a DISPUTED IP asset", + "timedOut": false, + "duration": 9, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3b422146-4818-45a0-bf77-bf123d49ccda", + "parentUUID": "bc79bfd0-2500-4877-b3dc-dea5f9d232d8", + "isHook": false, + "skipped": false + }, + { + "title": "Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset without License Tokens Commercial use PIL Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", + "timedOut": false, + "duration": 71, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xbb8ecd62404ef8d3e59b58aea6a4aa85a867a559a4b9aab65ba267894527046f\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5de6acaa-a06f-41bc-8699-a86a8a9e0651", + "parentUUID": "bc79bfd0-2500-4877-b3dc-dea5f9d232d8", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "3b422146-4818-45a0-bf77-bf123d49ccda", + "5de6acaa-a06f-41bc-8699-a86a8a9e0651" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 80, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "26c4c2c2-49cd-4844-b271-8e44721ac984", + "title": "Commercial remix PIL", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with commercial remix PIL, parent IP is a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset without License Tokens Commercial remix PIL Register derivative with commercial remix PIL, parent IP is a DISPUTED IP asset", + "timedOut": false, + "duration": 5, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2ef830f2-a2db-4289-b5b3-c7239656884f", + "parentUUID": "26c4c2c2-49cd-4844-b271-8e44721ac984", + "isHook": false, + "skipped": false + }, + { + "title": "Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset without License Tokens Commercial remix PIL Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", + "timedOut": false, + "duration": 1079, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6c1fddf8dbd6c529769372185ecddfc6c96d6b349b4411755790f0f4665a559b\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "73146377-b80e-4043-b333-e49199050ca4", + "parentUUID": "26c4c2c2-49cd-4844-b271-8e44721ac984", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "2ef830f2-a2db-4289-b5b3-c7239656884f", + "73146377-b80e-4043-b333-e49199050ca4" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 1084, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "d7b2017f-3af7-496b-8682-59ea4093cddc", + "title": "Register Derivative IP Asset with License Tokens", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register IP Asset in \"Register Derivative IP Asset with License Tokens\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens \"before all\" hook: Register IP Asset in \"Register Derivative IP Asset with License Tokens\"", + "timedOut": false, + "duration": 32852, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const responseResolveDispute = await (0, chai_2.expect)((0, sdkUtils_1.resolveDispute)(\"A\", disputeId2, \"0x0000\", false)).to.not.be.rejected;\n(0, chai_2.expect)(responseResolveDispute.txHash).to.be.a(\"string\").and.not.empty;\nawait (0, utils_1.sleep)(10);\nconst responsemintLicenseTokens1 = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"B\", ipIdB, setup_1.nonComLicenseTermsId, 2, config_1.accountA.address, true)).to.not.be.rejected;\n(0, chai_2.expect)(responsemintLicenseTokens1.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responsemintLicenseTokens1.licenseTokenIds).to.be.a(\"array\").and.to.have.lengthOf(2);\nlicenseTokenId1 = responsemintLicenseTokens1.licenseTokenIds[0];\nconst responsemintLicenseTokens2 = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"B\", ipIdB, setup_1.comUseLicenseTermsId1, 2, config_1.accountA.address, true)).to.not.be.rejected;\n(0, chai_2.expect)(responsemintLicenseTokens2.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responsemintLicenseTokens2.licenseTokenIds).to.be.a(\"array\").and.to.have.lengthOf(2);\nlicenseTokenId2 = responsemintLicenseTokens2.licenseTokenIds[0];\nconst responsemintLicenseTokens3 = await (0, chai_2.expect)((0, sdkUtils_1.mintLicenseTokens)(\"B\", ipIdB, setup_1.comRemixLicenseTermsId2, 2, config_1.accountA.address, true)).to.not.be.rejected;\n(0, chai_2.expect)(responsemintLicenseTokens3.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responsemintLicenseTokens3.licenseTokenIds).to.be.a(\"array\").and.to.have.lengthOf(2);\nlicenseTokenId3 = responsemintLicenseTokens3.licenseTokenIds[0];\nconst responseRaiseDispute = await (0, chai_2.expect)((0, sdkUtils_1.raiseDispute)(\"A\", ipIdB, config_1.arbitrationPolicyAddress, \"test\", \"PLAGIARISM\", waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseRaiseDispute.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responseRaiseDispute.disputeId).to.be.a(\"bigint\").and.to.be.ok;\ndisputeId2 = responseRaiseDispute.disputeId;\nawait (0, utils_1.setDisputeJudgement)(config_1.privateKeyC, disputeId2, true, \"0x\");\nconst tokenIdC = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyA);\n(0, utils_1.checkMintResult)(tokenIdC);\nconst response = await (0, chai_2.expect)((0, sdkUtils_1.registerIpAsset)(\"A\", config_1.nftContractAddress, tokenIdC, waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(response.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(response.ipId).to.be.a(\"string\").and.not.empty;\nipIdC = response.ipId;", + "err": {}, + "uuid": "9faea1de-2dde-42a3-9cbc-ad9ecc6ae911", + "parentUUID": "d7b2017f-3af7-496b-8682-59ea4093cddc", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "cc8bfcbf-dea9-44c5-9b6e-b3db302dabf0", + "title": "Register derivative IP asset, parent IP is a DISPUTED IP asset, ", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Non-commerical social remixing PIL", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens Register derivative IP asset, parent IP is a DISPUTED IP asset, Non-commerical social remixing PIL", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f9fde839-9653-4229-b5d6-777d6dd83dc1", + "parentUUID": "cc8bfcbf-dea9-44c5-9b6e-b3db302dabf0", + "isHook": false, + "skipped": false + }, + { + "title": "Commercial use PIL", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens Register derivative IP asset, parent IP is a DISPUTED IP asset, Commercial use PIL", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4c25d207-1df3-46c8-91dc-5122de11a851", + "parentUUID": "cc8bfcbf-dea9-44c5-9b6e-b3db302dabf0", + "isHook": false, + "skipped": false + }, + { + "title": "Register derivative with commercial remix PIL, parent IP is a DISPUTED IP asset", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens Register derivative IP asset, parent IP is a DISPUTED IP asset, Register derivative with commercial remix PIL, parent IP is a DISPUTED IP asset", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3d069ad6-a8a1-481e-be21-f8fc49ac121d", + "parentUUID": "cc8bfcbf-dea9-44c5-9b6e-b3db302dabf0", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "f9fde839-9653-4229-b5d6-777d6dd83dc1", + "4c25d207-1df3-46c8-91dc-5122de11a851", + "3d069ad6-a8a1-481e-be21-f8fc49ac121d" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 12, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "178a18a3-b9e9-4e64-a1fa-4dba8021492b", + "title": "Register derivative IP asset, derivative IP is a DISPUTED IP asset, ", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Resolve dispute for the parent IP, raise dispute for the derivative IP in \"Register derivative IP asset, derivative IP is a DISPUTED IP asset, \"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens Register derivative IP asset, derivative IP is a DISPUTED IP asset, \"before all\" hook: Resolve dispute for the parent IP, raise dispute for the derivative IP in \"Register derivative IP asset, derivative IP is a DISPUTED IP asset, \"", + "timedOut": false, + "duration": 1213, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const responseResolveDispute = await (0, chai_2.expect)((0, sdkUtils_1.resolveDispute)(\"A\", disputeId2, \"0x0000\", false)).to.not.be.rejected;\n(0, chai_2.expect)(responseResolveDispute.txHash).to.be.a(\"string\").and.not.empty;\nconst responseRaiseDispute = await (0, chai_2.expect)((0, sdkUtils_1.raiseDispute)(\"B\", ipIdC, config_1.arbitrationPolicyAddress, \"test\", \"PLAGIARISM\", waitForTransaction)).to.not.be.rejected;\n(0, chai_2.expect)(responseRaiseDispute.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_2.expect)(responseRaiseDispute.disputeId).to.be.a(\"bigint\").and.to.be.ok;\ndisputeId3 = responseRaiseDispute.disputeId;\nawait (0, utils_1.setDisputeJudgement)(config_1.privateKeyC, disputeId3, true, \"0x\");", + "err": {}, + "uuid": "462a15f3-d85e-4cae-8ca4-e199c0a6e214", + "parentUUID": "178a18a3-b9e9-4e64-a1fa-4dba8021492b", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Non-commerical social remixing PIL", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens Register derivative IP asset, derivative IP is a DISPUTED IP asset, Non-commerical social remixing PIL", + "timedOut": false, + "duration": 6, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b1442ea5-4b58-43fc-a9b5-28f7e51858d3", + "parentUUID": "178a18a3-b9e9-4e64-a1fa-4dba8021492b", + "isHook": false, + "skipped": false + }, + { + "title": "Commerical use PIL", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens Register derivative IP asset, derivative IP is a DISPUTED IP asset, Commerical use PIL", + "timedOut": false, + "duration": 5, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "de8e3053-175a-47d2-9e6c-ae7dc20c7439", + "parentUUID": "178a18a3-b9e9-4e64-a1fa-4dba8021492b", + "isHook": false, + "skipped": false + }, + { + "title": "Commerical remix PIL", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens Register derivative IP asset, derivative IP is a DISPUTED IP asset, Commerical remix PIL", + "timedOut": false, + "duration": 5, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f208362c-4ca1-448b-8c86-9c8c2055e31e", + "parentUUID": "178a18a3-b9e9-4e64-a1fa-4dba8021492b", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "b1442ea5-4b58-43fc-a9b5-28f7e51858d3", + "de8e3053-175a-47d2-9e6c-ae7dc20c7439", + "f208362c-4ca1-448b-8c86-9c8c2055e31e" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 16, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "title": "Register Derivative IP Asset with License Tokens and Royalty Related Process", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/dispute.test.ts", + "file": "/test/e2e/dispute.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Resolve dispute for the derivative IP in \"Register Derivative IP Asset with License Tokens and Royalty Related Process\"", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process \"before all\" hook: Resolve dispute for the derivative IP in \"Register Derivative IP Asset with License Tokens and Royalty Related Process\"", + "timedOut": false, + "duration": 10012, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "const responseResolveDispute = await (0, chai_2.expect)((0, sdkUtils_1.resolveDispute)(\"B\", disputeId3, \"0x0000\", false)).to.not.be.rejected;\n(0, chai_2.expect)(responseResolveDispute.txHash).to.be.a(\"string\").and.not.empty;\nawait (0, utils_1.sleep)(10);", + "err": {}, + "uuid": "c50b581a-55e4-402d-ab5a-25e2be45c38f", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Register derivative with license tokens attached commercial remix PIL", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Register derivative with license tokens attached commercial remix PIL", + "timedOut": false, + "duration": 5454, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xced5332ae6d09a4efc3a76e3bf55fbdcf3772e8a42f0a0b362067efd7b5dc74c\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4c592ab1-7c04-423e-9b54-c7c50d3421b4", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Raise dispute for the parent IP and set dispute judgement", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Raise dispute for the parent IP and set dispute judgement", + "timedOut": false, + "duration": 3177, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2767af199e574d5eb7c14571a29a8ebe158bb1419e6842d69a06af4a8e860e84\\\",\\\"disputeId\\\":\\\"140n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "afef5182-9236-4099-9027-c35c0946e45f", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Pay royalty on behalf, parent IP is DISPUTED", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Pay royalty on behalf, parent IP is DISPUTED", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "19796c6a-2316-44b5-9c08-a7d16afde6c2", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Pay royalty on behalf, derivative IP is DISPUTED", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Pay royalty on behalf, derivative IP is DISPUTED", + "timedOut": false, + "duration": 1182, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2a810a1351f5384c57f2fc074c85b3a6950c864a0d0fa73dad39a85c6cc7e285\\\"}\\n{\\\"txHash\\\":\\\"0xa80b9ba14cf3992df8984ad7a512fe471f9812bcc17355b1ed54a6034510a3e9\\\",\\\"disputeId\\\":\\\"141n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6645f358-d00c-4ac5-b805-e8cc972eb5cb", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Pay royalty on behalf", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Pay royalty on behalf", + "timedOut": false, + "duration": 10031, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x5ea5d9cc566a74e2d41929e8e488e48db98da5ef89e07e763668385c64548fea\\\"}\\n{\\\"txHash\\\":\\\"0x1055ce92ad7b129adfc5aba20accb1c8fcc7f17671fa81533060acb84e4c564c\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d3bda5c9-60f4-4abe-a7e1-6d53647d6b50", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Raise dispute for the parent IP and set dispute judgement", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Raise dispute for the parent IP and set dispute judgement", + "timedOut": false, + "duration": 156, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xdcc3d77d6c342a1705cac25785258acdb40b4ea2cbb23fd6467a8119a759b20d\\\",\\\"disputeId\\\":\\\"142n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "da7f3b1e-d97d-4ec0-a5cb-813e81fe3764", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Collect royalty tokens", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Collect royalty tokens", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xc6900ceff1292538ddf9a0bf9a53e4f60219924b8c36e367288350fd48b4ff8c\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5bdf852d-37fd-4080-ad9a-52b799cc8895", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Captue snapshot", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Captue snapshot", + "timedOut": false, + "duration": 12, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2fdbb2b936c07ec67ab20491015ee5a329d5840858df175bb586531cb47085be\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e40da2fb-94cd-4ced-8e32-23386d4629e3", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Check claimable revenue", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d48f9741-7720-482f-ad07-0e767b5fd08b", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + }, + { + "title": "Claim royalty tokens", + "fullTitle": "SDK E2E Test - Dispute Module IP Asset is DISPUTED Register Derivative IP Asset with License Tokens and Royalty Related Process Claim royalty tokens", + "timedOut": false, + "duration": 1050, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd861f18763fce93aa8c363b962a4d4055d332be1e3c2ef262d6745456593c629\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "282a0722-1370-4308-ad98-4b01acd9a413", + "parentUUID": "8a10ce0e-20db-4536-a7b2-34ef73781430", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "4c592ab1-7c04-423e-9b54-c7c50d3421b4", + "afef5182-9236-4099-9027-c35c0946e45f", + "19796c6a-2316-44b5-9c08-a7d16afde6c2", + "6645f358-d00c-4ac5-b805-e8cc972eb5cb", + "d3bda5c9-60f4-4abe-a7e1-6d53647d6b50", + "da7f3b1e-d97d-4ec0-a5cb-813e81fe3764", + "5bdf852d-37fd-4080-ad9a-52b799cc8895", + "e40da2fb-94cd-4ced-8e32-23386d4629e3", + "d48f9741-7720-482f-ad07-0e767b5fd08b", + "282a0722-1370-4308-ad98-4b01acd9a413" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 21085, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "4e234874-8ee2-4808-99f7-d656dd0f74ec", + "title": "SDK E2E Test", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/licenseTerms.nonComPIL.test.ts", + "file": "/test/e2e/licenseTerms.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "title": "Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/licenseTerms.nonComPIL.test.ts", + "file": "/test/e2e/licenseTerms.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 133, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x5f2ed31c140bc04fca0823251e2073869906814056620feda3440b756a1a0136\\\"\\nMinted NFT tokenId: 7362\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "789e775b-d9fa-4eaa-a537-54c9ed4f0f5f", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 84, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf75bd350ef95a524568f092e6514cc553ca9222bbb0d94982570bd7854376636\\\",\\\"ipId\\\":\\\"0x2B866819E6756228dCA4483a0A6eD118bD3C1b24\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f1e19fc5-c0f1-4ec3-800d-2ae930e6ab0c", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach the non-commercial social remixing PIL(licenseTermsId:0 - transferable:false) to ipIdA", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false Wallet A attach the non-commercial social remixing PIL(licenseTermsId:0 - transferable:false) to ipIdA", + "timedOut": false, + "duration": 121, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x794ec0b69deac5782caecd6f6a30de9b8af4efbf8f9855a0d0c90ae14f5f0a26\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "373611e4-91b4-4ac4-a929-e167232274f5", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenId1)", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenId1)", + "timedOut": false, + "duration": 7315, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe3c064b08093503eeab0d3bfd05f69b8d0c6d0fc6d66330be8001b250ee4aecd\\\",\\\"licenseTokenIds\\\":[\\\"6942n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2f52baa9-b9a2-4c1c-b1c7-8921279e6c51", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + }, + { + "title": "\"transferable\":false, 1 - check the owner of licenseTokenId1", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false \"transferable\":false, 1 - check the owner of licenseTokenId1", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Owner: 0xC7Fffc7bA56026b471AE5f792A012E5a29c37a82\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6c1ae309-4270-492c-aa56-5449be25ee72", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + }, + { + "title": "\"transferable\":false, 2 - WalletB cannot transfer licenseTokenId to WalletA as LicenseToken__NotTransferable()", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false \"transferable\":false, 2 - WalletB cannot transfer licenseTokenId to WalletA as LicenseToken__NotTransferable()", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"The contract function \\\"transferFrom\\\" reverted with the following signature: 0xd175f85c\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a23b5702-5caa-4d41-8b09-2e2ba48f2bfc", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + }, + { + "title": "\"transferable\":false, 3 - check the owner of licenseTokenId1 again", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false \"transferable\":false, 3 - check the owner of licenseTokenId1 again", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Owner: 0xC7Fffc7bA56026b471AE5f792A012E5a29c37a82\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b580a200-069f-49fb-8a18-3af63785cb7c", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + }, + { + "title": "\"derivativesAllowed\":false, cannot register an IP asset as licenseTokenId1's derivative as LicenseTokenNotCompatibleForDerivative", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":false, \"derivativesAllowed\":false \"derivativesAllowed\":false, cannot register an IP asset as licenseTokenId1's derivative as LicenseTokenNotCompatibleForDerivative", + "timedOut": false, + "duration": 2231, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x1199bd467cdf8081426574b25ff8b6f780bffffce3a08c92082dc2244a339282\\\"\\nMinted NFT tokenId: 7363\\n{\\\"txHash\\\":\\\"0x863f14a50611b45af2478fd91b56e0bd4e84b77915041291a64ccac4e84f71c6\\\",\\\"ipId\\\":\\\"0x6211fa7859A09CbBb9522aBFfdE78438335116aA\\\"}\\nFailed to register derivative with license tokens: The contract function \\\"registerDerivativeWithLicenseTokens\\\" reverted. Error: LicensingModule__LicenseTokenNotCompatibleForDerivative(address childIpId, uint256[] licenseTokenIds)\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "20768df1-349c-4952-bf8d-732320f61f39", + "parentUUID": "1b6544ab-8811-4182-bcfc-2e7e870f82c4", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "789e775b-d9fa-4eaa-a537-54c9ed4f0f5f", + "f1e19fc5-c0f1-4ec3-800d-2ae930e6ab0c", + "373611e4-91b4-4ac4-a929-e167232274f5", + "2f52baa9-b9a2-4c1c-b1c7-8921279e6c51", + "6c1ae309-4270-492c-aa56-5449be25ee72", + "a23b5702-5caa-4d41-8b09-2e2ba48f2bfc", + "b580a200-069f-49fb-8a18-3af63785cb7c", + "20768df1-349c-4952-bf8d-732320f61f39" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 9890, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "title": "Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/licenseTerms.nonComPIL.test.ts", + "file": "/test/e2e/licenseTerms.nonComPIL.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 113, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x849a2901bd64ce602b389c832402e3a3e9488d89b8f67163c19fae3a82d437f1\\\"\\nMinted NFT tokenId: 7364\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "188805df-a2a2-4ed8-b4ed-c2543b6ddde8", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset and default attach the non-commercial remixing PIL(licenseTermsId:2 - \"transferable\":true\"), get an ipId (ipIdA) and a licenseTermsId (licenseTermsId1)", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true Wallet A register an IP Asset and default attach the non-commercial remixing PIL(licenseTermsId:2 - \"transferable\":true\"), get an ipId (ipIdA) and a licenseTermsId (licenseTermsId1)", + "timedOut": false, + "duration": 69, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6976d63e955d8ec6ad6fe960e9992631a26b45c082b97748ac0283e6d18c271f\\\",\\\"ipId\\\":\\\"0x710A4c49Ad475C508C2eC324ffc59117E157006b\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2a2ef27a-80e2-4938-856c-b0203bc31f26", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach another non-commercial social remixing PIL(licenseTermsId:0) to ipIdA", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true Wallet A attach another non-commercial social remixing PIL(licenseTermsId:0) to ipIdA", + "timedOut": false, + "duration": 4193, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xc75c6e9fe01b20227d333c88fda31dc77a74198d2cd2e65cf36ca9d9994a201d\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b5424227-2e44-485b-9318-44cbb01343a1", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A mint a license token with ipIdA and licenseTermsId1, get a licenseTokenId (licenseTokenId1)", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true Wallet A mint a license token with ipIdA and licenseTermsId1, get a licenseTokenId (licenseTokenId1)", + "timedOut": false, + "duration": 3283, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa08c96b66b9e30adba11968e470ab296ba2aba70b21c94ec0f4c9e14404e1cbb\\\",\\\"licenseTokenIds\\\":[\\\"6943n\\\"]}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "961d71f6-c8a5-411b-b0e3-a51f666e863c", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "\"derivativesAllowed\":true & \"derivativesReciprocal\":true, only can register a derivative with the same license terms as parent IP", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true \"derivativesAllowed\":true & \"derivativesReciprocal\":true, only can register a derivative with the same license terms as parent IP", + "timedOut": false, + "duration": 16649, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x0242d249a3dd12a27d7d492d691e707edb47674ec336ffd1d1e410fa3b74290d\\\"\\nMinted NFT tokenId: 7365\\n{\\\"txHash\\\":\\\"0xaf2c96e918c33bf1105230d7bb17a5aae2849bf2ea26cfa4497efe4da3f9e3de\\\",\\\"ipId\\\":\\\"0x419bB424C2c86532CcD926Bd011E5318f6cc3Da3\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d9481590-dbd0-42fc-84ca-ae5f42e545f2", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "\"derivativesReciprocal\":true, derivative IP cannot add additional license terms", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true \"derivativesReciprocal\":true, derivative IP cannot add additional license terms", + "timedOut": false, + "duration": 23, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"The contract function \\\"attachLicenseTerms\\\" reverted with the following signature: 0x1ae3058f\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6de1c4fa-1c9e-46fd-bd38-200c135588eb", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "\"transferable\":true, 1 - check the owner of licenseTokenId1", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true \"transferable\":true, 1 - check the owner of licenseTokenId1", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Owner: 0x3679649FCDb9528F26e508b59d7Dd8de73b612E1\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "1c33c839-e362-4865-9391-a9532cde126d", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "\"transferable\":true, 2 - wallet A can transfer the licenseTokenId to Wallet B", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true \"transferable\":true, 2 - wallet A can transfer the licenseTokenId to Wallet B", + "timedOut": false, + "duration": 50, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Transaction hash: 0xeffbebd40f8ac8ce3abcb1210b7cd8a9e7c0543d612eff3b07b6709f30097f69\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "752e8296-4611-4cd8-ae8a-ab61bf496600", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + }, + { + "title": "\"transferable\":true, 3 - check the owner of licenseTokenId1 again", + "fullTitle": "SDK E2E Test Non-Commercial Social Remixing PIL: \"transferable\":true, \"derivativesAllowed\":true, \"derivativesReciprocal\":true \"transferable\":true, 3 - check the owner of licenseTokenId1 again", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Owner: 0xC7Fffc7bA56026b471AE5f792A012E5a29c37a82\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "61fb89c9-9e52-4c31-8e23-9d9ca1638188", + "parentUUID": "ccf624ef-3535-440b-900f-a9d2bd8fec4e", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "188805df-a2a2-4ed8-b4ed-c2543b6ddde8", + "2a2ef27a-80e2-4938-856c-b0203bc31f26", + "b5424227-2e44-485b-9318-44cbb01343a1", + "961d71f6-c8a5-411b-b0e3-a51f666e863c", + "d9481590-dbd0-42fc-84ca-ae5f42e545f2", + "6de1c4fa-1c9e-46fd-bd38-200c135588eb", + "1c33c839-e362-4865-9391-a9532cde126d", + "752e8296-4611-4cd8-ae8a-ab61bf496600", + "61fb89c9-9e52-4c31-8e23-9d9ca1638188" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 24384, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "0a7617a4-5df8-48fe-9bb5-174ea1440858", + "title": "SDK E2E Test - Register Derivative IP Asset with multiple PILs", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/multiLIcenseTerms.test.ts", + "file": "/test/e2e/multiLIcenseTerms.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "title": "@smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/multiLIcenseTerms.test.ts", + "file": "/test/e2e/multiLIcenseTerms.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 126, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x9cc60eea1d11015b6cfddb46be036037033cb116df09a977de301e09c48caadc\\\"\\nMinted NFT tokenId: 7366\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a5ddea9f-d604-4631-8300-1f970d162907", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 78, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x1d63a55a25ab5704a001fbb61b9ee389d0b21d394665baea3563f101c81bd6f8\\\",\\\"ipId\\\":\\\"0x9c691Ff76A029EF8CB8528EB417cdfB5Ccadf52f\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8ebd90b7-6936-4a9e-af81-29165f010af1", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1 (commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet A attach comUseLicenseTermsId1 (commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 1157, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xabfa334979ee491106d6ddd0b80cf2b0463a778bde3f941009418b1af00a43be\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "07237b6c-3df8-41b8-b953-61c1dffd8097", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId2 (commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet A attach comUseLicenseTermsId2 (commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 2090, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x0ca68ce24e82a3067a222f02caa77682422976461e7222630ab8895c3631ab5d\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e4390971-e525-4a7d-804e-850e4e939950", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 6200, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x8f4444f50f1d9f07b527978c35a4f657e1c7fe43edb183902fdbccf7175ccebe\\\"\\nMinted NFT tokenId: 7367\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "62a12e45-e8e2-42ab-90a3-6c4465b2f180", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 68, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2c8193e8254a60617321531f6b874d8d6deff0d0d63698719d127ec3b965b18d\\\",\\\"ipId\\\":\\\"0x8d6d5479D52242348fad23F8CC229540321f21DA\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a544512c-ab3d-4f83-aa88-4374c282b46a", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can use comUseLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet B can use comUseLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 9642, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x0f6313f21884e5ee18461237573c76a3f7b866519fd67fb9180df91a48d5c36e\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "dc80f4b5-3455-4444-870a-999a5e9941a5", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1119, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xf05bef29821d3553f0959a0c6197846cfa2f399ba258c1a4caca71791e9103bf\\\"\\nMinted NFT tokenId: 7368\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "811247f9-b415-42f3-a5cb-cecfd2090191", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", + "timedOut": false, + "duration": 62, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xeabd05b6367ce5e800469dd25984d57a7dfbc888139193d43a29f395fcec8cf6\\\",\\\"ipId\\\":\\\"0x8350BD27492F5174F5AeD5b17c9bEdc96e74F385\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "18104187-d0a6-4f33-a3c6-73df96ced277", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT use comRemixLicenseTermsId1 to register ipIdC as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet B can NOT use comRemixLicenseTermsId1 to register ipIdC as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 21, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "09b074f4-c635-4ac9-81e2-a9d250ea35bc", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can use comUseLicenseTermsId1 and comUseLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs @smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs Wallet B can use comUseLicenseTermsId1 and comUseLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 11681, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x7407431bb9540dd03a1ae2cf26ecd32960666d2f8820e927eefa477a2cb59020\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d128a41d-fbd2-4e8a-b758-8aff2719c96c", + "parentUUID": "6b779e4c-0b10-4e7d-b567-0657e6316e10", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "a5ddea9f-d604-4631-8300-1f970d162907", + "8ebd90b7-6936-4a9e-af81-29165f010af1", + "07237b6c-3df8-41b8-b953-61c1dffd8097", + "e4390971-e525-4a7d-804e-850e4e939950", + "62a12e45-e8e2-42ab-90a3-6c4465b2f180", + "a544512c-ab3d-4f83-aa88-4374c282b46a", + "dc80f4b5-3455-4444-870a-999a5e9941a5", + "811247f9-b415-42f3-a5cb-cecfd2090191", + "18104187-d0a6-4f33-a3c6-73df96ced277", + "09b074f4-c635-4ac9-81e2-a9d250ea35bc", + "d128a41d-fbd2-4e8a-b758-8aff2719c96c" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 32244, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "title": "[smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/multiLIcenseTerms.test.ts", + "file": "/test/e2e/multiLIcenseTerms.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 112, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x30b12dd195ad66a55d9dd72e0b1dea8fe313161dc3e7ec92ae38062e3bb087b7\\\"\\nMinted NFT tokenId: 7369\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6556672c-4a93-4e4c-b46e-99acfc37adb0", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 98, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x9a9c871a7eb323fe7ea26fb631a3cc12f1a0cac3696b2e70f3bb7b601933598e\\\",\\\"ipId\\\":\\\"0xBb7d516EDC6D6D8875e64D834d181aB70B33672e\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "bbb026bd-9328-44a7-9899-589bcb2a18f6", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 140, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x15101d312a1046fa0aba10db8e4e3d2cbb4fb86b46f1913321b5d61497627145\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5d9cdc98-6f17-4453-a921-20674a25ea0f", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId2(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet A attach comRemixLicenseTermsId2(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 57, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf6d28647d90e2ecf9fd8119b4343500e3d3f453ecb6993a9e43097d47b4ddc67\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0d8c0a61-583e-4945-aeaf-15f68c7ef2e0", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1135, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0xd6023dad028da1c9e789a2b12b8184888f658dcba920250ec313d2d115b75c96\\\"\\nMinted NFT tokenId: 7370\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "86b8a4bd-9f44-41ce-bd3a-913ef2de6ec8", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 65, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xadedf21b74362a6ee639ec38f08224e833a5440ff3bed4a52c87cfad87a9a929\\\",\\\"ipId\\\":\\\"0x299Ac61e473A247dAfd2625590fEcF3E3bD37CB1\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "11166cf2-858f-4ea9-9e2a-b22a7b21c7a9", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can use comRemixLicenseTermsId2 to register ipIdB as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet B can use comRemixLicenseTermsId2 to register ipIdB as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 7633, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x93d8b98e14b587ad80eabece8209743423e999f5ccc6d46725ca55170dd970b7\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "cdf8c5cf-e5cc-4012-bcda-9a26edc5ad63", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 2138, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x16a5562d30ebbbfb2815f7d3da4faad785fd4a4d6317e9edaa39edca4a6e1dee\\\"\\nMinted NFT tokenId: 7371\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "7a95dd1a-206f-4cb5-a208-0448f56a0b67", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", + "timedOut": false, + "duration": 69, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x8674df218169c1ff76a4356639d5132b9cace85889ed43e3b9cabee6633b8e1a\\\",\\\"ipId\\\":\\\"0x5d588b9db8AEDad7421b028952DfD4E544aFdf83\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "55e24d0e-e0d1-4fd7-8790-8fbaaf6f8fd6", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT use nonComLicenseTermsId to register ipIdC as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet B can NOT use nonComLicenseTermsId to register ipIdC as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 18, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ca804e19-5ece-4dc2-be84-a44f4c47e030", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can use comRemixLicenseTermsId1 and comRemixLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs [smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs Wallet B can use comRemixLicenseTermsId1 and comRemixLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 11514, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xab081f4283c32ac0947eb406b732f87ac1838cf98b08c5c0b37857eea3e4dbaa\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2e8eae2f-8c63-43b7-9f2b-a57f7e1fd472", + "parentUUID": "02fe0dd3-6c4a-467f-b225-1fffe725deda", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "6556672c-4a93-4e4c-b46e-99acfc37adb0", + "bbb026bd-9328-44a7-9899-589bcb2a18f6", + "5d9cdc98-6f17-4453-a921-20674a25ea0f", + "0d8c0a61-583e-4945-aeaf-15f68c7ef2e0", + "86b8a4bd-9f44-41ce-bd3a-913ef2de6ec8", + "11166cf2-858f-4ea9-9e2a-b22a7b21c7a9", + "cdf8c5cf-e5cc-4012-bcda-9a26edc5ad63", + "7a95dd1a-206f-4cb5-a208-0448f56a0b67", + "55e24d0e-e0d1-4fd7-8790-8fbaaf6f8fd6", + "ca804e19-5ece-4dc2-be84-a44f4c47e030", + "2e8eae2f-8c63-43b7-9f2b-a57f7e1fd472" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 22979, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "title": "Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/multiLIcenseTerms.test.ts", + "file": "/test/e2e/multiLIcenseTerms.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Mint a NFT to Wallet A and get a tokenId (tokenIdA)", + "timedOut": false, + "duration": 1135, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x37921e91b6fccd8b5617263af9eacd6eabc33aa2d1793c6d8a4dbee1811c6bae\\\"\\nMinted NFT tokenId: 7372\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "bd50af89-7244-4477-a92e-20834ba848d9", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", + "timedOut": false, + "duration": 74, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x81d544fdbecf6ade2eba73bdd5739a93a599fa8c949f061a9df3a59c607c2361\\\",\\\"ipId\\\":\\\"0xBBDfA956e7Ad3126DCC10425efe638b31eeFA61c\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0ac3dc7a-13d6-4b40-9f2f-4cc235e4cb58", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", + "timedOut": false, + "duration": 133, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xea2f9a0735bbb96c28bd0def08736af7c40d159d7076d264e02830d3391dc4d6\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "65724793-5680-404e-bdc6-e3716da6216d", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", + "timedOut": false, + "duration": 63, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xdc8e5efdf264d766020c0c8b752ea977069112a3c512d9844e27f5acc7388ae4\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a5ecb610-592e-44a5-94e2-2765195a3fba", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Mint a NFT to Wallet B and get a tokenId (tokenIdB)", + "timedOut": false, + "duration": 1128, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"Minted NFT successful with hash: \\\"0x71839f7a4eaa82287ddb1f4927f7191d1e87157422c70e35b98d68f31bcbdbc1\\\"\\nMinted NFT tokenId: 7373\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "88f07719-12c8-45bb-8f4e-9b440be1fd5a", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", + "timedOut": false, + "duration": 72, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x574079848d4429c29c3434f1b4c16d3fcab6a115af850c02373f52ff268d8e88\\\",\\\"ipId\\\":\\\"0x5e7141401B4105e890ee55947c4804edC4a7A615\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "04b1396f-b69c-40a4-9bbb-1e03d1e5a23d", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 21, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "61e1445f-b639-4edb-a09f-89ce3d1669b2", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT use comUseLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet B can NOT use comUseLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 8, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "1d7bc5e9-67c6-4d68-8a82-399c7949852b", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT use comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet B can NOT use comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 7, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c8ecd604-4f1c-480f-be1a-91b6d9bcb61f", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", + "fullTitle": "SDK E2E Test - Register Derivative IP Asset with multiple PILs Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", + "timedOut": false, + "duration": 8, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "05a892b0-9641-40e9-894a-0e910673742e", + "parentUUID": "46d4ca89-1f3b-43b3-95e7-865de3ab63e3", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "bd50af89-7244-4477-a92e-20834ba848d9", + "0ac3dc7a-13d6-4b40-9f2f-4cc235e4cb58", + "65724793-5680-404e-bdc6-e3716da6216d", + "a5ecb610-592e-44a5-94e2-2765195a3fba", + "88f07719-12c8-45bb-8f4e-9b440be1fd5a", + "04b1396f-b69c-40a4-9bbb-1e03d1e5a23d", + "61e1445f-b639-4edb-a09f-89ce3d1669b2", + "1d7bc5e9-67c6-4d68-8a82-399c7949852b", + "c8ecd604-4f1c-480f-be1a-91b6d9bcb61f", + "05a892b0-9641-40e9-894a-0e910673742e" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 2649, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "9b524fbf-ab3e-481a-a74d-4429b21fbca1", + "title": "SDK E2E Test - Royalty", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comRemixPIL.test.ts", + "file": "/test/e2e/royalty.comRemixPIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Get total RT supply in \"SDK E2E Test - Royalty\"", + "fullTitle": "SDK E2E Test - Royalty \"before all\" hook: Get total RT supply in \"SDK E2E Test - Royalty\"", + "timedOut": false, + "duration": 2, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "TOTAL_RT_SUPPLY = await (0, utils_1.getTotalRTSupply)();\nconsole.log(\"TOTAL_RT_SUPPLY: \" + TOTAL_RT_SUPPLY);", + "err": {}, + "uuid": "eabe72a8-b689-42c1-b2ca-35f6f1df0f0d", + "parentUUID": "9b524fbf-ab3e-481a-a74d-4429b21fbca1", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "title": "Commercial Remix PIL - Claim Minting Fee by IPA account", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comRemixPIL.test.ts", + "file": "/test/e2e/royalty.comRemixPIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee by IPA account\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account \"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee by IPA account\"", + "timedOut": false, + "duration": 20490, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// Register commercial use PIL\nconst licenseTermsId = Number((await (0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee, commercialRevShare, config_1.mintingFeeTokenAddress, true)).licenseTermsId);\n// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, licenseTermsId);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [licenseTermsId]);", + "err": {}, + "uuid": "6b9283b4-0d91-4399-bc11-a9185bc84761", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "ipIdA collect royalty tokens from ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account ipIdA collect royalty tokens from ipIdB", + "timedOut": false, + "duration": 19, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe671642ef2a4d90f616462f68f39765f251f72605afdb987a1f6a9d1ec54f149\\\",\\\"royaltyTokensCollected\\\":\\\"500000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fb6d58bd-dbe8-4cea-9711-e475af7726d3", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account Capture snapshotId for ipIdB", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe2290aaa56d2be7592094518896c42800e39fe0bb16a2b8541e007b1f48f4faf\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f810dd83-5acd-48da-b220-1400b2a53d72", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account ipIdA check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "bd8c14d4-65ba-4ff4-9157-f352cf747492", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA claim revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account ipIdA claim revenue from vaultIpIdB", + "timedOut": false, + "duration": 58, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x791a155aabb81dfeace9658b1d1c136f408703e724a0a85cd82f615bcb62651d\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fc303461-241d-4411-915c-d6a4591ed5cb", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account ipIdB check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "092fe47e-fd95-4ceb-9c59-ccca1256c6e2", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB claim revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account ipIdB claim revenue from vaultIpIdB", + "timedOut": false, + "duration": 41, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe4e0d1c74296c60cc448d04bed2e6e55840c0a2bf41bfa7bb2a78cf3e209e541\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "40805942-7dae-4769-8f80-058e30129921", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account Capture snapshotId for ipIdA", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x94646487922e50d93d8aa1904f836da7cf271c75ef8dad052978ad0943786340\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6115fc2c-5168-4b6d-b9b7-fdc341b57902", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account ipIdA check claimable revenue from vaultIpIdA", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"100\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "1df25eab-269f-4827-bb65-df6704d1f8ad", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "idIdA claim revenue from vaultIpIdA (minting fee)", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account idIdA claim revenue from vaultIpIdA (minting fee)", + "timedOut": false, + "duration": 23, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2477758e9a82ba99623dd7955aa72c76bbc7c9819a2b59057e5e3de7566c8cc3\\\",\\\"claimableToken\\\":\\\"100n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "63f48643-2741-4d71-8e16-8da143cfffa5", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue again", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee by IPA account Check claimable revenue again", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "92cb4067-91be-44b3-8c8a-6ec1139b1a9a", + "parentUUID": "7ce9d18f-426b-47b1-a832-b79cfc8bbc9f", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "fb6d58bd-dbe8-4cea-9711-e475af7726d3", + "f810dd83-5acd-48da-b220-1400b2a53d72", + "bd8c14d4-65ba-4ff4-9157-f352cf747492", + "fc303461-241d-4411-915c-d6a4591ed5cb", + "092fe47e-fd95-4ceb-9c59-ccca1256c6e2", + "40805942-7dae-4769-8f80-058e30129921", + "6115fc2c-5168-4b6d-b9b7-fdc341b57902", + "1df25eab-269f-4827-bb65-df6704d1f8ad", + "63f48643-2741-4d71-8e16-8da143cfffa5", + "92cb4067-91be-44b3-8c8a-6ec1139b1a9a" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 184, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "title": "Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comRemixPIL.test.ts", + "file": "/test/e2e/royalty.comRemixPIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account \"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account\"", + "timedOut": false, + "duration": 31904, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// create license terms\nconst licenseTermsId = Number((await (0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee, commercialRevShare, config_1.mintingFeeTokenAddress, true)).licenseTermsId);\n// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, licenseTermsId);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [licenseTermsId]);\n// ipIdC is ipIdB's derivative IP\nipIdC = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdB], [licenseTermsId]);\n// ipIdD is ipIdC's derivative IP\nipIdD = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdC], [licenseTermsId]);", + "err": {}, + "uuid": "cc9a1b68-ed88-4562-8e09-b96f88009597", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "ipIdA collect royalty tokens from ipIdB's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account ipIdA collect royalty tokens from ipIdB's vault account", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xaa599ac3fb16ffb004da3f66ab01d1777f0b9dbf8c07d3a254aade9ad5c22399\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "677da4a1-06bd-4133-8fc4-24a126dafb1e", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account ipIdA collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb26b83cb4ef2c77d2f974fbe38c58988095e55dd16749cf5dd9d7629742503fb\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "568dfc70-f394-43bc-bc0b-4de0e14cb909", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account ipIdA collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 20, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x5d6b2fbd840b1c492df842b3672a5a3686704a77c3ece4bd8fafd4c676108b8d\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "090168d0-1dab-4337-8394-1f963305a578", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account ipIdB collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb3c558a2be8b5ae6403ea23e2638b8efd14733dcc121cb9a0c38914bcf93b0e2\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "dc193722-b83a-4b9d-941f-0bfdea39cf94", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account ipIdB collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x0ab52f44849b878ff84c0382e15b3e2def3f7ae0470cd3c484101fe91b902109\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "78d3125b-3fe1-42e6-bc74-5471c5656878", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdC collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account ipIdC collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x0621720ae792da1fb9a94a60b5d56b7e373567352214b1db74adf27f7767bb23\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "1fd52687-b4f2-403a-9590-36a8d460e3bb", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdD pay royalty on behalf to ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account ipIdD pay royalty on behalf to ipIdC", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2d3b76d6582776b33878980fca7901ffb22e2fdfc7492c1efe96a1182c31c041\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f1594b08-86d4-48d7-9b68-644f3072dece", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdD", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Capture snapshotId for ipIdD", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2948a38ba40ede661531e94688df54952236dff8c4957eb77f3d6ee19cc864a7\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "28b30d14-4cce-4b04-a856-d5ea910ae6a9", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Capture snapshotId for ipIdC", + "timedOut": false, + "duration": 35, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x7dac8b4bb0fef0ffb32c38a843ea6f9f6a02c0919286ecd582e1b34fa6c6e16f\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "dc6bde4d-1c6d-4b62-a33b-558994fb5879", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Capture snapshotId for ipIdB", + "timedOut": false, + "duration": 22, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb4cbb3b78e11e4401b60abf4dcc1140455ea32f3faae101b7b164abadb4b6c99\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f5f9b2c4-8fe0-4cdd-bebd-9c8aaac5df34", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Capture snapshotId for ipIdA", + "timedOut": false, + "duration": 26, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x4d56b5169ec8fd66b8b055f1b6d96002a606348a45062d581836010389b180cb\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fc520c62-a4b3-4098-8dec-c369cda261fa", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue A from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue A from D", + "timedOut": false, + "duration": 5, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "aea03781-cc1f-4a58-b296-19c308025caa", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue B from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue B from D", + "timedOut": false, + "duration": 9, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4bae8dc5-e465-4621-8d44-34fb80fe2cb4", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue C from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue C from D", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a76b5cac-1bfa-4033-94ca-905cb7f055be", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue D from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue D from D", + "timedOut": false, + "duration": 10, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "419b957f-562b-4d82-91f2-0d4c42d82d31", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue A from C", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"70\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f1edf032-0ced-444e-8f34-9b7f012fdf83", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue B from C", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"70\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "37f4c721-8116-4709-ba09-5030c82551b0", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue C from C", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"560\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c1a4b001-403e-45cc-b909-d3665c85e15a", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue A from B", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue A from B", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"60\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "9631f03c-9906-432f-a9c4-4935a308a9f9", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue B from B", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue B from B", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"540\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "534ab951-fe6f-455c-99d5-814add942b3d", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue A from A", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Check claimable revenue A from A", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"600\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fc46146d-9bf8-4d4f-973e-b5f208b0fc3a", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue A from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue A from D", + "timedOut": false, + "duration": 59, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x49792dd523ee624fb32005f5934dfb5e2e879bedd9fdc105f81fde2109844046\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5c5c41df-1d76-4ce4-bddd-06d137b9aabd", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue B from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue B from D", + "timedOut": false, + "duration": 45, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2b3e78bd223fb510f68f286561b0ad7efa4da19afd8a3a8dba338066a9cf5bee\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "921150bc-fe9d-4dc7-a452-1e8b88da65c3", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue C from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue C from D", + "timedOut": false, + "duration": 39, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x141432fc5e927ccdd9cb3a1cb18db145c2f45444e1f10edafaa9b835c250cec8\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a81d7665-6c18-427d-9240-53a65a948724", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue D from D", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue D from D", + "timedOut": false, + "duration": 43, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x42a11ce7c30392ab4c9064d2c940da3be33add6041b8db0799812a230df622f5\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "35b972ce-d03c-49d3-a5e5-40668a59aa9d", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue A from C", + "timedOut": false, + "duration": 21, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x694f8dbdcb1ecb26dc4d555003322784b1fb3b6112b8ff814874add756f816c9\\\",\\\"claimableToken\\\":\\\"70n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "819027b2-fabc-486b-a7c8-3f31dd0e0073", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue B from C", + "timedOut": false, + "duration": 28, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xfb3918c67d10e2351cc54fb08357e0f14736c6ec63de23d1435ea0dca79b876a\\\",\\\"claimableToken\\\":\\\"70n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e31897ec-7a52-4b43-b942-153652409856", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue C from C", + "timedOut": false, + "duration": 29, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2dfde3b9f4f2aafb8223fe551ea18d9dfc10460fb7b5bccfffd7a084f76dee94\\\",\\\"claimableToken\\\":\\\"560n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "979e3859-d696-47bf-b9a6-b0332e96d0db", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue A from B", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue A from B", + "timedOut": false, + "duration": 25, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x5ea2fe618d6c7f1dc74ae6898d71d31adfed1188b7ed0531a09a971654f0dda2\\\",\\\"claimableToken\\\":\\\"60n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a78e9e3e-7ffa-4f4d-9eb1-19fc1be01917", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue B from B", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue B from B", + "timedOut": false, + "duration": 28, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x3dfdd37fd091c163538deb1f5699a368afd6de2bcc2775e5935c7d2f3884470f\\\",\\\"claimableToken\\\":\\\"540n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f0e8d361-dd55-4f5c-be5c-56c7514f3753", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue A from A", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account Claim revenue A from A", + "timedOut": false, + "duration": 22, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x72d43cdd2d3a12e7daf191fa1e595361e0fbcb0afe4c1507819265019ece86c8\\\",\\\"claimableToken\\\":\\\"600n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6100fb06-9dac-4ebe-a0bf-8231cff2a228", + "parentUUID": "c62ada4a-f483-46e9-b9b4-2be998b357ef", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "677da4a1-06bd-4133-8fc4-24a126dafb1e", + "568dfc70-f394-43bc-bc0b-4de0e14cb909", + "090168d0-1dab-4337-8394-1f963305a578", + "dc193722-b83a-4b9d-941f-0bfdea39cf94", + "78d3125b-3fe1-42e6-bc74-5471c5656878", + "1fd52687-b4f2-403a-9590-36a8d460e3bb", + "f1594b08-86d4-48d7-9b68-644f3072dece", + "28b30d14-4cce-4b04-a856-d5ea910ae6a9", + "dc6bde4d-1c6d-4b62-a33b-558994fb5879", + "f5f9b2c4-8fe0-4cdd-bebd-9c8aaac5df34", + "fc520c62-a4b3-4098-8dec-c369cda261fa", + "aea03781-cc1f-4a58-b296-19c308025caa", + "4bae8dc5-e465-4621-8d44-34fb80fe2cb4", + "a76b5cac-1bfa-4033-94ca-905cb7f055be", + "419b957f-562b-4d82-91f2-0d4c42d82d31", + "f1edf032-0ced-444e-8f34-9b7f012fdf83", + "37f4c721-8116-4709-ba09-5030c82551b0", + "c1a4b001-403e-45cc-b909-d3665c85e15a", + "9631f03c-9906-432f-a9c4-4935a308a9f9", + "534ab951-fe6f-455c-99d5-814add942b3d", + "fc46146d-9bf8-4d4f-973e-b5f208b0fc3a", + "5c5c41df-1d76-4ce4-bddd-06d137b9aabd", + "921150bc-fe9d-4dc7-a452-1e8b88da65c3", + "a81d7665-6c18-427d-9240-53a65a948724", + "35b972ce-d03c-49d3-a5e5-40668a59aa9d", + "819027b2-fabc-486b-a7c8-3f31dd0e0073", + "e31897ec-7a52-4b43-b942-153652409856", + "979e3859-d696-47bf-b9a6-b0332e96d0db", + "a78e9e3e-7ffa-4f4d-9eb1-19fc1be01917", + "f0e8d361-dd55-4f5c-be5c-56c7514f3753", + "6100fb06-9dac-4ebe-a0bf-8231cff2a228" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 604, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "title": "Commercial Remix PIL - Claim Minting Fee and Revenue by EOA", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comRemixPIL.test.ts", + "file": "/test/e2e/royalty.comRemixPIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by EOA\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA \"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by EOA\"", + "timedOut": false, + "duration": 38014, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// create license terms\nconst licenseTermsId = Number((await (0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee, commercialRevShare, config_1.mintingFeeTokenAddress, true)).licenseTermsId);\n// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, licenseTermsId);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [licenseTermsId]);\n// ipIdC is ipIdB's derivative IP\nipIdC = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdB], [licenseTermsId]);\n// ipIdD is ipIdC's derivative IP\nipIdD = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdC], [licenseTermsId]);", + "err": {}, + "uuid": "9aba0845-cbe9-4087-831e-f42119f43506", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "ipIdA collect royalty tokens from ipIdB's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA ipIdA collect royalty tokens from ipIdB's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x32b788a3adaba253f99f3338dafd476756f09adde45f935eccc280a9720c0b73\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "69d0195f-b9ef-4b67-8874-6e4f88aaf2ff", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA ipIdA collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x43789b660d544f41616c4e84e1a7e2f0147be9b0d4fb25caab266f455b8f8445\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5a69573e-b588-473c-98cb-7326e9bcf9c9", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA ipIdA collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x8687389af28cb0f09825642596ae1a6954fc13b54ea7058ce9766663814681c1\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "cb709a95-8cbd-420c-8469-a328152b17d8", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA ipIdB collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x4ffb7928311ee2d2936de0b4f11c5bbf9e4ee98cc095cd5a9bc3e0d5e73c5b1d\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c7565be8-12b6-440b-b261-162a9a161db7", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA ipIdB collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf2caae1898b5bc77d7d9b9ff912752e85ef4e7ed20ee4fc23959dfc862a8664c\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "64451c5a-0c0d-4323-b50b-cb746d413b17", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdC collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA ipIdC collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa06083403c2473160aaec23b73de546c58b3bc58e22ef9ef1e10740ce050b25c\\\",\\\"royaltyTokensCollected\\\":\\\"20000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8ad36885-4700-4ef7-823b-14091c9a67e8", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Transfer token to EOA - ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Transfer token to EOA - ipIdC", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0x15e67D7d3c7347E1916ff51FaC9DB3b9Ca20c378\\n0x15e67D7d3c7347E1916ff51FaC9DB3b9Ca20c378\\n{\\\"txHash\\\":\\\"0x510ae771202a9e09ddd14e4edc64db51b732c28ebd3aeb6ca0e9c690b557a3dc\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b587fe5c-fc36-485c-9972-10b5e81d31a5", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdD pay royalty on behalf to ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA ipIdD pay royalty on behalf to ipIdC", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xfbd0c963098c76fab63a5c665d7e89e00501ce5cd01c10511e8e3ac72fb57e6b\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "51770ec1-93e4-4f5c-99d2-9ed5831a74c5", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Capture snapshotId for ipIdC", + "timedOut": false, + "duration": 12, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x05a4a901260e09b5c18feeb905d321d337cc1d6cf86538a7748449eedcbf5708\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "56a879ee-9866-4ef5-b104-f4827831a9d6", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Check claimable revenue A from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"1400\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "db242065-7fa6-4743-90ad-c21d7ec6b1af", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Check claimable revenue B from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"1400\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "bf0ca255-2c7a-4632-8d2c-93976606eb72", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Check claimable revenue C from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "b8c55900-cb60-4cf7-bd1e-0f89ea89a1d0", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Claim revenue by EOA A from C", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x515db817a5f92380352101c311bda368e6bffe490312e00807193015e2b873f4\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0c2c710a-7c05-48cd-b161-1cb1d7d54c90", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Claim revenue by EOA B from C", + "timedOut": false, + "duration": 13, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb860af4041a1f264184d31f91afaa427c657a216e9fe8cd14455f171459de052\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fe4bf07a-1492-4d4a-9cb0-16ad59b2deae", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA Claim revenue by EOA C from C", + "timedOut": false, + "duration": 12, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x98e882f1086cc7428dd4ae1d8df39240182dbfbc3e277e412b8e979f732f7667\\\",\\\"claimableToken\\\":\\\"4200n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "945128e6-5e98-459d-a851-00bf8858196d", + "parentUUID": "5fe6c9f4-595a-4ec1-b2d7-558d755910be", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "69d0195f-b9ef-4b67-8874-6e4f88aaf2ff", + "5a69573e-b588-473c-98cb-7326e9bcf9c9", + "cb709a95-8cbd-420c-8469-a328152b17d8", + "c7565be8-12b6-440b-b261-162a9a161db7", + "64451c5a-0c0d-4323-b50b-cb746d413b17", + "8ad36885-4700-4ef7-823b-14091c9a67e8", + "b587fe5c-fc36-485c-9972-10b5e81d31a5", + "51770ec1-93e4-4f5c-99d2-9ed5831a74c5", + "56a879ee-9866-4ef5-b104-f4827831a9d6", + "db242065-7fa6-4743-90ad-c21d7ec6b1af", + "bf0ca255-2c7a-4632-8d2c-93976606eb72", + "b8c55900-cb60-4cf7-bd1e-0f89ea89a1d0", + "0c2c710a-7c05-48cd-b161-1cb1d7d54c90", + "fe4bf07a-1492-4d4a-9cb0-16ad59b2deae", + "945128e6-5e98-459d-a851-00bf8858196d" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 187, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "title": "Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comRemixPIL.test.ts", + "file": "/test/e2e/royalty.comRemixPIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 \"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1\"", + "timedOut": false, + "duration": 27672, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// create license terms\nconst licenseTermsId = Number((await (0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee, commercialRevShare, config_1.mintingFeeTokenAddress, true)).licenseTermsId);\n// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, licenseTermsId);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [licenseTermsId]);\n// ipIdC is ipIdB's derivative IP\nipIdC = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdB], [licenseTermsId]);\n// ipIdD is ipIdC's derivative IP\nipIdD = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdC], [licenseTermsId]);", + "err": {}, + "uuid": "73c30deb-19d9-4ef6-b464-14afca72a846", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "ipIdA collect royalty tokens from ipIdB's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 ipIdA collect royalty tokens from ipIdB's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x96d67cb5d77e0ec11b257d3dc3c98a9b5d383a0c8a6a144ceb281f4bd28c9534\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "cc8b2754-e17a-4c03-b9b1-f164a89e9b79", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 ipIdA collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x08ac18f58c2823f6316582e70cdc6e0fe9ac17681c9c040b5f886e1ba0d2d226\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5fcaf01c-218b-4ed0-bfd1-ca3be6f56ee7", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 ipIdA collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb67b772653a9f6add375ddc1874cc54c3e7d97c46b58f059166fc9638ec0a699\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "52d283e8-11e2-4987-89a8-7c1574ba0abe", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 ipIdB collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xc1d7f91ea92860e5b637cb5a87ff70936e93f60cd9d93c6556f53b6795689c74\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4a74fd38-c298-4cb5-845c-f01dbbe57823", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 ipIdB collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xfff6da5f6893bb180bbe6792640d6b34466bc6ae1d1f22d02a8c3430943f994f\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "af47d1af-cf49-41d6-ac69-7e06a91b4833", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdC collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 ipIdC collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x4ad8a73d08435f21ceb1bc11116ea1d2058dfb105886ea011001de1cdc71bc83\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "eda15aab-d7ca-4355-a224-eb384cec3d8b", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Transfer token to EOA - ipIdC to ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Transfer token to EOA - ipIdC to ipIdA", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"20000000\\n0x8e8D222EB47BB28959d5F5EFB5f7A81897A2de0F\\n0x8e8D222EB47BB28959d5F5EFB5f7A81897A2de0F\\n{\\\"txHash\\\":\\\"0xb132ebf7edad915f986aa5f08a9b86fc722785044a5aa183cbe1d108b83d3a3a\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d52cce27-f6b2-4645-aa1a-273e363f769a", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Transfer token to EOA - ipIdC to ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Transfer token to EOA - ipIdC to ipIdB", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"20000000\\n0x8e8D222EB47BB28959d5F5EFB5f7A81897A2de0F\\n0x8e8D222EB47BB28959d5F5EFB5f7A81897A2de0F\\n{\\\"txHash\\\":\\\"0x2fc6a4d963ec52d89fc460b5e4bcfae553848e6a3bc29be3819cc1ec2ce5dfd4\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f7291aec-5da3-42e8-ae4d-229f9801bf0f", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Transfer token to EOA - ipIdC to ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Transfer token to EOA - ipIdC to ipIdC", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"40000000\\n0x8e8D222EB47BB28959d5F5EFB5f7A81897A2de0F\\n0x8e8D222EB47BB28959d5F5EFB5f7A81897A2de0F\\n{\\\"txHash\\\":\\\"0x3fc82444533f622b21603dac9020f7286a06225f1c96d18ffb4b076b3a8e1717\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "66780291-9876-4a82-b351-75dd2545110d", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdD pay royalty on behalf to ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 ipIdD pay royalty on behalf to ipIdC", + "timedOut": false, + "duration": 13, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xaecc72fdc838006d4a695a4a81018eb162a0dbcb27c0bbe1973267219a606302\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c58916a1-062f-4d69-90a5-0a9c5448d903", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Capture snapshotId for ipIdC", + "timedOut": false, + "duration": 12, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x51d387bca3e697f65f9f96c6a0ddfb264ad3eb4d6d670f39ebe06cb22756a534\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "acb03d93-eff9-40bd-ba87-c4ec2e96041e", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Check claimable revenue A from C", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"260\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e7b75f1f-b4fa-43ae-94fe-2a473c8321c4", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Check claimable revenue B from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"260\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5a3a74a7-0081-415b-a9f7-1135f3c79524", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Check claimable revenue C from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"520\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "77dc0c93-f823-4e3c-ba45-1e61f3b02e7e", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Claim revenue by EOA A from C", + "timedOut": false, + "duration": 13, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x753c1a3069f0b80374ad3af31db25e69947c7f21534934a4625f624bc7543362\\\",\\\"claimableToken\\\":\\\"520n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "54dcbb08-7dc7-4a02-8555-0b3c8e72ec8a", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Claim revenue by EOA B from C", + "timedOut": false, + "duration": 12, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe6dd170741b55b5c4eeca91e4fd4b389d0f8b3935964028dcb19f67c054e3c74\\\",\\\"claimableToken\\\":\\\"520n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "22519a31-0716-4a7b-839f-f581acf6a297", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1 Claim revenue by EOA C from C", + "timedOut": false, + "duration": 12, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x17e6886c1ba5da7a7ddc01a2b9342c05f1290de351d0427a409c0e0ca442b6ac\\\",\\\"claimableToken\\\":\\\"520n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "253ab867-fc09-4775-99cb-4c8271a970a4", + "parentUUID": "40b84ef2-4ec4-4e24-bd2c-4d1ba2236840", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "cc8b2754-e17a-4c03-b9b1-f164a89e9b79", + "5fcaf01c-218b-4ed0-bfd1-ca3be6f56ee7", + "52d283e8-11e2-4987-89a8-7c1574ba0abe", + "4a74fd38-c298-4cb5-845c-f01dbbe57823", + "af47d1af-cf49-41d6-ac69-7e06a91b4833", + "eda15aab-d7ca-4355-a224-eb384cec3d8b", + "d52cce27-f6b2-4645-aa1a-273e363f769a", + "f7291aec-5da3-42e8-ae4d-229f9801bf0f", + "66780291-9876-4a82-b351-75dd2545110d", + "c58916a1-062f-4d69-90a5-0a9c5448d903", + "acb03d93-eff9-40bd-ba87-c4ec2e96041e", + "e7b75f1f-b4fa-43ae-94fe-2a473c8321c4", + "5a3a74a7-0081-415b-a9f7-1135f3c79524", + "77dc0c93-f823-4e3c-ba45-1e61f3b02e7e", + "54dcbb08-7dc7-4a02-8555-0b3c8e72ec8a", + "22519a31-0716-4a7b-839f-f581acf6a297", + "253ab867-fc09-4775-99cb-4c8271a970a4" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 210, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "title": "Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comRemixPIL.test.ts", + "file": "/test/e2e/royalty.comRemixPIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 \"before all\" hook: Register parent and derivative IP Assets in \"Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2\"", + "timedOut": false, + "duration": 21824, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// create license terms\nconst licenseTermsId = Number((await (0, sdkUtils_1.registerCommercialRemixPIL)(\"A\", mintingFee, commercialRevShare, config_1.mintingFeeTokenAddress, true)).licenseTermsId);\n// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, licenseTermsId);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [licenseTermsId]);\n// ipIdC is ipIdB's derivative IP\nipIdC = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdB], [licenseTermsId]);\n// ipIdD is ipIdC's derivative IP\nipIdD = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdC], [licenseTermsId]);", + "err": {}, + "uuid": "ad8f8e69-4986-4c45-af77-ef49bc1b277d", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Transfer token to EOA - ipIdC to ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Transfer token to EOA - ipIdC to ipIdA", + "timedOut": false, + "duration": 20, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"20000000\\n0x8912965a2Ec22dC392B514a705E7c82f347E17Ca\\n0x8912965a2Ec22dC392B514a705E7c82f347E17Ca\\n{\\\"txHash\\\":\\\"0x5fef0f34748d557533c2df0b0c5cd713b48d7663eac4951bf89e871a6b8b99f0\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "726b0325-46b9-4a85-a021-22f1b95e8962", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Transfer token to EOA - ipIdC to ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Transfer token to EOA - ipIdC to ipIdB", + "timedOut": false, + "duration": 20, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"20000000\\n0x8912965a2Ec22dC392B514a705E7c82f347E17Ca\\n0x8912965a2Ec22dC392B514a705E7c82f347E17Ca\\n{\\\"txHash\\\":\\\"0x90879c5ba675e6ec16534844cec3278a1feda5a27c222073e1822315f47f68dc\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c6286f6d-af0e-4703-8280-044acc5265e0", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Transfer token to EOA - ipIdC to ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Transfer token to EOA - ipIdC to ipIdC", + "timedOut": false, + "duration": 18, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"40000000\\n0x8912965a2Ec22dC392B514a705E7c82f347E17Ca\\n0x8912965a2Ec22dC392B514a705E7c82f347E17Ca\\n{\\\"txHash\\\":\\\"0x70b64c155f05fd12daa4606b5a024b47668c6b93da58398d0e913b2def127310\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8315cdd2-e315-4b17-9347-1a4f965d622e", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdD pay royalty on behalf to ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 ipIdD pay royalty on behalf to ipIdC", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x8f37f3a3cb07bc66522cd47a0002d0df8b274ba9bdfb91f6754097032964ed5a\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3a0d5074-c3be-4d61-8869-89da96966d2a", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdB's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 ipIdA collect royalty tokens from ipIdB's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x973f3dd01fe615a7eb87b7b5604dd32d524cdd5fed4b4ec011dcdee07e9609ef\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4bff3aea-713e-4f2d-8f2e-9ee101ee9ccc", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 ipIdA collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x345c8a1d2f58e2b4fc4b7579c4a28666e61e3d8e6cf4ced4aa1577eafa029fdc\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "15b49c05-343c-4d04-a9f5-c3566113e093", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 ipIdA collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 19, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x218bf710cea26a4852af7cdcee595755fce33abb703bc5cfc1efd657e34389fe\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "418acd3d-b90d-4313-9328-f6f8bea3a678", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdC's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 ipIdB collect royalty tokens from ipIdC's vault account", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xf03783520d82aabcc7162298b091719f855dd4d7f6dff1046d15f169962e808d\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fc2a02ac-ac85-4821-8a2e-1d2e6239885e", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 ipIdB collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 17, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xcd7e928a07285a56554b168dfd9bc1d7bfd34cedeb6acd0464b04297a823c9c0\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3ef601a8-66fc-483b-85ac-1d0edae80467", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdC collect royalty tokens from ipIdD's vault account", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 ipIdC collect royalty tokens from ipIdD's vault account", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x790a9397f2cc90c2e039d37ceceecdcdce85f86bfa13b12c1cf747a21c390b55\\\",\\\"royaltyTokensCollected\\\":\\\"10000000n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "4d5eb767-4262-4684-86db-5ad8be324855", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdC", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Capture snapshotId for ipIdC", + "timedOut": false, + "duration": 13, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xa2b82e5f48b8dca2cd4af5d86757364bf3bfd5f37fe856827e519369b2412486\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "221dea1c-257a-40fd-a772-b2dbf2022ef5", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Check claimable revenue A from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"260\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0f9cfad3-3564-4b93-ae57-b0088053ab85", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Check claimable revenue B from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"260\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "fcb83600-03c8-426f-9aeb-27e45cf7fd42", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Check claimable revenue C from C", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"520\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d66b5464-c5eb-4326-89a1-3bf99b1bac89", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA A from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Claim revenue by EOA A from C", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x13c92949f466c60bce9faec01e6be00342a19067864385735287a5d192dd6c89\\\",\\\"claimableToken\\\":\\\"520n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3f075eb5-febb-4ba6-939e-dc777a28f8f4", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA B from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Claim revenue by EOA B from C", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2aa7dc131d348eb581316105726c6ef1ab59ede9a2f607189960faa6d88583ac\\\",\\\"claimableToken\\\":\\\"520n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e40f95c0-226b-4e94-be78-70a49dbecefd", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + }, + { + "title": "Claim revenue by EOA C from C", + "fullTitle": "SDK E2E Test - Royalty Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2 Claim revenue by EOA C from C", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x31d8f0e927fae5855e682999dc5187a0a161f85887ca70b5a2491fa18c84fdf3\\\",\\\"claimableToken\\\":\\\"520n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "a6134118-d9ae-4192-9022-e888c2b520e9", + "parentUUID": "401541fc-5d5a-4eae-b87e-215d4d09dbef", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "726b0325-46b9-4a85-a021-22f1b95e8962", + "c6286f6d-af0e-4703-8280-044acc5265e0", + "8315cdd2-e315-4b17-9347-1a4f965d622e", + "3a0d5074-c3be-4d61-8869-89da96966d2a", + "4bff3aea-713e-4f2d-8f2e-9ee101ee9ccc", + "15b49c05-343c-4d04-a9f5-c3566113e093", + "418acd3d-b90d-4313-9328-f6f8bea3a678", + "fc2a02ac-ac85-4821-8a2e-1d2e6239885e", + "3ef601a8-66fc-483b-85ac-1d0edae80467", + "4d5eb767-4262-4684-86db-5ad8be324855", + "221dea1c-257a-40fd-a772-b2dbf2022ef5", + "0f9cfad3-3564-4b93-ae57-b0088053ab85", + "fcb83600-03c8-426f-9aeb-27e45cf7fd42", + "d66b5464-c5eb-4326-89a1-3bf99b1bac89", + "3f075eb5-febb-4ba6-939e-dc777a28f8f4", + "e40f95c0-226b-4e94-be78-70a49dbecefd", + "a6134118-d9ae-4192-9022-e888c2b520e9" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 239, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "e1645e8c-6f18-4f6d-816a-73c931a375ec", + "title": "SDK E2E Test - Royalty", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comUsePIL.test.ts", + "file": "/test/e2e/royalty.comUsePIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Get total RT supply in \"SDK E2E Test - Royalty\"", + "fullTitle": "SDK E2E Test - Royalty \"before all\" hook: Get total RT supply in \"SDK E2E Test - Royalty\"", + "timedOut": false, + "duration": 2, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "TOTAL_RT_SUPPLY = await (0, utils_1.getTotalRTSupply)();\nconsole.log(\"TOTAL_RT_SUPPLY: \" + TOTAL_RT_SUPPLY);", + "err": {}, + "uuid": "a1cac84e-653e-4f19-9030-1561ca66ae2b", + "parentUUID": "e1645e8c-6f18-4f6d-816a-73c931a375ec", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "title": "Commercial Use PIL - Claim Minting Fee by IPA account", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comUsePIL.test.ts", + "file": "/test/e2e/royalty.comUsePIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP assets in \"Commercial Use PIL - Claim Minting Fee by IPA account\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account \"before all\" hook: Register parent and derivative IP assets in \"Commercial Use PIL - Claim Minting Fee by IPA account\"", + "timedOut": false, + "duration": 11135, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, setup_1.comUseLicenseTermsId1);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [setup_1.comUseLicenseTermsId1]);", + "err": {}, + "uuid": "3bdc5d50-484f-4369-924e-2e102696c8d8", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "ipIdA collect royalty tokens from ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account ipIdA collect royalty tokens from ipIdB", + "timedOut": false, + "duration": 23, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x6a2d807141177378fd273f411422733dd5aad8ecdea002e56f4c6764c9676b5d\\\",\\\"royaltyTokensCollected\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2556d671-96c1-46ff-9cee-489f1501afb2", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account Capture snapshotId for ipIdB", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd4e3715f47b2ea6db6d6c6e20017463682fad39060c261d9be190c5c7fc1ec4c\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ac708648-3093-4052-af4b-dd0888c578a0", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account ipIdA check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f7ef47be-9e19-4937-b4c5-df106e249397", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA claim revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account ipIdA claim revenue from vaultIpIdB", + "timedOut": false, + "duration": 1069, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xc47525938658d7242b439f11ed5d3dec4e4060310a788676001b71a35128daa6\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "93351f68-f73c-4138-b03b-90ae5ef51780", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account ipIdB check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 5, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "aa0039be-b765-40f1-abde-f6bf389a45dc", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB claim revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account ipIdB claim revenue from vaultIpIdB", + "timedOut": false, + "duration": 39, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x1119f84a9d9f9cac7e562bad65f10c96860cc9c5f4027169299310d676579196\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ddaaf112-2d66-488a-a250-37fb2af122f1", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account Capture snapshotId for ipIdA", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x3eddac57d8ccc1b02b11128f2772881789fcfe7ea97d0c8d77a4d298e1c1cd84\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "0fb86c4c-ba5a-4ca1-a87c-e3ab4afe2fec", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account ipIdA check claimable revenue from vaultIpIdA", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"100\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "bde499e7-cf67-46a5-be38-a268c2c6bece", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "idIdA claim revenue from vaultIpIdA (minting fee)", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account idIdA claim revenue from vaultIpIdA (minting fee)", + "timedOut": false, + "duration": 22, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xc1d36f84457203331814d56a13311fe680f6033fee9ff1f7f5490454a9cb1bde\\\",\\\"claimableToken\\\":\\\"100n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "5e446488-aab9-4db9-97d3-061afafd7817", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + }, + { + "title": "Check claimable revenue again", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee by IPA account Check claimable revenue again", + "timedOut": false, + "duration": 4, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "be41613e-cf07-4e45-93e1-af668fc1c2d2", + "parentUUID": "ec58c3ea-a0b5-4498-a4d0-90e149b7e43e", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "2556d671-96c1-46ff-9cee-489f1501afb2", + "ac708648-3093-4052-af4b-dd0888c578a0", + "f7ef47be-9e19-4937-b4c5-df106e249397", + "93351f68-f73c-4138-b03b-90ae5ef51780", + "aa0039be-b765-40f1-abde-f6bf389a45dc", + "ddaaf112-2d66-488a-a250-37fb2af122f1", + "0fb86c4c-ba5a-4ca1-a87c-e3ab4afe2fec", + "bde499e7-cf67-46a5-be38-a268c2c6bece", + "5e446488-aab9-4db9-97d3-061afafd7817", + "be41613e-cf07-4e45-93e1-af668fc1c2d2" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 1199, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "title": "Commercial Use PIL - Claim Minting Fee and Revenue by IPA account", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comUsePIL.test.ts", + "file": "/test/e2e/royalty.comUsePIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP assets in \"Commercial Use PIL - Claim Minting Fee and Revenue by IPA account\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account \"before all\" hook: Register parent and derivative IP assets in \"Commercial Use PIL - Claim Minting Fee and Revenue by IPA account\"", + "timedOut": false, + "duration": 14321, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// register commercial use PIL\nconst licenseTermsId = Number((await (0, sdkUtils_1.registerCommercialUsePIL)(\"A\", mintingFee, config_1.mintingFeeTokenAddress, true)).licenseTermsId);\n// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, licenseTermsId);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [licenseTermsId]);\n// ipIdC is ipIdB's derivative IP\nipIdC = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdB], [licenseTermsId]);", + "err": {}, + "uuid": "ba32efda-bd49-4a2a-b436-79789cfc08c5", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "ipIdC pay royalty on behalf to ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account ipIdC pay royalty on behalf to ipIdB", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb0d24594397e6fcdd3514082eee7ad1761f2a754a043914b35a41f51c13a5b14\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "879742cd-ccb8-4338-86a6-5f9ca9090815", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account Capture snapshotId for ipIdB", + "timedOut": false, + "duration": 13, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xd8af64005e28b5cee09c3998fac3740c866d1c91a35ec43ff6e47eb819f92af9\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "79b5a38f-b914-45f1-a106-355432c59efa", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account ipIdA check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c96c9290-63e3-492b-a757-dc8cd9b58ab3", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA claim revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account ipIdA claim revenue from vaultIpIdB", + "timedOut": false, + "duration": 1052, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x8c7778e07514c31ca05a0f6b9d63f249fb4a5321c8ca75ef6a0afe026d2d1dab\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f7453b0c-1550-4acc-9072-2715cdc549b2", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account ipIdB check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"1000180\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2c388683-6bca-4b8a-9857-a2ca9e4e2675", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB claim revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account ipIdB claim revenue from vaultIpIdB", + "timedOut": false, + "duration": 41, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xafc3895f135211f46b9b37b8fda8f074d4394305ad2e95618e367ae4719658eb\\\",\\\"claimableToken\\\":\\\"1000180n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "36959a77-32a4-43b8-9513-a71c1f0e0807", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account Capture snapshotId for ipIdA", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x9324395b00b751e45d9267f19ded682e7b09395ef7ad5b994c474e77d52ebee9\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "23f18039-f7b9-4840-9830-d73481e44cb2", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account ipIdA check claimable revenue from vaultIpIdA", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"180\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "3941c92e-2919-463b-9557-c1562d784509", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA claim revenue from vaultIpIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by IPA account ipIdA claim revenue from vaultIpIdA", + "timedOut": false, + "duration": 22, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xaa76723caee3586d2af0c29fd265818c454be8284ae2af876d476e72ba8c5548\\\",\\\"claimableToken\\\":\\\"180n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f4e6287b-2584-41b1-bb6a-a92a0c40fd24", + "parentUUID": "a1856390-06fc-434b-8cb8-6699e48f76e3", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "879742cd-ccb8-4338-86a6-5f9ca9090815", + "79b5a38f-b914-45f1-a106-355432c59efa", + "c96c9290-63e3-492b-a757-dc8cd9b58ab3", + "f7453b0c-1550-4acc-9072-2715cdc549b2", + "2c388683-6bca-4b8a-9857-a2ca9e4e2675", + "36959a77-32a4-43b8-9513-a71c1f0e0807", + "23f18039-f7b9-4840-9830-d73481e44cb2", + "3941c92e-2919-463b-9557-c1562d784509", + "f4e6287b-2584-41b1-bb6a-a92a0c40fd24" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 1166, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "title": "Commercial Use PIL - Claim Minting Fee and Revenue by EOA", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/royalty.comUsePIL.test.ts", + "file": "/test/e2e/royalty.comUsePIL.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Register parent and derivative IP assets in \"Commercial Use PIL - Claim Minting Fee and Revenue by EOA\"", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA \"before all\" hook: Register parent and derivative IP assets in \"Commercial Use PIL - Claim Minting Fee and Revenue by EOA\"", + "timedOut": false, + "duration": 22184, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "// register commercial use PIL\nconst licenseTermsId = Number((await (0, sdkUtils_1.registerCommercialUsePIL)(\"A\", mintingFee, config_1.mintingFeeTokenAddress, true)).licenseTermsId);\n// root IP: ipIdA\nipIdA = await (0, testUtils_1.mintNFTCreateRootIPandAttachPIL)(\"A\", config_1.privateKeyA, licenseTermsId);\n// ipIdB is ipIdA's derivative IP\nipIdB = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"B\", config_1.privateKeyB, [ipIdA], [licenseTermsId]);\n// ipIdC is ipIdB's derivative IP\nipIdC = await (0, testUtils_1.mintNFTAndRegisterDerivative)(\"C\", config_1.privateKeyC, [ipIdB], [licenseTermsId]);", + "err": {}, + "uuid": "5ffc0efc-ce2d-4558-8920-ea3ef4e136e0", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [ + { + "title": "Transfer token to EOA - ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA Transfer token to EOA - ipIdB", + "timedOut": false, + "duration": 18, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0x6549CDf13fd433de6955CbEf70C8F7B2Cd9aAdB7\\n0x6549CDf13fd433de6955CbEf70C8F7B2Cd9aAdB7\\n{\\\"txHash\\\":\\\"0xcddb499b4b8735a09209b25a330b72154b047f82844d5dc92435104710445523\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "e2a83671-0b3e-40d0-b643-297d6a4e41ae", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "Transfer token to EOA - ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA Transfer token to EOA - ipIdA", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0x271F8b8899C8b52B34A784d8Ac4299b5adA31ee0\\n0x271F8b8899C8b52B34A784d8Ac4299b5adA31ee0\\n{\\\"txHash\\\":\\\"0xcbef343ee201a137a7ce53d1c1451c096fa6e0cbc87cc8cd6f915eccd218855d\\\"}\\n[object Object]\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "d7289da3-a28f-4000-a9bc-30f94b5fb45a", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdC pay royalty on behalf to ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdC pay royalty on behalf to ipIdB", + "timedOut": false, + "duration": 18, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb3f7045b0f73d7741519941b634387fda84f34e87ad1bff57caef9e20c184a47\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c56b0299-deec-4737-9b8c-c9dc9a224690", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA Capture snapshotId for ipIdB", + "timedOut": false, + "duration": 13, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x19f2e22409a75676fd5ec0cc34520a1c9cb9c470d8119f2ae6e9c12c12e95823\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6d603006-39bb-4b58-b68f-9f8fc94bb34c", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdA check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f56e1ec1-4f35-4215-8525-4eeaa32f670a", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB check claimable revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdB check claimable revenue from vaultIpIdB", + "timedOut": false, + "duration": 2, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "afe83d32-a9ab-409b-b28c-a135ae48a63f", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA claim revenue from vaultIpIdB", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdA claim revenue from vaultIpIdB", + "timedOut": false, + "duration": 15, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x2de0efccd083f799c2d0b73dfbf0e196815ddc65a70e5ef6ec4f1989f14e4e5a\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "ad41c2ff-5030-47fc-82dd-e5730964a0fa", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB claim revenue from vaultIpIdB by IPA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdB claim revenue from vaultIpIdB by IPA", + "timedOut": false, + "duration": 38, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb0e1740c824d4d05ff1a4419df0d2eef4b50dfe88fa4c4132e4a58140433c862\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "c33793e4-f03b-4b5b-a8c4-c6dd2ecd6d12", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdB claim revenue from vaultIpIdB by EOA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdB claim revenue from vaultIpIdB by EOA", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x5563563111ebd3da905187bcf98d3453b453576b2938aa478f97a881e06fb5ba\\\",\\\"claimableToken\\\":\\\"1200n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8c71ec51-5ade-4871-96d7-e0e176b37998", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "Capture snapshotId for ipIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA Capture snapshotId for ipIdA", + "timedOut": false, + "duration": 12, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xccc571a36751b531ef0ace5368e99e20e121935f215bcc1023b45ace27b7aa89\\\",\\\"snapshotId\\\":\\\"1n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6adaa5b9-dec3-4170-a200-e96c0db1f7fb", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA check claimable revenue from vaultIpIdA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdA check claimable revenue from vaultIpIdA", + "timedOut": false, + "duration": 3, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"0\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "6cac4a7d-6f52-492e-83bc-f153263ff29c", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA claim revenue from vaultIpIdA by IPA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdA claim revenue from vaultIpIdA by IPA", + "timedOut": false, + "duration": 39, + "state": "passed", + "speed": "medium", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x0aebbafc64b7da52f32abf577bc7aa723f2f112ae52c4a2ff29361e8373b382e\\\",\\\"claimableToken\\\":\\\"0n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "332a5ce0-7599-45b3-ba58-3471e733ce33", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + }, + { + "title": "ipIdA claim revenue from vaultIpIdA by EOA", + "fullTitle": "SDK E2E Test - Royalty Commercial Use PIL - Claim Minting Fee and Revenue by EOA ipIdA claim revenue from vaultIpIdA by EOA", + "timedOut": false, + "duration": 14, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xc6978245708da0a52381c56aebe584db3b7fd6f34f35389b94ca848d26f74b3d\\\",\\\"claimableToken\\\":\\\"200n\\\"}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8f92ae18-cc35-413c-8f29-fbc2afcdb322", + "parentUUID": "e65988f8-cef1-487d-b46f-c9439b19db6a", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "e2a83671-0b3e-40d0-b643-297d6a4e41ae", + "d7289da3-a28f-4000-a9bc-30f94b5fb45a", + "c56b0299-deec-4737-9b8c-c9dc9a224690", + "6d603006-39bb-4b58-b68f-9f8fc94bb34c", + "f56e1ec1-4f35-4215-8525-4eeaa32f670a", + "afe83d32-a9ab-409b-b28c-a135ae48a63f", + "ad41c2ff-5030-47fc-82dd-e5730964a0fa", + "c33793e4-f03b-4b5b-a8c4-c6dd2ecd6d12", + "8c71ec51-5ade-4871-96d7-e0e176b37998", + "6adaa5b9-dec3-4170-a200-e96c0db1f7fb", + "6cac4a7d-6f52-492e-83bc-f153263ff29c", + "332a5ce0-7599-45b3-ba58-3471e733ce33", + "8f92ae18-cc35-413c-8f29-fbc2afcdb322" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 205, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "c58b2a2e-2606-4efc-b071-77ea5356f680", + "title": "@smoke SDK E2E Test - Permissions", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/setPermissions.test.ts", + "file": "/test/e2e/setPermissions.test.ts", + "beforeHooks": [ + { + "title": "\"before all\" hook: Wallet A register 2 license terms and 2 IP assets in \"@smoke SDK E2E Test - Permissions\"", + "fullTitle": "@smoke SDK E2E Test - Permissions \"before all\" hook: Wallet A register 2 license terms and 2 IP assets in \"@smoke SDK E2E Test - Permissions\"", + "timedOut": false, + "duration": 4411, + "state": null, + "speed": null, + "pass": false, + "fail": false, + "pending": false, + "context": null, + "code": "tokenIdA = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyA);\n(0, utils_1.checkMintResult)(tokenIdA);\nconst responseRegisterIpA = await (0, chai_1.expect)((0, sdkUtils_1.registerIpAsset)(\"A\", config_1.nftContractAddress, tokenIdA, waitForTransaction)).to.not.be.rejected;\n(0, chai_1.expect)(responseRegisterIpA.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_1.expect)(responseRegisterIpA.ipId).to.be.a(\"string\").and.not.empty;\nipIdA = responseRegisterIpA.ipId;\ntokenIdB = await (0, utils_1.mintNFTWithRetry)(config_1.privateKeyA);\n(0, utils_1.checkMintResult)(tokenIdB);\nconst responseRegisterIpB = await (0, chai_1.expect)((0, sdkUtils_1.registerIpAsset)(\"A\", config_1.nftContractAddress, tokenIdB, waitForTransaction)).to.not.be.rejected;\n(0, chai_1.expect)(responseRegisterIpB.txHash).to.be.a(\"string\").and.not.empty;\n(0, chai_1.expect)(responseRegisterIpB.ipId).to.be.a(\"string\").and.not.empty;\nipIdB = responseRegisterIpB.ipId;", + "err": {}, + "uuid": "4f3e8d2d-e381-4d51-8dd5-4a4249d15400", + "parentUUID": "c58b2a2e-2606-4efc-b071-77ea5356f680", + "isHook": true, + "skipped": false + } + ], + "afterHooks": [], + "tests": [], + "suites": [ + { + "uuid": "f4fa3382-cf8d-4d67-aa8c-68c94a3ccbc6", + "title": "Set permission - 1 ALLOW", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/setPermissions.test.ts", + "file": "/test/e2e/setPermissions.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Wallet B(non-owner) can NOT attach licenseTermsId 0 to ipIdA", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 1 ALLOW Wallet B(non-owner) can NOT attach licenseTermsId 0 to ipIdA", + "timedOut": false, + "duration": 2107, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "2a146b20-2d96-4100-8285-772bde281c23", + "parentUUID": "f4fa3382-cf8d-4d67-aa8c-68c94a3ccbc6", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdA", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 1 ALLOW Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdA", + "timedOut": false, + "duration": 18, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xe57375b3c47877c9dfe9c603cc5c83adab988df74f1ab0b32cfe9ee3a8e219c7\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "17b06058-02fc-44a3-bcfa-a4ebde225735", + "parentUUID": "f4fa3382-cf8d-4d67-aa8c-68c94a3ccbc6", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can attach licenseTermsId 0 to ipIdA", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 1 ALLOW Wallet B can attach licenseTermsId 0 to ipIdA", + "timedOut": false, + "duration": 118, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xb459395ffc7b58a9215c546de995f45cf79b3bce3a1ebac811c5f9d9753ed2ab\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8b214de4-ee96-4de6-84fb-f7977b2a723d", + "parentUUID": "f4fa3382-cf8d-4d67-aa8c-68c94a3ccbc6", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT attach licenseTermsId 0 to ipIdB", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 1 ALLOW Wallet B can NOT attach licenseTermsId 0 to ipIdB", + "timedOut": false, + "duration": 2091, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f79eaca6-9960-46c5-a2b6-5f33de1f9737", + "parentUUID": "f4fa3382-cf8d-4d67-aa8c-68c94a3ccbc6", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "2a146b20-2d96-4100-8285-772bde281c23", + "17b06058-02fc-44a3-bcfa-a4ebde225735", + "8b214de4-ee96-4de6-84fb-f7977b2a723d", + "f79eaca6-9960-46c5-a2b6-5f33de1f9737" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 4334, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "b5fc5b28-f0ee-4b84-b910-97204d49f249", + "title": "Set permission - 2 DENY", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/setPermissions.test.ts", + "file": "/test/e2e/setPermissions.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Wallet A set permission (permission id: 2) to NOT allow Wallet B to call license Module for ipIdA", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 2 DENY Wallet A set permission (permission id: 2) to NOT allow Wallet B to call license Module for ipIdA", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x4c2db84582cc9f7f3ef2833f3e086cf31fbf0910fa49c5a293552db640de60e2\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "506b4116-4261-418f-8f5a-33a4b6ae2337", + "parentUUID": "b5fc5b28-f0ee-4b84-b910-97204d49f249", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT attach licenseTermsId1 to ipIdA", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 2 DENY Wallet B can NOT attach licenseTermsId1 to ipIdA", + "timedOut": false, + "duration": 20, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f3cb91d3-ba55-4f17-a7f0-c9eaf3b67919", + "parentUUID": "b5fc5b28-f0ee-4b84-b910-97204d49f249", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "506b4116-4261-418f-8f5a-33a4b6ae2337", + "f3cb91d3-ba55-4f17-a7f0-c9eaf3b67919" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 36, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + }, + { + "uuid": "682c9ecc-814d-4287-9cb6-bc2d86eb664c", + "title": "Set permission - 0 ABSTAIN", + "fullFile": "/home/runner/work/sdk-e2e-tests/sdk-e2e-tests/test/e2e/setPermissions.test.ts", + "file": "/test/e2e/setPermissions.test.ts", + "beforeHooks": [], + "afterHooks": [], + "tests": [ + { + "title": "Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdB", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 0 ABSTAIN Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdB", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xaeb004b19aa236cc030d27877b54dd6633fae2361c7c68e8996261b42a22c3ee\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "7cb47620-068c-4a4b-8bbb-d76c8bd3e75e", + "parentUUID": "682c9ecc-814d-4287-9cb6-bc2d86eb664c", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can attach licenseTermsId 0 to ipIdB", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 0 ABSTAIN Wallet B can attach licenseTermsId 0 to ipIdB", + "timedOut": false, + "duration": 1130, + "state": "passed", + "speed": "slow", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0xbfd87d4418f8e73c51fb9c3e48aae4edfbbe657db44f6c4e97792a82809bc005\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "f8f8ab1f-ae24-463d-a2e6-cd9e9fa9a7ab", + "parentUUID": "682c9ecc-814d-4287-9cb6-bc2d86eb664c", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet A set permission (permission id: 0) to NOT allow Wallet B to call license Module for ipIdB", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 0 ABSTAIN Wallet A set permission (permission id: 0) to NOT allow Wallet B to call license Module for ipIdB", + "timedOut": false, + "duration": 16, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": "{\n \"title\": \"Test Result\",\n \"value\": \"{\\\"txHash\\\":\\\"0x53b6afaa8b941e8860fcd4353a60641fc987e10bfd857d797412c190af0aef5c\\\",\\\"success\\\":true}\"\n}", + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "17f0ca0c-0bc3-4d70-b528-2536dc3306c3", + "parentUUID": "682c9ecc-814d-4287-9cb6-bc2d86eb664c", + "isHook": false, + "skipped": false + }, + { + "title": "Wallet B can NOT attach licenseTermsId2 to ipIdB", + "fullTitle": "@smoke SDK E2E Test - Permissions Set permission - 0 ABSTAIN Wallet B can NOT attach licenseTermsId2 to ipIdB", + "timedOut": false, + "duration": 25, + "state": "passed", + "speed": "fast", + "pass": true, + "fail": false, + "pending": false, + "context": null, + "code": "var context = this;\n try {\n var promise = fn.call(context);\n if (promise != null && promise.then != null && promise.catch != null) {\n return promise.catch(function(err) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw err;\n });\n } else {\n return promise;\n }\n } catch (ex) {\n markRemainingTestsAndSubSuitesAsPending(context.test);\n throw ex;\n }", + "err": {}, + "uuid": "8ef25361-5ae3-4e83-9733-e36d1d937e12", + "parentUUID": "682c9ecc-814d-4287-9cb6-bc2d86eb664c", + "isHook": false, + "skipped": false + } + ], + "suites": [], + "passes": [ + "7cb47620-068c-4a4b-8bbb-d76c8bd3e75e", + "f8f8ab1f-ae24-463d-a2e6-cd9e9fa9a7ab", + "17f0ca0c-0bc3-4d70-b528-2536dc3306c3", + "8ef25361-5ae3-4e83-9733-e36d1d937e12" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 1187, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [], + "failures": [], + "pending": [], + "skipped": [], + "duration": 0, + "root": false, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "passes": [ + "6576355b-7358-48e0-951a-f3a1d587fe4c", + "ddb562e0-10c8-442d-8417-74ff39cd068b", + "4bc7b34e-05c2-430e-8a16-fd81137846f9" + ], + "failures": [], + "pending": [], + "skipped": [], + "duration": 321, + "root": true, + "rootEmpty": false, + "_timeout": 240000 + } + ], + "meta": { + "mocha": { + "version": "10.6.0" + }, + "mochawesome": { + "options": { + "quiet": false, + "reportFilename": "[status]_[datetime]_sdk-test-report", + "saveHtml": true, + "saveJson": true, + "consoleReporter": "spec", + "useInlineDiffs": false, + "code": true + }, + "version": "7.1.3" + }, + "marge": { + "options": { + "reportDir": "test-reports", + "reportFilename": "[status]_[datetime]_sdk-test-report", + "timestamp": "mm-dd-yyyy_HHMMss", + "reportTitle": "SDK Test Report" + }, + "version": "6.2.0" + } + } +} \ No newline at end of file diff --git a/test/dispute/cancelDispute.test.ts b/test/dispute/cancelDispute.test.ts new file mode 100644 index 0000000..1be5107 --- /dev/null +++ b/test/dispute/cancelDispute.test.ts @@ -0,0 +1,113 @@ +import { privateKeyA, nftContractAddress, arbitrationPolicyAddress } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult } from '../../utils/utils'; +import { registerIpAsset, raiseDispute, cancelDispute } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; + +let tokenIdA: string; +let ipIdA: Address; +let disputeId1: bigint; +let disputeId2: bigint; +let disputeId3: bigint; + +describe("SDK Test", function () { + describe("Test dispute.cancelDispute Function", async function () { + before("Register IP assets and raise disputes", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + expect(tokenIdA).not.empty; + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const responseRaiseDispute1 = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test1", "PLAGIARISM", true) + ).to.not.be.rejected; + + expect(responseRaiseDispute1.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute1.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId1 = responseRaiseDispute1.disputeId; + + const responseRaiseDispute2 = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test2", "PLAGIARISM", true) + ).to.not.be.rejected; + + expect(responseRaiseDispute2.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute2.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId2 = responseRaiseDispute2.disputeId; + + const responseRaiseDispute3 = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test3", "PLAGIARISM", true) + ).to.not.be.rejected; + + expect(responseRaiseDispute3.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute3.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId3 = responseRaiseDispute3.disputeId; + }); + + it("Cancel dispute fail as undefined disputeId", async function () { + let disputeId1: any; + const response = await expect( + cancelDispute("B", disputeId1, true) + ).to.be.rejectedWith("Failed to cancel dispute: Cannot convert undefined to a BigInt"); + }); + + it("Cancel dispute fail as invalid disputeId", async function () { + const response = await expect( + cancelDispute("B", "test", true) + ).to.be.rejectedWith("Failed to cancel dispute: Cannot convert test to a BigInt"); + }); + + it("Cancel dispute fail as non-existent disputeId", async function () { + const response = await expect( + cancelDispute("B", "999999", true) + ).to.be.rejectedWith("Failed to cancel dispute: The contract function \"cancelDispute\" reverted.", + "Error: DisputeModule__NotInDisputeState()"); + }); + + it("Cancel dispute with waitForTransaction: true", async function () { + const response = await expect( + cancelDispute("B", disputeId1, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Cancel dispute with waitForTransaction: false", async function () { + const response = await expect( + cancelDispute("B", disputeId2, false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Cancel dispute with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + cancelDispute("B", disputeId3, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Cancel dispute fail as already canceled", async function () { + const response = await expect( + cancelDispute("B", disputeId1, true) + ).to.be.rejectedWith("Failed to cancel dispute: The contract function \"cancelDispute\" reverted.", + "Error: DisputeModule__NotInDisputeState()"); + }); + }); +}); \ No newline at end of file diff --git a/test/dispute/raiseDispute.test.ts b/test/dispute/raiseDispute.test.ts new file mode 100644 index 0000000..42d3b53 --- /dev/null +++ b/test/dispute/raiseDispute.test.ts @@ -0,0 +1,148 @@ +import { privateKeyA, nftContractAddress, arbitrationPolicyAddress } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult } from '../../utils/utils'; +import { registerIpAsset, raiseDispute } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; + +const waitForTransaction: boolean = true; + +let tokenIdA: string; +let ipIdA: Address; + +describe("SDK Test", function () { + describe("Test dispute.raiseDispute Function", async function () { + before("Register IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + expect(tokenIdA).not.empty; + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + }); + + it("Raise dispute fail as undefined ipId", async function () { + let ipIdA: any; + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.be.rejectedWith(`Failed to raise dispute: request.targetIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Raise dispute fail as invalid ipId", async function () { + const response = await expect( + raiseDispute("B", "0x0000", arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.be.rejectedWith(`Failed to raise dispute: request.targetIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Raise dispute fail as non-existent ipId", async function () { + const response = await expect( + raiseDispute("B", "0x8Dcd7f0be38Be6adbe2a7d8fb58032b1e20E3681", arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.be.rejectedWith(`Failed to raise dispute: The contract function "raiseDispute" reverted.`, `Error: DisputeModule__NotRegisteredIpId()`); + }); + + it("Raise dispute fail as undefined linkToDisputeEvidence", async function () { + let linkToDisputeEvidence: any; + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, linkToDisputeEvidence, "PLAGIARISM", waitForTransaction) + ).to.be.rejectedWith("Failed to raise dispute: The contract function \"raiseDispute\" reverted.", + "Error: DisputeModule__ZeroLinkToDisputeEvidence()"); + }); + + it("Raise dispute fail as empty linkToDisputeEvidence", async function () { + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "", "PLAGIARISM", waitForTransaction) + ).to.be.rejectedWith("Failed to raise dispute: The contract function \"raiseDispute\" reverted.", + "Error: DisputeModule__ZeroLinkToDisputeEvidence()"); + }); + + it("Raise dispute fail as undefined targetTag", async function () { + let targetTag: any; + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test", targetTag, waitForTransaction) + ).to.be.rejectedWith("Failed to raise dispute: The contract function \"raiseDispute\" reverted.", + "DisputeModule__NotWhitelistedDisputeTag()"); + }); + + it("Raise dispute fail as unwhitelisted targetTag", async function () { + let targetTag: any; + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test", "test", waitForTransaction) + ).to.be.rejectedWith("Failed to raise dispute: The contract function \"raiseDispute\" reverted.", + "Error: DisputeModule__NotWhitelistedDisputeTag()"); + }); + + it("Raise dispute with undefined arbitrationPolicyAddress", async function () { + let arbitrationPolicyAddress: any; + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.disputeId).to.be.a("bigint").and.to.be.ok; + }); + + it("Raise dispute with invalid arbitrationPolicyAddress", async function () { + const response = await expect( + raiseDispute("B", ipIdA, "0x0000", "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.disputeId).to.be.a("bigint").and.to.be.ok; + }); + + it("Raise dispute", async function () { + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test1", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.disputeId).to.be.a("bigint").and.to.be.ok; + }); + + it("Raise dispute one more time", async function () { + const response = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test1", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.disputeId).to.be.a("bigint").and.to.be.ok; + }); + + it("Raise dispute with undefined waitForTransaction", async function () { + let waitForTransaction: any; + const response = await expect( + raiseDispute("A", ipIdA, arbitrationPolicyAddress, "test2", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.disputeId).to.not.exist; + }); + + it("Raise dispute with waitForTransaction: true", async function () { + const response = await expect( + raiseDispute("A", ipIdA, arbitrationPolicyAddress, "test3", "PLAGIARISM", true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.disputeId).to.be.a("bigint").and.to.be.ok; + }); + + it("Raise dispute with undefined waitForTransaction: false", async function () { + const response = await expect( + raiseDispute("A", ipIdA, arbitrationPolicyAddress, "test4", "PLAGIARISM", false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.disputeId).to.not.exist; + }); + }); +}); \ No newline at end of file diff --git a/test/dispute/resolveDispute.test.ts b/test/dispute/resolveDispute.test.ts new file mode 100644 index 0000000..3a95404 --- /dev/null +++ b/test/dispute/resolveDispute.test.ts @@ -0,0 +1,119 @@ +import { privateKeyA, nftContractAddress, arbitrationPolicyAddress, privateKeyC } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult, setDisputeJudgement, sleep } from '../../utils/utils'; +import { registerIpAsset, raiseDispute, resolveDispute } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; + +let tokenIdA: string; +let ipIdA: Address; +let disputeId1: bigint; +let disputeId2: bigint; + +describe("SDK Test", function () { + describe("Test dispute.resolveDispute Function", async function () { + before("Register IP assets and raise disputes", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const responseRaiseDispute1 = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test1", "PLAGIARISM", true) + ).to.not.be.rejected; + + expect(responseRaiseDispute1.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute1.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId1 = responseRaiseDispute1.disputeId; + + const responseRaiseDispute2 = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test2", "PLAGIARISM", true) + ).to.not.be.rejected; + + expect(responseRaiseDispute2.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute1.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId2 = responseRaiseDispute2.disputeId; + }); + + it("Resolve dispute fail as undefined disputeId", async function () { + let disputeId1: any; + const response = await expect( + resolveDispute("B", disputeId1, "0x", true) + ).to.be.rejectedWith(`Failed to resolve dispute: Cannot convert undefined to a BigInt`); + }); + + it("Resolve dispute fail as invalid disputeId", async function () { + const response = await expect( + resolveDispute("B", "test", "0x", true) + ).to.be.rejectedWith(`Failed to resolve dispute: Cannot convert test to a BigInt`); + }); + + it("Resolve dispute fail as non-existent disputeId", async function () { + const response = await expect( + resolveDispute("B", "999999", "0x", true) + ).to.be.rejectedWith(`Failed to resolve dispute: The contract function "resolveDispute" reverted.`, + `Error: DisputeModule__NotDisputeInitiator()`); + }); + + it("Resolve dispute fail as undefined data", async function () { + let data: any; + const response = await expect( + resolveDispute("B", disputeId1, data, true) + ).to.be.rejectedWith(`Failed to resolve dispute: Cannot read properties of undefined (reading 'length')`); + }); + + it("Resolve dispute fail as not dispute initiator", async function () { + const response = await expect( + resolveDispute("A", disputeId1, "0x", true) + ).to.be.rejectedWith(`Failed to resolve dispute: The contract function "resolveDispute" reverted.`, + `Error: DisputeModule__NotDisputeInitiator()`); + }); + + it("Resolve dispute fail as not set judgement", async function () { + const response = await expect( + resolveDispute("B", disputeId1, "0x0000", true) + ).to.be.rejectedWith(`Failed to resolve dispute: The contract function "resolveDispute" reverted.`, + `Error: DisputeModule__NotAbleToResolve()`); + }); + + it("Resolve dispute fail as judgement decision is false", async function () { + await setDisputeJudgement(privateKeyC, disputeId1, false, "0x"); + await sleep(10); + + const response = await expect( + resolveDispute("B", disputeId1, "0x0000", true) + ).to.be.rejectedWith(`Failed to resolve dispute: The contract function "resolveDispute" reverted.`, + `Error: DisputeModule__NotAbleToResolve()`); + }); + + it("Resolve dispute faile as already resolved", async function () { + const response = await expect( + resolveDispute("B", disputeId1, "0x0000", false) + ).to.be.rejectedWith(`Failed to resolve dispute: The contract function "resolveDispute" reverted.`, + `Error: DisputeModule__NotAbleToResolve()`); + }); + + it("Resolve dispute with waitForTransaction: false", async function () { + await setDisputeJudgement(privateKeyC, disputeId2, true, "0x"); + await sleep(10); + + const response = await expect( + resolveDispute("B", disputeId2, "0x0000", false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); +}); diff --git a/test/e2e/derivativeIP.comRemixPIL.test.ts b/test/e2e/derivativeIP.comRemixPIL.test.ts new file mode 100644 index 0000000..7675e6c --- /dev/null +++ b/test/e2e/derivativeIP.comRemixPIL.test.ts @@ -0,0 +1,577 @@ +import { privateKeyA, privateKeyB, privateKeyC, accountA, accountB, accountC, nftContractAddress } from '../../config/config'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, mintLicenseTokens, registerDerivative, registerDerivativeWithLicenseTokens } from '../../utils/sdkUtils'; +import { expect } from 'chai'; + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Hex } from 'viem'; +import { comRemixLicenseTermsId1 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Hex; +let ipIdB: Hex; +let ipIdC: Hex; +let licenseTokenIdA: string; +let licenseTokenIdB: string; + +const waitForTransaction: boolean = true; + +describe("SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL", function () { + describe("@smoke Register a derivative IP asset with/without license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA= response.licenseTokenIds[0]; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }) + + // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA + step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + + step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe('Register a derivative IP asset with multiple parent IP assets', async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet C can register a derivative IP asset with multiple parent IP assets", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA, ipIdB], [comRemixLicenseTermsId1, comRemixLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; +            }); + }); + + describe("Register a derivative IP assets with multiple license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + // Wallet C is not the licensee of licenseTokenIdA + step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); + }); + }); + + describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdC); + + expect(tokenIdC).not.empty; + }); + + step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + }); + + describe("Register derivative IP asset with an IP that already has license", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA= response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 1, accountA.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); + }); + }); +}); + diff --git a/test/e2e/derivativeIP.comUsePIL.test.ts b/test/e2e/derivativeIP.comUsePIL.test.ts new file mode 100644 index 0000000..7c44e84 --- /dev/null +++ b/test/e2e/derivativeIP.comUsePIL.test.ts @@ -0,0 +1,593 @@ +import { privateKeyA, privateKeyB, privateKeyC, accountA, accountB, accountC, nftContractAddress } from '../../config/config'; +import { mintNFTWithRetry } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, mintLicenseTokens, registerDerivative, registerDerivativeWithLicenseTokens } from '../../utils/sdkUtils'; +import { expect } from 'chai'; + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Hex } from 'viem'; +import { comUseLicenseTermsId1 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Hex; +let ipIdB: Hex; +let ipIdC: Hex; +let licenseTokenIdA: string; +let licenseTokenIdB: string; + +const waitForTransaction: boolean = true; + +describe("SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL", function () { + describe("[smoke]Register a derivative IP asset with/without license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }) + + // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA + step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + + step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe('Register a derivative IP asset with multiple parent IP assets', async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet C can register a derivative IP asset with multiple parent IP assets (ipIdA, ipIdB)", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA, ipIdB], [comUseLicenseTermsId1, comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; +            }); + }); + + describe("Register a derivative IP assets with multiple license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA= response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet C can register a derivative IP asset with multiple license tokens (licenseTokenIdA, licenseTokenIdB)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + // Wallet C is not the licensee of licenseTokenIdA + step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); + }); + }); + + describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + }); + + describe("Register derivative IP asset with an IP that already has license", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 1, accountA.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); + }); + }); +}); diff --git a/test/e2e/derivativeIP.nonComPIL.test.ts b/test/e2e/derivativeIP.nonComPIL.test.ts new file mode 100644 index 0000000..9729b1e --- /dev/null +++ b/test/e2e/derivativeIP.nonComPIL.test.ts @@ -0,0 +1,521 @@ +import { privateKeyA, privateKeyB, privateKeyC, accountA, accountB, accountC,nftContractAddress } from '../../config/config'; +import { mintNFTWithRetry } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, mintLicenseTokens, registerDerivative, registerDerivativeWithLicenseTokens } from '../../utils/sdkUtils'; +import { expect } from 'chai'; + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Hex } from 'viem'; +import { nonComLicenseTermsId } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Hex; +let ipIdB: Hex; +let ipIdC: Hex; +let licenseTokenIdA: string; +let licenseTokenIdB: string; + +const waitForTransaction: boolean = true; + +describe("SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL", function () { + describe("[smoke]Register a derivative IP asset with/without license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }) + + // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA + step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + + step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA], [nonComLicenseTermsId], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe('Register a derivative IP asset with multiple parent IP assets', async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet C can register a derivative IP asset with multiple parent IP assets", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA, ipIdB], [nonComLicenseTermsId, nonComLicenseTermsId], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; +            }); + }); + + describe("Register a derivative IP assets with multiple license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + // Wallet C is not the licensee of licenseTokenIdA + step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); + }); + }); + + describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + }); + + describe("Register derivative IP asset with an IP that already has license", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, 0n, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, 0n, 1, accountA.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); + }); + }); +}); diff --git a/test/e2e/dispute.test.ts b/test/e2e/dispute.test.ts new file mode 100644 index 0000000..4cc115e --- /dev/null +++ b/test/e2e/dispute.test.ts @@ -0,0 +1,693 @@ +import { privateKeyA, privateKeyB, accountB, nftContractAddress, arbitrationPolicyAddress, mintingFeeTokenAddress, privateKeyC, accountA } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult, setDisputeJudgement, sleep } from '../../utils/utils'; +import { registerIpAsset, raiseDispute, attachLicenseTerms, mintLicenseTokens, registerDerivativeWithLicenseTokens, payRoyaltyOnBehalf, collectRoyaltyTokens, royaltySnapshot, royaltyClaimableRevenue, royaltyClaimRevenue, registerDerivative, resolveDispute } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { nonComLicenseTermsId, comUseLicenseTermsId1, comRemixLicenseTermsId2, mintingFee1, mintingFee2, commercialRevShare2 } from '../setup'; + +const waitForTransaction: boolean = true; + +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; +let disputeId1: bigint; +let disputeId2: bigint; +let disputeId3: bigint; +let licenseTokenId1: bigint; +let licenseTokenId2: bigint; +let licenseTokenId3: bigint; + +describe("SDK E2E Test - Dispute Module", function () { + describe("IP Asset is IN_DISPUTE", async function () { + before("Register IP assets and raise dispute", async function () { + const tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + + const responseRaiseDispute = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + }); + + describe("Attach License Terms to IN_DISPUTE IP Asset", async function () { + it("Attach non-commerical social remixing PIL to IN_DISPUTE IP asset", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, 0n, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Attach commercial use PIL to IN_DISPUTE IP asset", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Attach commericial remix PIL to IN_DISPUTE IP asset", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Mint License Tokens for IN_DISPUTE IP asset", async function () { + it("Mint license tokens with non-commerical social remixing PIL for IN_DISPUTE IP asset", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint license tokens with commercial use PIL for IN_DISPUTE IP asset", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint license tokens with commericial remix PIL for IN_DISPUTE IP asset", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId2, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenId3 = response.licenseTokenIds[0]; + }); + }); + + describe("Register Derivative IP Asset with License Tokens and Royalty Related Process", async function () { + let snapshotId1: string; + const payAmount: string = "100"; + const revenueTokens: bigint = BigInt(Number(payAmount) + Number(mintingFee1) * 2 + Number(mintingFee2) * 2); + + step("Register derivative with license tokens attached commercial remix PIL, parent IP is an IN_DISPUTE IP asset", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenId3], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Pay royalty on behalf", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, ipIdB, mintingFeeTokenAddress, payAmount, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Collect royalty tokens", async function () { + const response = await expect( + collectRoyaltyTokens("A", ipIdA, ipIdB, waitForTransaction) + ).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 * 1000000)); + }); + + step("Captue snapshot", async function () { + const response = await expect( + royaltySnapshot("A", ipIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("String").and.not.empty; + + snapshotId1 = response.snapshotId; + }); + + step("Check claimable revenue", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) + ).to.not.be.rejected; + + expect(response).to.be.a("bigint").and.be.equal(revenueTokens); + }); + + step("Claim royalty tokens", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.claimableToken).to.be.a("bigint").and.be.equal(revenueTokens); + }); + }); + + describe("Register Derivative IP Asset without License Tokens", async function () { + describe("Non-commerical social remixing PIL", async function () { + before("Register IP Asset", async function () { + const tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }) + + step("Register derivative with non-commercial social remixing PIL, parent IP is an IN_DISPUTE IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Commercial use PIL", async function () { + before("Register IP Asset", async function () { + const tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }) + + step("Register derivative with commercial use PIL, parent IP is an IN_DISPUTE IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Commercial remix PIL", async function () { + before("Register IP Asset", async function () { + const tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Register derivative with commercial remix PIL, parent IP is an IN_DISPUTE IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + }); + }); + + describe("IP Asset is DISPUTED", async function () { + before("Register IP assets and raise dispute", async function () { + const tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + + const responseRaiseDispute = await expect( + raiseDispute("B", ipIdA, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId1 = responseRaiseDispute.disputeId; + + await setDisputeJudgement(privateKeyC, disputeId1, true, "0x"); + }); + + describe("Attach License Terms to DISPUTED IP Asset", async function () { + it("Attach non-commerical social remixing PIL to a DISPUTED IP asset", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, 0n, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted.", + "Error: LicensingModule__DisputedIpId()"); + }); + + it("Attach commercial use PIL to an IN_DISPUTE IP asset", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted.", + "Error: LicensingModule__DisputedIpId()"); + }); + + it("Attach commericial remix PIL to an IN_DISPUTE IP asset", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId2, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted.", + "Error: LicensingModule__DisputedIpId()"); + }); + }); + + describe("Mint License Tokens for DISPUTED IP asset", async function () { + before("Attach license terms, raise dispute and set judgement", async function () { + const responseComUsePIL = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseComUsePIL.txHash).to.be.a("string").and.not.empty; + + const responsecomRemixPIL = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(responsecomRemixPIL.txHash).to.be.a("string").and.not.empty; + + const responseRaiseDispute = await expect( + raiseDispute("A", ipIdB, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId2 = responseRaiseDispute.disputeId; + + await setDisputeJudgement(privateKeyC, disputeId2, true, "0x"); + }); + + it("Mint license tokens with non-commerical social remixing PIL for a DISPUTED IP asset", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) + ).to.be.rejectedWith("Failed to mint license tokens: The contract function \"mintLicenseTokens\" reverted.", + "Error: LicensingModule__DisputedIpId()"); + }); + + it("Mint license tokens with commerical use PIL for a DISPUTED IP asset", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.be.rejectedWith("Failed to mint license tokens: The contract function \"mintLicenseTokens\" reverted.", + "Error: LicensingModule__DisputedIpId()"); + }); + + it("Mint license tokens with commericial remix PIL for a DISPUTED IP asset", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId2, 2, accountB.address, waitForTransaction) + ).to.be.rejectedWith("Failed to mint license tokens: The contract function \"mintLicenseTokens\" reverted.", + "Error: LicensingModule__DisputedIpId()"); + }); + }); + + describe("Register Derivative IP Asset without License Tokens", async function () { + before("Register IP Asset", async function () { + const tokenIdC = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdC); + + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + describe("Non-commerical social remixing PIL", async function () { + // 0x76a26b62: LicenseRegistry__ParentIpTagged(address) + step("Register derivative with non-commercial social remixing PIL, parent IP is a DISPUTED IP asset", async function () { + const response = await expect( + registerDerivative("A", ipIdC, [ipIdB], [nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted with the following signature:", "0x76a26b62"); + }); + + step("Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", async function () { + const responseAttachLicenseTerms = await expect( + attachLicenseTerms("A", ipIdC, 0n, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + + const response = await expect( + registerDerivative("B", ipIdB, [ipIdC], [nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", "Error: LicensingModule__DisputedIpId()"); + }); + }); + + describe("Commercial use PIL", async function () { + // 0x76a26b62: LicenseRegistry__ParentIpTagged(address) + step("Register derivative with commercial use PIL, parent IP is a DISPUTED IP asset", async function () { + const response = await expect( + registerDerivative("A", ipIdC, [ipIdB], [comUseLicenseTermsId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted with the following signature:", "0x76a26b62"); + }); + + step("Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", async function () { + const responseAttachLicenseTerms = await expect( + attachLicenseTerms("A", ipIdC, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + + const response = await expect( + registerDerivative("B", ipIdB, [ipIdC], [comUseLicenseTermsId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", "Error: LicensingModule__DisputedIpId()"); + }); + }); + + describe("Commercial remix PIL", async function () { + // 0x76a26b62: LicenseRegistry__ParentIpTagged(address) + step("Register derivative with commercial remix PIL, parent IP is a DISPUTED IP asset", async function () { + const response = await expect( + registerDerivative("A", ipIdC, [ipIdB], [comRemixLicenseTermsId2], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted with the following signature:", "0x76a26b62"); + }); + + step("Register derivative with non-commercial social remixing PIL, derivative IP is a DISPUTED IP asset", async function () { + const responseAttachLicenseTerms = await expect( + attachLicenseTerms("A", ipIdC, comRemixLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + + const response = await expect( + registerDerivative("B", ipIdB, [ipIdC], [comRemixLicenseTermsId2], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", "Error: LicensingModule__DisputedIpId()"); + }); + }); + }); + + describe("Register Derivative IP Asset with License Tokens", async function () { + before("Register IP Asset", async function () { + const responseResolveDispute = await expect( + resolveDispute("A", disputeId2, "0x0000", false) + ).to.not.be.rejected; + + expect(responseResolveDispute.txHash).to.be.a("string").and.not.empty; + + await sleep(10); + + const responsemintLicenseTokens1 = await expect( + mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountA.address, true) + ).to.not.be.rejected; + + expect(responsemintLicenseTokens1.txHash).to.be.a("string").and.not.empty; + expect(responsemintLicenseTokens1.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenId1 = responsemintLicenseTokens1.licenseTokenIds[0]; + + const responsemintLicenseTokens2 = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountA.address, true) + ).to.not.be.rejected; + + expect(responsemintLicenseTokens2.txHash).to.be.a("string").and.not.empty; + expect(responsemintLicenseTokens2.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenId2 = responsemintLicenseTokens2.licenseTokenIds[0]; + + const responsemintLicenseTokens3 = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId2, 2, accountA.address, true) + ).to.not.be.rejected; + + expect(responsemintLicenseTokens3.txHash).to.be.a("string").and.not.empty; + expect(responsemintLicenseTokens3.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenId3 = responsemintLicenseTokens3.licenseTokenIds[0]; + + const responseRaiseDispute = await expect( + raiseDispute("A", ipIdB, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId2 = responseRaiseDispute.disputeId; + + await setDisputeJudgement(privateKeyC, disputeId2, true, "0x"); + + const tokenIdC = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdC); + + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + describe("Register derivative IP asset, parent IP is a DISPUTED IP asset, ", async function () { + // 0x39944339: LicenseToken__RevokedLicense(uint256) + step("Non-commerical social remixing PIL", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("A", ipIdC, [licenseTokenId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x39944339"); + }); + + // 0x39944339: LicenseToken__RevokedLicense(uint256) + step("Commercial use PIL", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("A", ipIdC, [licenseTokenId2],waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x39944339"); + }); + + // 0x39944339: LicenseToken__RevokedLicense(uint256) + step("Register derivative with commercial remix PIL, parent IP is a DISPUTED IP asset", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("A", ipIdC, [licenseTokenId3],waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x39944339"); + }); + }); + + describe("Register derivative IP asset, derivative IP is a DISPUTED IP asset, ", async function () { + before("Resolve dispute for the parent IP, raise dispute for the derivative IP", async function () { + const responseResolveDispute = await expect( + resolveDispute("A", disputeId2, "0x0000", false) + ).to.not.be.rejected; + + expect(responseResolveDispute.txHash).to.be.a("string").and.not.empty; + + const responseRaiseDispute = await expect( + raiseDispute("B", ipIdC, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId3 = responseRaiseDispute.disputeId; + + await setDisputeJudgement(privateKeyC, disputeId3, true, "0x"); + }) + + step("Non-commerical social remixing PIL", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("A", ipIdC, [licenseTokenId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted.", "Error: LicensingModule__DisputedIpId()"); + }); + + step("Commerical use PIL", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("A", ipIdC, [licenseTokenId2], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted.", "Error: LicensingModule__DisputedIpId()"); + }); + + step("Commerical remix PIL", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("A", ipIdC, [licenseTokenId3], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted.", "Error: LicensingModule__DisputedIpId()"); + }); + }); + }); + + describe("Register Derivative IP Asset with License Tokens and Royalty Related Process", async function () { + let snapshotId1: bigint; + const payAmount: string = "100"; + + before("Resolve dispute for the derivative IP", async function () { + const responseResolveDispute = await expect( + resolveDispute("B", disputeId3, "0x0000", false) + ).to.not.be.rejected; + + expect(responseResolveDispute.txHash).to.be.a("string").and.not.empty; + await sleep(10); + }) + + step("Register derivative with license tokens attached commercial remix PIL", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("A", ipIdC, [licenseTokenId3], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Raise dispute for the parent IP and set dispute judgement", async function () { + const responseRaiseDispute = await expect( + raiseDispute("A", ipIdB, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId2 = responseRaiseDispute.disputeId; + + await setDisputeJudgement(privateKeyC, disputeId2, true, "0x"); + }); + + step("Pay royalty on behalf, parent IP is DISPUTED", async function () { + const response = await expect( + payRoyaltyOnBehalf("A", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: The contract function \"payRoyaltyOnBehalf\" reverted.", "Error: RoyaltyModule__IpIsTagged()"); + }); + + step("Pay royalty on behalf, derivative IP is DISPUTED", async function () { + const responseResolveDispute = await expect( + resolveDispute("A", disputeId2, "0x0000", false) + ).to.not.be.rejected; + + expect(responseResolveDispute.txHash).to.be.a("string").and.not.empty; + + const responseRaiseDispute = await expect( + raiseDispute("B", ipIdC, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId3 = responseRaiseDispute.disputeId; + + await setDisputeJudgement(privateKeyC, disputeId3, true, "0x"); + + const response = await expect( + payRoyaltyOnBehalf("B", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: The contract function \"payRoyaltyOnBehalf\" reverted.", "Error: RoyaltyModule__IpIsTagged()"); + }); + + step("Pay royalty on behalf", async function () { + const responseResolveDispute = await expect( + resolveDispute("B", disputeId3, "0x0000", false) + ).to.not.be.rejected; + + expect(responseResolveDispute.txHash).to.be.a("string").and.not.empty; + await sleep(10); + + const response = await expect( + payRoyaltyOnBehalf("B", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Raise dispute for the parent IP and set dispute judgement", async function () { + const responseRaiseDispute = await expect( + raiseDispute("A", ipIdB, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) + ).to.not.be.rejected; + + expect(responseRaiseDispute.txHash).to.be.a("string").and.not.empty; + expect(responseRaiseDispute.disputeId).to.be.a("bigint").and.to.be.ok; + + disputeId2 = responseRaiseDispute.disputeId; + + await setDisputeJudgement(privateKeyC, disputeId2, true, "0x"); + }); + + step("Collect royalty tokens", async function () { + const response = await expect( + collectRoyaltyTokens("B", ipIdB, ipIdC, waitForTransaction) + ).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 * 1000000)); + }); + + step("Captue snapshot", async function () { + const response = await expect( + royaltySnapshot("B", ipIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + + snapshotId1 = response.snapshotId; + }); + + // IP asset is disputed, the cliaimable revenue should be 0 + step("Check claimable revenue", async function () { + const response = await expect( + royaltyClaimableRevenue("B", ipIdB, ipIdB, BigInt(snapshotId1), mintingFeeTokenAddress, waitForTransaction) + ).to.not.be.rejected; + + expect(response).to.be.a("bigint").and.be.equal(0n); + }); + + // IP asset is disputed, the cliaimable revenue should be 0 + step("Claim royalty tokens", async function () { + const response = await expect( + royaltyClaimRevenue("B", [snapshotId1], ipIdB, mintingFeeTokenAddress, ipIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.claimableToken).to.be.a("bigint").and.be.equal(0n); + }); + }); + }); +}); + + diff --git a/test/e2e/licenseTerms.nonComPIL.test.ts b/test/e2e/licenseTerms.nonComPIL.test.ts new file mode 100644 index 0000000..8590026 --- /dev/null +++ b/test/e2e/licenseTerms.nonComPIL.test.ts @@ -0,0 +1,197 @@ +import { privateKeyA, nftContractAddress, accountA, accountB, privateKeyB } from '../../config/config'; +import { attachLicenseTerms, mintLicenseTokens, registerDerivativeIp, registerDerivativeWithLicenseTokens, registerIpAsset } from '../../utils/sdkUtils'; +import { getLicenseTokenOwner, mintNFTWithRetry, transferLicenseToken } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address } from 'viem'; + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Address; +let ipIdB: Address; +let licenseTermsId1: bigint; +let licenseTokenId1: bigint; + +describe('SDK E2E Test', function () { + describe(`Non-Commercial Social Remixing PIL: "transferable":false, "derivativesAllowed":false`, async function () { + licenseTermsId1 = 0n; + + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).to.be.a("string").and.not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, 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; + + ipIdA = response.ipId; + }); + + step("Wallet A attach the non-commercial social remixing PIL(licenseTermsId:0 - transferable:false) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, 0n, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.a("boolean").and.to.be.true; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenId1)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, 0n, 1, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenId1 = response.licenseTokenIds[0]; + }); + + step(`"transferable":false, 1 - check the owner of licenseTokenId1`, async function () { + const response = await expect( + getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.to.be.equal(accountB.address); + }); + + // ipAccountExecute to call licenseToken.transferFrom + // 0xd175f85c - LicenseToken__NotTransferable() + step(`"transferable":false, 2 - WalletB cannot transfer licenseTokenId to WalletA as LicenseToken__NotTransferable()`, async function () { + const errorMessage = `The contract function "transferFrom" reverted with the following signature:`; + const errorCode = `0xd175f85c`; + await expect( + transferLicenseToken(privateKeyB, accountB.address, accountA.address, Number(licenseTokenId1)) + ).to.be.rejectedWith(errorMessage, errorCode); + console.log(`${errorMessage} ${errorCode}`); + }); + + step(`"transferable":false, 3 - check the owner of licenseTokenId1 again`, async function () { + const owner = await expect( + getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(owner).to.be.a("string").and.to.be.equal(accountB.address); + }); + + step(`"derivativesAllowed":false, cannot register an IP asset as licenseTokenId1's derivative as LicenseTokenNotCompatibleForDerivative`, async function () { + const errorMessage = `Failed to register derivative with license tokens: The contract function "registerDerivativeWithLicenseTokens" reverted.`; + const errorReason = `Error: LicensingModule__LicenseTokenNotCompatibleForDerivative(address childIpId, uint256[] licenseTokenIds)`; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).to.be.a("string").and.not.empty; + + const responseRegisterIpAsset = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, true) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpAsset.ipId; + + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenId1], true) + ).to.be.rejectedWith(errorMessage, errorReason); + console.log(`${errorMessage} ${errorReason}`); + }); + }); + + describe(`Non-Commercial Social Remixing PIL: "transferable":true, "derivativesAllowed":true, "derivativesReciprocal":true`, async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).to.be.a("string").and.not.empty; + }); + + step(`Wallet A register an IP Asset and default attach the non-commercial remixing PIL(licenseTermsId:2 - "transferable":true"), get an ipId (ipIdA) and a licenseTermsId (licenseTermsId1)`, async function () { + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + licenseTermsId1 = 2n; + }); + + step("Wallet A attach another non-commercial social remixing PIL(licenseTermsId:0) to ipIdA", async function () { + const responseAttachLicenseTerms = await expect( + attachLicenseTerms("A", ipIdA, 0n, true) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + expect(responseAttachLicenseTerms.success).to.be.a("boolean").and.to.be.true; + }); + + step(`Wallet A mint a license token with ipIdA and licenseTermsId1, get a licenseTokenId (licenseTokenId1)`, async function () { + const responseMintLicenseTokens = await expect( + mintLicenseTokens("A", ipIdA, licenseTermsId1, 1, accountA.address, true) + ).to.not.be.rejected; + + expect(responseMintLicenseTokens.txHash).to.be.a("string").and.not.empty; + expect(responseMintLicenseTokens.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenId1 = responseMintLicenseTokens.licenseTokenIds[0]; + }); + + step(`"derivativesAllowed":true & "derivativesReciprocal":true, only can register a derivative with the same license terms as parent IP`, async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).to.be.a("string").and.not.empty; + + const response = await expect( + registerDerivativeIp("B", nftContractAddress, tokenIdB, [ipIdA], [licenseTermsId1], 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; + + ipIdB = response.ipId; + }); + + // 0x1ae3058f LicensingModule__DerivativesCannotAddLicenseTerms() + step(`"derivativesReciprocal":true, derivative IP cannot add additional license terms`, async function () { + const errorMessage = `The contract function "attachLicenseTerms" reverted with the following signature:`; + const errorCode = `0x1ae3058f`; + + await expect( + attachLicenseTerms("B", ipIdB, 0n,true) + ).to.be.rejectedWith( + `Failed to attach license terms: The contract function "attachLicenseTerms" reverted with the following signature:`, + `0x1ae3058f` + ); + + console.log(`${errorMessage} ${errorCode}`); + }); + + step(`"transferable":true, 1 - check the owner of licenseTokenId1`, async function () { + const response = await expect(getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.to.be.equal(accountA.address); + }); + + step(`"transferable":true, 2 - wallet A can transfer the licenseTokenId to Wallet B`, async function () { + const response = await expect( + transferLicenseToken(privateKeyA, accountA.address, accountB.address, Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.not.empty; + }); + + step(`"transferable":true, 3 - check the owner of licenseTokenId1 again`, async function () { + const response = await expect(getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.to.be.equal(accountB.address); + }); + }); +}); diff --git a/test/e2e/multiLIcenseTerms.test.ts b/test/e2e/multiLIcenseTerms.test.ts new file mode 100644 index 0000000..1aaab35 --- /dev/null +++ b/test/e2e/multiLIcenseTerms.test.ts @@ -0,0 +1,277 @@ +import { privateKeyA, privateKeyB, nftContractAddress } from '../../config/config'; +import { mintNFTWithRetry } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, registerDerivative } from '../../utils/sdkUtils'; +import { expect } from 'chai'; + +import '../setup'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Hex } from 'viem'; +import { nonComLicenseTermsId, comUseLicenseTermsId1, comUseLicenseTermsId2, comRemixLicenseTermsId1, comRemixLicenseTermsId2 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Hex; +let ipIdB: Hex; +let ipIdC: Hex; + +const waitForTransaction: boolean = true; + +describe("SDK E2E Test - Register Derivative IP Asset with multiple PILs", function () { + describe("@smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1 (commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A attach comUseLicenseTermsId2 (commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can use comUseLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + expect(tokenIdC).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT use comRemixLicenseTermsId1 to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: License terms id " + comRemixLicenseTermsId1 + " must be attached to the parent ipId " + ipIdA + " before registering derivative."); + }); + + step("Wallet B can use comUseLicenseTermsId1 and comUseLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA, ipIdA], [comUseLicenseTermsId1, comUseLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("[smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A attach comRemixLicenseTermsId2(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can use comRemixLicenseTermsId2 to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + expect(tokenIdC).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT use nonComLicenseTermsId to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA], [0n], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: License terms id 0 must be attached to the parent ipId " + ipIdA + " before registering derivative."); + }); + + step("Wallet B can use comRemixLicenseTermsId1 and comRemixLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA, ipIdA], [comRemixLicenseTermsId1, comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comUseLicenseTermsId1, comRemixLicenseTermsId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); + }); + + step("Wallet B can NOT use comUseLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comUseLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); + }); + + step("Wallet B can NOT use comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comRemixLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); + }); + + step("Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA, ipIdA], [comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); + }); + }); +}); \ No newline at end of file diff --git a/test/e2e/royalty.comRemixPIL.test.ts b/test/e2e/royalty.comRemixPIL.test.ts new file mode 100644 index 0000000..125d45c --- /dev/null +++ b/test/e2e/royalty.comRemixPIL.test.ts @@ -0,0 +1,533 @@ +import { privateKeyA, privateKeyB, privateKeyC, mintingFeeTokenAddress, accountA, accountB, accountC } from '../../config/config'; +import { getTotalRTSupply} from '../../utils/utils'; +import { payRoyaltyOnBehalf, registerCommercialRemixPIL } from '../../utils/sdkUtils'; +import { mintNFTCreateRootIPandAttachPIL, mintNFTAndRegisterDerivative, checkRoyaltyTokensCollected, getSnapshotId,checkClaimableRevenue, claimRevenueByIPA, claimRevenueByEOA, transferTokenToEOA } from '../testUtils'; + +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import { Address } from 'viem'; +import '../setup'; + +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; +let ipIdD: Address; +let snapshotId1_ipIdA: bigint; +let snapshotId1_ipIdB: bigint; +let snapshotId1_ipIdC: bigint; +let snapshotId1_ipIdD: bigint; +let TOTAL_RT_SUPPLY: number; + +describe("SDK E2E Test - Royalty", function () { + this.beforeAll("Get total RT supply", async function (){ + TOTAL_RT_SUPPLY = await getTotalRTSupply(); + console.log("TOTAL_RT_SUPPLY: " + TOTAL_RT_SUPPLY); + }); + + describe("Commercial Remix PIL - Claim Minting Fee by IPA account", function () { + const mintingFee: string = "100"; + const commercialRevShare: number = 0.5; + before("Register parent and derivative IP Assets", async function () { + // Register commercial use PIL + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(TOTAL_RT_SUPPLY * (commercialRevShare/100))); + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, 0n); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, BigInt(mintingFee)); + }); + + step("idIdA claim revenue from vaultIpIdA (minting fee)", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, BigInt(mintingFee)); + }); + + step("Check claimable revenue again", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, 0n); + }); + }); + + describe('Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account', async function () { + const mintingFee = "600"; + const payAmount = 100; + const commercialRevShare = 10; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, expectedRoyaltyTokensCollected); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, expectedRoyaltyTokensCollected); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, expectedRoyaltyTokensCollected); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, expectedRoyaltyTokensCollected); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, expectedRoyaltyTokensCollected); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, expectedRoyaltyTokensCollected); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdD", async function () { + snapshotId1_ipIdD = await getSnapshotId("C", ipIdD); + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("Check claimable revenue A from D", async function () { + await checkClaimableRevenue("A", ipIdD, ipIdA, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue B from D", async function () { + await checkClaimableRevenue("B", ipIdD, ipIdB, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue C from D", async function () { + await checkClaimableRevenue("C", ipIdD, ipIdC, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue D from D", async function () { + await checkClaimableRevenue("C", ipIdD, ipIdD, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * ((100 - 2 * commercialRevShare) / 100)); + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue A from B", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee)) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from B", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee)) * ((100 - commercialRevShare) / 100)); + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, expectedClaimableRevenue); + }); + + step("Check claimable revenue A from A", async function () { + const expectedClaimableRevenue = BigInt(mintingFee); + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, expectedClaimableRevenue); + }); + + step("Claim revenue A from D", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdD], ipIdD, ipIdA, 0n); + }); + + step("Claim revenue B from D", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdD], ipIdD, ipIdB, 0n); + }); + + step("Claim revenue C from D", async function () { + await claimRevenueByIPA("C", [snapshotId1_ipIdD], ipIdD, ipIdC, 0n); + }); + + step("Claim revenue D from D", async function () { + await claimRevenueByIPA("C", [snapshotId1_ipIdD], ipIdD, ipIdD, 0n); + }); + + step("Claim revenue A from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await claimRevenueByIPA("A", [snapshotId1_ipIdC], ipIdC, ipIdA, expectedClaimableToken); + }); + + step("Claim revenue B from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await claimRevenueByIPA("B", [snapshotId1_ipIdC], ipIdC, ipIdB, expectedClaimableToken); + }); + + step("Claim revenue C from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * ((100 - commercialRevShare - commercialRevShare) / 100)); + await claimRevenueByIPA("C", [snapshotId1_ipIdC], ipIdC, ipIdC, expectedClaimableToken); + }); + + step("Claim revenue A from B", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee)) * commercialRevShare / 100); + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, expectedClaimableToken); + }); + + step("Claim revenue B from B", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee)) * ((100 - commercialRevShare) / 100)); + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, expectedClaimableToken); + }); + + step("Claim revenue A from A", async function () { + const expectedClaimableToken = BigInt(mintingFee); + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, expectedClaimableToken); + }); + }); + + describe("Commercial Remix PIL - Claim Minting Fee and Revenue by EOA", function () { + const mintingFee = "1000"; + const payAmount = 6000; + const commercialRevShare = 20; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("Transfer token to EOA - ipIdC", async function () { + await transferTokenToEOA("C", ipIdC, accountC.address, BigInt(60 * 10 ** 6)); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, 0n); + }); + + step("Claim revenue by EOA A from C", async function () { + await claimRevenueByEOA("A", [snapshotId1_ipIdC], ipIdC, 0n); + }); + + step("Claim revenue by EOA B from C", async function () { + await claimRevenueByEOA("B", [snapshotId1_ipIdC], ipIdC, 0n); + }); + + step("Claim revenue by EOA C from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * ((100 - 2 * commercialRevShare) / 100)); + await claimRevenueByEOA("C", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + }); + + describe("Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1", function () { + const mintingFee = 600; + const payAmount = 2000; + const commercialRevShare = 10; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("Transfer token to EOA - ipIdC to ipIdA", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountA.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdB", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountB.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdC", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 2) + await transferTokenToEOA("C", ipIdC, accountC.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * (100 - 2 * commercialRevShare)/100 /4); + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Claim revenue by EOA A from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("A", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA B from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("B", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA C from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("C", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + }); + + describe("Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2", function () { + const mintingFee = 600; + const payAmount = 2000; + const commercialRevShare = 10; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("Transfer token to EOA - ipIdC to ipIdA", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountA.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdB", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountB.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdC", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 2) + await transferTokenToEOA("C", ipIdC, accountC.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * (100 - 2 * commercialRevShare)/100 /4); + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Claim revenue by EOA A from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("A", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA B from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("B", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA C from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("C", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + }); +}); diff --git a/test/e2e/royalty.comUsePIL.test.ts b/test/e2e/royalty.comUsePIL.test.ts new file mode 100644 index 0000000..83f78f7 --- /dev/null +++ b/test/e2e/royalty.comUsePIL.test.ts @@ -0,0 +1,205 @@ +import { privateKeyA, privateKeyB, privateKeyC, mintingFeeTokenAddress, accountB, accountA } from '../../config/config'; +import { getTotalRTSupply} from '../../utils/utils'; +import { payRoyaltyOnBehalf, registerCommercialUsePIL } from '../../utils/sdkUtils'; +import { expect } from 'chai'; +import { mintNFTCreateRootIPandAttachPIL, mintNFTAndRegisterDerivative, checkRoyaltyTokensCollected, getSnapshotId,checkClaimableRevenue, claimRevenueByIPA, claimRevenueByEOA, transferTokenToEOA } from '../testUtils'; + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address } from 'viem'; +import { comUseLicenseTermsId1, mintingFee1 } from '../setup'; + +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; +let snapshotId1_ipIdA: bigint; +let snapshotId1_ipIdB: bigint; +let TOTAL_RT_SUPPLY: number; + +describe("SDK E2E Test - Royalty", function () { + this.beforeAll("Get total RT supply", async function (){ + TOTAL_RT_SUPPLY = await getTotalRTSupply(); + console.log("TOTAL_RT_SUPPLY: " + TOTAL_RT_SUPPLY); + }); + + describe("Commercial Use PIL - Claim Minting Fee by IPA account", function () { + before("Register parent and derivative IP assets", async function () { + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, comUseLicenseTermsId1); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [comUseLicenseTermsId1]); + }); + + step("ipIdA collect royalty tokens from ipIdB", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, 0n); + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, 0n); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, BigInt(mintingFee1)); + }); + + step("idIdA claim revenue from vaultIpIdA (minting fee)", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, BigInt(mintingFee1)); + }); + + step("Check claimable revenue again", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, 0n); + }); + }); + + describe('Commercial Use PIL - Claim Minting Fee and Revenue by IPA account', async function () { + const mintingFee: number = 180; + const payAmount: number = 1000000; + + before("Register parent and derivative IP assets", async function () { + // register commercial use PIL + const licenseTermsId = Number((await registerCommercialUsePIL("A", mintingFee, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + }); + + step("ipIdC pay royalty on behalf to ipIdB", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, BigInt(payAmount + mintingFee)); + }); + + step("ipIdB claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, BigInt(payAmount + mintingFee)); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, BigInt(mintingFee)); + }); + + step("ipIdA claim revenue from vaultIpIdA", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, BigInt(mintingFee)); + }); + }); + + describe('Commercial Use PIL - Claim Minting Fee and Revenue by EOA', async function () { + const mintingFee: number = 200; + const payAmount: number = 1000; + + before("Register parent and derivative IP assets", async function () { + // register commercial use PIL + const licenseTermsId = Number((await registerCommercialUsePIL("A", mintingFee, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + }); + + step("Transfer token to EOA - ipIdB", async function () { + await transferTokenToEOA("B", ipIdB, accountB.address, BigInt(100 * 10 ** 6)); + }); + + step("Transfer token to EOA - ipIdA", async function () { + await transferTokenToEOA("A", ipIdA, accountA.address, BigInt(100 * 10 ** 6)); + }); + + step("ipIdC pay royalty on behalf to ipIdB", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByEOA("A", [snapshotId1_ipIdB], ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB by IPA", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB by EOA", async function () { + await claimRevenueByEOA("B", [snapshotId1_ipIdB], ipIdB, BigInt(payAmount + mintingFee)); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdA by IPA", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdA by EOA", async function () { + await claimRevenueByEOA("A", [snapshotId1_ipIdA], ipIdA, BigInt(mintingFee)); + }); + }); +}); diff --git a/test/e2e/setPermissions.test.ts b/test/e2e/setPermissions.test.ts new file mode 100644 index 0000000..2ba6d93 --- /dev/null +++ b/test/e2e/setPermissions.test.ts @@ -0,0 +1,137 @@ +import { privateKeyA, accountB, licensingModuleAddress, nftContractAddress} from '../../config/config'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { registerIpAsset, setPermission, attachLicenseTerms } from '../../utils/sdkUtils'; +import { expect } from 'chai'; +import { Hex } from 'viem'; +import '../setup'; +import { comUseLicenseTermsId1 } from '../setup'; + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Hex; +let ipIdB: Hex; + +const waitForTransaction: boolean = true; + +describe('@smoke SDK E2E Test - Permissions', function () { + this.beforeAll("Wallet A register 2 license terms and 2 IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpA = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpA.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpA.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpA.ipId; + + tokenIdB = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdB); + + const responseRegisterIpB = await expect( + registerIpAsset("A", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpB.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpB.ipId; + }) + + describe("Set permission - 1 ALLOW", async function (){ + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B(non-owner) can NOT attach licenseTermsId 0 to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdA, 0n, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); + }); + + // wallet B is granted permission - 1 ALLOW for ipIdA + step("Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdA", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; + }); + + step("Wallet B can attach licenseTermsId 0 to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdA, 0n, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + // wallet B is not granted any permission for ipIdB + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B can NOT attach licenseTermsId 0 to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, 0n, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); + }); + }); + + describe("Set permission - 2 DENY", async function (){ + // change wallet B's permission to 2 DENY for ipIdA + step("Wallet A set permission (permission id: 2) to NOT allow Wallet B to call license Module for ipIdA", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; + }); + + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B can NOT attach licenseTermsId1 to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); + }); + }); + + describe("Set permission - 0 ABSTAIN", async function (){ + // wallet B is granted permission - 1 ALLOW for ipIdB + step("Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdB", async function () { + const response = await expect( + setPermission("A", ipIdB, accountB.address, licensingModuleAddress, 1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; + }); + + step("Wallet B can attach licenseTermsId 0 to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, 0n, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + // change wallet B's permission to 0 ABSTAIN for ipIdB + step("Wallet A set permission (permission id: 0) to NOT allow Wallet B to call license Module for ipIdB", async function () { + const response = await expect( + setPermission("A", ipIdB, accountB.address, licensingModuleAddress, 0, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; + }); + + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B can NOT attach licenseTermsId2 to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); + }); + }); +}); diff --git a/test/ipAccount/executeWithSig.test.ts b/test/ipAccount/executeWithSig.test.ts new file mode 100644 index 0000000..383c6bf --- /dev/null +++ b/test/ipAccount/executeWithSig.test.ts @@ -0,0 +1,77 @@ +import { privateKeyA, privateKeyB, clientA, accountA, chainId } from '../../config/config'; +import { getDeadline, getWalletClient } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address, Hex, encodeFunctionData, getAddress, toFunctionSelector } from 'viem'; +import { getPermissionSignature, AccessPermission } from '@story-protocol/core-sdk'; +import { mintNFTAndRegisterDerivative, mintNFTCreateRootIPandAttachPIL } from '../testUtils'; +import { comUseLicenseTermsId1 } from '../setup'; +import { accessControllerAbi } from '../../config/abi'; +import { ipAccountExecuteWithSig } from '../../utils/sdkUtils'; + +let ipIdA: Address; +let ipIdB: Address; +let signature: Hex; + +const coreMetadataModule = "0xDa498A3f7c8a88cb72201138C366bE3778dB9575" as Address; +const accessControllerAddress = "0xF9936a224b3Deb6f9A4645ccAfa66f7ECe83CF0A" as Address; +const deadline = getDeadline(60000n); +const walletClinet = getWalletClient(privateKeyA); + +describe('SDK Test', function () { + describe('Test ipAccount.executeWithSig Function', async function () { + before("Mint 3 NFTs to Wallet A", async function () { + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, comUseLicenseTermsId1); + + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [comUseLicenseTermsId1]); + + const state = await clientA.ipAccount.getIpAccountNonce(ipIdA); + const expectedState = state + 1n; + + signature = await getPermissionSignature({ + ipId: ipIdA, + wallet: walletClinet, + permissions: [ + { + ipId: ipIdA, + signer: accountA.address, + to: coreMetadataModule, + permission: AccessPermission.ALLOW, + func: "function setAll(address,string,bytes32,bytes32)", + }, + ], + nonce: expectedState, + + chainId: BigInt(chainId), + deadline: deadline, + }); + }); + + it("ipAccount execute with siganature", async function () { + console.log("ipIdA: " + ipIdA); + + const data = encodeFunctionData({ + abi: accessControllerAbi, + functionName: "setPermission", + args: [ + getAddress(ipIdA), + getAddress(accountA.address), + getAddress(coreMetadataModule), + toFunctionSelector("function setAll(address,string,bytes32,bytes32)"), + AccessPermission.ALLOW, + ], + }); + + const response = await ipAccountExecuteWithSig("A", ipIdA, accessControllerAddress, 0, data, accountA.address, deadline, signature, true); + + console.log(response); + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); +}); diff --git a/test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts b/test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts new file mode 100644 index 0000000..38fce32 --- /dev/null +++ b/test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts @@ -0,0 +1,158 @@ +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: request.nftContract address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + 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: request.nftContract address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + 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: request.recipient address is invalid: 0x000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + 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.COMMERCIAL_USE, false, undefined, undefined, undefined, undefined, "100", undefined, mintingFeeTokenAddress) + ).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 id 2", async function () { + const response = await expect( + mintAndRegisterIpAssetWithPilTerms("A", 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 with the following signature:`, `0x55d48f8d`); + }); + + 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 id 2 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.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: The contract function "mintAndRegisterIpAndAttachPILTerms" reverted with the following signature:`, `0x55d48f8d`); + }); + + 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; + }); + }); +}); diff --git a/test/ipAsset/register.test.ts b/test/ipAsset/register.test.ts new file mode 100644 index 0000000..bbaf401 --- /dev/null +++ b/test/ipAsset/register.test.ts @@ -0,0 +1,97 @@ +import { privateKeyA, privateKeyB, privateKeyC, nftContractAddress } from '../../config/config'; +import { registerIpAsset } from '../../utils/sdkUtils'; +import { checkMintResult, isRegistered, mintNFTWithRetry } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address } from 'viem'; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Address; + +describe('SDK Test', function () { + describe('Test ipAsset.register Function', async function () { + before("Mint 3 NFTs to Wallet A", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + }); + + // 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 "registerIp" reverted with the following signature:`, "0x1033cd88"); + }); + + it("Register an IP asset fail as invalid NFT contract address", async function () { + await expect( + registerIpAsset("A", "0x000000", tokenIdA, true) + ).to.be.rejectedWith(`Failed to register IP: nftContract address is invalid: 0x000000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register an IP asset fail as invalid tokenId", async function () { + await expect( + registerIpAsset("A", nftContractAddress, "tokenid", true) + ).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 "registerIp" reverted with the following signature:`, "0x7e273289"); + }); + + it("Owner can register an IP asset", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, 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; + + 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 () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(response.txHash).not.to.be.exist; + expect(response.ipId).to.be.a("string").and.not.empty; + 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.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 () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.empty; + expect(response.ipId).not.to.be.exist; + }); + }); +}); diff --git a/test/ipAsset/registerDerivative.test.ts b/test/ipAsset/registerDerivative.test.ts new file mode 100644 index 0000000..6179e1d --- /dev/null +++ b/test/ipAsset/registerDerivative.test.ts @@ -0,0 +1,160 @@ +import { privateKeyA, privateKeyB, nftContractAddress } from '../../config/config'; +import { attachLicenseTerms, registerDerivative, registerIpAsset } from '../../utils/sdkUtils'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address } from 'viem'; +import { nonComLicenseTermsId, comUseLicenseTermsId1 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Address; +let ipIdB: Address; + +describe('SDK Test', function () { + describe('Test ipAsset.registerDerivative Function', async function () { + before("Register license terms, mint NFTs and register IP assets",async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + expect(tokenIdA).not.empty; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + expect(tokenIdB).not.empty; + + const responseRegisterIpA = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(responseRegisterIpA.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpA.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpA.ipId; + + const responseRegisterIpB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, true) + ).to.not.be.rejected; + + expect(responseRegisterIpB.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpB.ipId; + }); + + it("Register a derivative IP asset fail as no license terms attached", async function () { + await expect( + registerDerivative("C", ipIdB, [ipIdA], [0n], true) + ).to.be.rejectedWith("Failed to register derivative: License terms id 0 must be attached to the parent ipId " + ipIdA + " before registering derivative."); + }); + + it("Register a derivative IP asset fail as no license terms attached", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, 0n, true) + ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + + await expect( + registerDerivative("C", ipIdB, [ipIdA], [0n], true) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted with the following signature:", "0xb3e96921"); + }); + + it("Register a derivative IP asset fail as undefined child ipId", async function () { + let ipIdB: any; + await expect( + registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative: ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as invalid child ipId", async function () { + await expect( + registerDerivative("B", "0x0000", [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative: ipId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as non-existent child ipId", async function () { + await expect( + registerDerivative("B", "0x485FCfC79Ce0A082Ab2a5e729D6e6255A540342a", [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative: The child IP with id 0x485FCfC79Ce0A082Ab2a5e729D6e6255A540342a is not registered."); + }); + + it("Register a derivative IP asset fail as undefined parent ipId", async function () { + let ipIdA: any; + await expect( + registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative: request.parentIpIds address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as invalid parent ipId", async function () { + await expect( + registerDerivative("B", ipIdB, ["0x0000"], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative: request.parentIpIds address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as non-existent parent ipId", async function () { + await expect( + registerDerivative("B", ipIdB, ["0x485FCfC79Ce0A082Ab2a5e729D6e6255A540342a"], [nonComLicenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative: The parent IP with id 0x485FCfC79Ce0A082Ab2a5e729D6e6255A540342a is not registered."); + }); + + it("Register a derivative IP asset fail as undefined licenseTermsId", async function () { + let nonComLicenseTermsId: any; + await expect( + registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative: Cannot convert undefined to a BigInt"); + }); + + it("Register a derivative IP asset fail as invalid licenseTermsId", async function () { + await expect( + registerDerivative("B", ipIdB, [ipIdA], ["test"], true) + ).to.be.rejectedWith("Failed to register derivative: Cannot convert test to a BigInt"); + }); + + it("Register a derivative IP asset fail as non-existent licenseTermsId", async function () { + await expect( + registerDerivative("B", ipIdB, [ipIdA], ["999"], true) + ).to.be.rejectedWith("Failed to register derivative: License terms id 999 must be attached to the parent ipId " + ipIdA + " before registering derivative."); + }); + + it("Register a derivative IP asset fail as parent id and licenseTermsId not in pairs", async function () { + const response= await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + + await expect( + registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId, comUseLicenseTermsId1], true) + ).to.be.rejectedWith("Failed to register derivative: Parent IP IDs and License terms IDs must be provided in pairs."); + }); + + it("Register a derivative IP asset fail as LicenseNotCompatibleForDerivative", async function () { + await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA], [nonComLicenseTermsId, comUseLicenseTermsId1], true) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative(address childIpId)"); + }); + + it("Register a derivative IP asset success", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Register a derivative IP asset fail as DerivativeIpAlreadyHasLicense", async function () { + await expect( + registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], true) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted with the following signature:", "0x650aa4f5"); + }); + + it("Register a derivative IP asset that is already registered with same parent ipId and licenseTermsId", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted with the following signature:", "0x650aa4f5"); + }); + }); +}); diff --git a/test/ipAsset/registerDerivativeIp.test.ts b/test/ipAsset/registerDerivativeIp.test.ts new file mode 100644 index 0000000..40ae25c --- /dev/null +++ b/test/ipAsset/registerDerivativeIp.test.ts @@ -0,0 +1,220 @@ +import { privateKeyA, nftContractAddress } from '../../config/config'; +import { attachLicenseTerms, registerDerivativeIp, registerIpAsset, createNFTCollection } from '../../utils/sdkUtils'; +import { checkMintResult, getBlockTimestamp, mintNFTWithRetry } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address, toHex } from 'viem'; +import { comRemixLicenseTermsId1, nonComLicenseTermsId } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Address; +let nftCollectionAddress: Address; +const metadataURI = "http://example.com/metadata/12345"; + +describe('SDK Test', function () { + describe('Test ipAsset.registerDerivativeIp Function', async function () { + before("Mint NFT, register IP assets and attach license terms",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; + + tokenIdA = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdA); + + tokenIdB = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdB); + + const responseRegisterIpA = await expect( + registerIpAsset("A", nftCollectionAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(responseRegisterIpA.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpA.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpA.ipId; + + const attachLicenseTermsResponse = await expect( + attachLicenseTerms("A", ipIdA, 0n, true) + ).to.not.be.rejected; + + expect(attachLicenseTermsResponse.txHash).to.be.a("string").and.not.empty; + }); + + it("Register a derivative IP asset fail as undefined NFT contract address", async function () { + let nftContractAddress: any; + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: nftContract address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as invalid NFT contract address", async function () { + await expect( + registerDerivativeIp("A", "0x0000", tokenIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: nftContract address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + // 0x1033cd88: IPAssetRegistry__UnsupportedIERC721(address) + it("Register a derivative IP asset fail as non-existent NFT contract address", async function () { + await expect( + registerDerivativeIp("A", "0x121022F354787754f39f55b9795178dA291348Ba", tokenIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: The contract function "registerIpAndMakeDerivative" reverted with the following signature:`, `0x1033cd88`); + }); + + it("Register a derivative IP asset fail as undefined tokenId", async function () { + let tokenId: any; + await expect( + registerDerivativeIp("A", nftContractAddress, tokenId, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative IP: Cannot convert undefined to a BigInt"); + }); + + it("Register a derivative IP asset fail as invalid tokenId", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, "test", [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative IP: Cannot convert test to a BigInt"); + }); + + it("Register a derivative IP asset fail as non-existent tokenId", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, "999999999999", [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: The contract function "registerIpAndMakeDerivative" reverted with the following signature:`, `0x1033cd88`); + }); + + it("Register a derivative IP asset fail as undefined ipId", async function () { + let ipId: any; + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipId], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: request.derivData.parentIpIds address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as invalid ipId", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, ["0x0000"], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: request.derivData.parentIpIds address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as undefined licenseTermsId", async function () { + let licenseTermsId: any; + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [licenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative IP: Cannot convert undefined to a BigInt"); + }); + + it("Register a derivative IP asset fail as invalid licenseTermsId", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], ["test"], true) + ).to.be.rejectedWith("Failed to register derivative IP: Cannot convert test to a BigInt"); + }); + + it("Register a derivative IP asset fail as unattached licenseTermsId", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [comRemixLicenseTermsId1], true) + ).to.be.rejectedWith(`Failed to register derivative IP: License terms id ${comRemixLicenseTermsId1} must be attached to the parent ipId ${ipIdA} before registering derivative.`); + }); + + it("Register a derivative IP asset fail as parent id and licenseTermsId not in pairs", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA, ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith("Failed to register derivative IP: Parent IP IDs and License terms IDs must be provided in pairs."); + }); + + it("Register a derivative IP asset fail as invalid licenseTemplate", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true, "0x0000") + ).to.be.rejectedWith(`Failed to register derivative IP: request.derivData.licenseTemplate address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as invalid metadataHash", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true, undefined, metadataURI, "0x0000") + ).to.be.rejectedWith(`Failed to register derivative IP: Size of bytes "0x0000" (bytes2) does not match expected size (bytes32).`); + }); + + it("Register a derivative IP asset fail as invalid nftMetadataHash", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true, undefined, metadataURI, undefined, "0x0000") + ).to.be.rejectedWith(`Failed to register derivative IP: Size of bytes "0x0000" (bytes2) does not match expected size (bytes32).`); + }); + + it("Register a derivative IP asset fail as invalid deadline", async function () { + await expect( + registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true, undefined, metadataURI, undefined, undefined, "test") + ).to.be.rejectedWith(`Failed to register derivative IP: Invalid deadline value.`); + }); + + it("Register a derivative IP asset success", async function () { + const response = await expect( + registerDerivativeIp("A", nftCollectionAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], 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; + }); + + it("Register a derivative IP asset with undefined waitForTransaction", async function () { + let waitForTransaction: any; + const tokenIdC = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdC); + + const response = await expect( + registerDerivativeIp("A", nftCollectionAddress, tokenIdC, [ipIdA], [nonComLicenseTermsId], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.not.be.exist; + }); + + it("Register a derivative IP asset with waitForTransaction: false", async function () { + const tokenIdC = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + expect(tokenIdC).to.be.a("string").and.not.empty; + + const response = await expect( + registerDerivativeIp("A", nftCollectionAddress, tokenIdC, [ipIdA], [nonComLicenseTermsId], false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.not.be.exist; + }); + + it("Register a derivative IP asset fail as already registered", async function () { + await expect( + registerDerivativeIp("A", nftCollectionAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: The NFT with id ${tokenIdB} is already registered as IP.`); + }); + + // 0xb3e96921 - AccessController__PermissionDenied(address,address,address,bytes4) + it("Non-owner register a derivative IP asset fail", async function () { + const tokenIdC = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + expect(tokenIdC).to.be.a("string").and.not.empty; + + await expect( + registerDerivativeIp("B", nftCollectionAddress, tokenIdC, [ipIdA], [nonComLicenseTermsId], true) + ).to.be.rejectedWith(`Failed to register derivative IP: The contract function "registerIpAndMakeDerivative" reverted with the following signature:`, `0xb3e96921`); + }); + + it("Register a derivative IP asset with all optional parameters", async function () { + const licenseTemplate = "0x260B6CB6284c89dbE660c0004233f7bB99B5edE7"; + const metadataHash = toHex("test-metadata-hash", { size: 32 }); + const nftMetadataHash = toHex("test-nft-metadata-hash", { size: 32 }); + const deadline = await(getBlockTimestamp()) + 1000n; + + const tokenIdC = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + expect(tokenIdC).to.be.a("string").and.not.empty; + + const response = await expect( + registerDerivativeIp("A", nftCollectionAddress, tokenIdC, [ipIdA], [nonComLicenseTermsId], true, licenseTemplate, metadataURI, metadataHash, nftMetadataHash, deadline) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + }); + }); +}); diff --git a/test/ipAsset/registerDerivativeWithLicenseTokens.test.ts b/test/ipAsset/registerDerivativeWithLicenseTokens.test.ts new file mode 100644 index 0000000..1e4dd16 --- /dev/null +++ b/test/ipAsset/registerDerivativeWithLicenseTokens.test.ts @@ -0,0 +1,203 @@ +import { privateKeyA, privateKeyB, privateKeyC, accountB, accountC, nftContractAddress } from '../../config/config'; +import { attachLicenseTerms, registerDerivativeWithLicenseTokens, registerIpAsset, mintLicenseTokens } from '../../utils/sdkUtils'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { nonComLicenseTermsId, comUseLicenseTermsId1, comUseLicenseTermsId2 } from '../setup'; +import { Address } from 'viem'; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; +let licenseTokenIdA: bigint; +let licenseTokenIdB: bigint; +let licenseTokenIdC: bigint; +let licenseTokenIdD: bigint; + +describe('SDK Test', function () { + describe('Test ipAsset.registerDerivativeWithLicenseTokens Function', async function () { + before("Register license terms, register IP assets and mint license tokens",async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + + const responseRegisterIpA = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(responseRegisterIpA.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpA.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpA.ipId; + + const responseRegisterIpB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, true) + ).to.not.be.rejected; + + expect(responseRegisterIpB.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpB.ipId; + + const responseRegisterIpC = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, true) + ).to.not.be.rejected; + + expect(responseRegisterIpC.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpC.ipId).to.be.a("string").and.not.empty; + + ipIdC = responseRegisterIpC.ipId; + + const responsemintLicenseTokenA = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, true) + ).to.not.be.rejected; + + expect(responsemintLicenseTokenA.txHash).to.be.a("string").and.not.empty; + expect(responsemintLicenseTokenA.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = responsemintLicenseTokenA.licenseTokenIds[0]; + + const responseAttachLicenseTerms2 = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, true) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms2.txHash).to.be.a("string").and.not.empty; + + const responsemintLicenseTokenB = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, true) + ).to.not.be.rejected; + + expect(responsemintLicenseTokenB.txHash).to.be.a("string").and.not.empty; + expect(responsemintLicenseTokenB.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = responsemintLicenseTokenB.licenseTokenIds[0]; + + const responsemintLicenseTokenC = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountC.address, true) + ).to.not.be.rejected; + + expect(responsemintLicenseTokenC.txHash).to.be.a("string").and.not.empty; + expect(responsemintLicenseTokenC.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdC = responsemintLicenseTokenC.licenseTokenIds[0]; + + const responseAttachLicenseTerms3 = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId2, true) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms3.txHash).to.be.a("string").and.not.empty; + + const responsemintLicenseTokenD = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId2, 2, accountC.address, true) + ).to.not.be.rejected; + + expect(responsemintLicenseTokenD.txHash).to.be.a("string").and.not.empty; + expect(responsemintLicenseTokenD.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdD = responsemintLicenseTokenD.licenseTokenIds[0]; + }); + + it("Register a derivative IP asset fail as non-owner", async function () { + await expect( + registerDerivativeWithLicenseTokens("C", ipIdB, [licenseTokenIdA], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0xb3e96921"); + }); + + it("Register a derivative IP asset fail as undefined child ipId", async function () { + let ipIdB: any; + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], true) + ).to.be.rejectedWith(`Failed to register derivative with license tokens: ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as invalid child ipId", async function () { + await expect( + registerDerivativeWithLicenseTokens("B", "0x0000", [licenseTokenIdA], true) + ).to.be.rejectedWith(`Failed to register derivative with license tokens: ipId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register a derivative IP asset fail as non-existent child ipId", async function () { + await expect( + registerDerivativeWithLicenseTokens("B", "0x485FCfC79Ce0A082Ab2a5e729D6e6255A540342a", [licenseTokenIdA], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The child IP with id 0x485FCfC79Ce0A082Ab2a5e729D6e6255A540342a is not registered."); + }); + + it("Register a derivative IP asset fail as undefined licenseTokenId", async function () { + let licenseTokenIdA: any; + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: Cannot convert undefined to a BigInt"); + }); + + it("Register a derivative IP asset fail as invalid licenseTokenId", async function () { + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, ["test"], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: Cannot convert test to a BigInt"); + }); + + // 0xd474000f - LicenseToken__NotLicenseTokenOwner(uint256,address,address) + it("Register a derivative IP asset fail as non-existent licenseTokenId", async function () { + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, ["999"], true) + ).to.be.rejectedWith(`Failed to register derivative with license tokens: The contract function "registerDerivativeWithLicenseTokens" reverted with the following signature:`, `0xd474000f`); + }); + + it("Register a derivative IP asset fail as LicenseTokenNotCompatibleForDerivative", async function () { + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA, licenseTokenIdB], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted.", + "Error: LicensingModule__LicenseTokenNotCompatibleForDerivative"); + }); + + it("Register a derivative IP asset with one license token", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Register a derivative IP asset fail as already registered with the license token", async function () { + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + + it("Register a derivative IP asset fail as already registered with one of the license tokens", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA, licenseTokenIdB], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + + it("Register a derivative IP asset fail as NotLicenseTokenOwner for one of the license tokens", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdB, licenseTokenIdC], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); + }); + + it("Register a derivative IP asset fail as NotLicenseTokenOwner for all license tokens", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdC, licenseTokenIdD], true) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); + }); + + it("Register a derivative IP asset with multiple license tokens", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdC, licenseTokenIdD], true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); +}); diff --git a/test/ipAsset/registerIpAndAttachPilTerms.test.ts b/test/ipAsset/registerIpAndAttachPilTerms.test.ts new file mode 100644 index 0000000..3c42fd1 --- /dev/null +++ b/test/ipAsset/registerIpAndAttachPilTerms.test.ts @@ -0,0 +1,189 @@ +import { privateKeyA, mintingFeeTokenAddress } from '../../config/config'; +import { createNFTCollection, registerIpAndAttachPilTerms } from '../../utils/sdkUtils'; +import { checkMintResult, getBlockTimestamp, mintNFTWithRetry } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address, 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: Address; +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; + +describe('SDK Test', function () { + describe('Test ipAsset.registerIpAndAttachPilTerms Function', async function () { + before("Mint NFT, register IP assets and attach license terms",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; + + tokenIdA = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdA); + + tokenIdB = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdB); + + tokenIdC = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdC); + }); + + it("Register IP and attach PilTerms fail as undefined NFT contract address", async function () { + let nftContractAddress: any; + await expect( + registerIpAndAttachPilTerms("A", nftContractAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: nftContract address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Register IP and attach PilTerms fail as invalid NFT contract address", async function () { + await expect( + registerIpAndAttachPilTerms("A", "0x0000", tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: nftContract address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + // 0x1033cd88: IPAssetRegistry__UnsupportedIERC721(address) + it("Register IP and attach PilTerms fail as non-existent NFT contract address", async function () { + await expect( + registerIpAndAttachPilTerms("A", "0x121022F354787754f39f55b9795178dA291348Ba", tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: The contract function "registerIpAndAttachPILTerms" reverted with the following signature:`, `0x1033cd88`); + }); + + it("Register IP and attach PilTerms fail as undefined tokenId", async function () { + let tokenId: any; + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenId, PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.be.rejectedWith("Failed to register IP and attach PIL terms: Cannot convert undefined to a BigInt"); + }); + + it("Register IP and attach PilTerms fail as invalid tokenId", async function () { + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, "test", PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.be.rejectedWith("Failed to register IP and attach PIL terms: Cannot convert test to a BigInt"); + }); + + // 0x7e273289 - ERC721NonexistentToken(uint256) + it("Register IP and attach PilTerms fail as non-existent tokenId", async function () { + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, "999999999999", PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: The contract function "registerIpAndAttachPILTerms" reverted with the following signature:`, `0x7e273289`); + }); + + it("Register IP and attach PilTerms fail as undefined pilType", async function () { + let pilType: any; + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdA, pilType, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: PIL type is required.`); + }); + + it("Register IP and attach PilTerms fail as invalid metadataHash", async function () { + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, "0x0000") + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: Size of bytes "0x0000" (bytes2) does not match expected size (bytes32).`); + }); + + it("Register IP and attach PilTerms fail as invalid nftMetadataHash", async function () { + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, metadataHash, "0x0000") + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: Size of bytes "0x0000" (bytes2) does not match expected size (bytes32).`); + }); + + it("Register IP and attach PilTerms fail as invalid deadline", async function () { + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, metadataHash, nftMetadataHash, "test") + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: Invalid deadline value.`); + }); + + // 0xb3e96921 - AccessController__PermissionDenied(address,address,address,bytes4) + it("Non-owner register IP and attach PilTerms fail", async function () { + await expect( + registerIpAndAttachPilTerms("B", nftCollectionAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, metadataHash, nftMetadataHash, 1000n, "100", 20, mintingFeeTokenAddress) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: The contract function "registerIpAndAttachPILTerms" reverted with the following signature:`, `0xb3e96921`); + }); + + it("Register IP and attach COMMERCIAL_USE PilTerms fail as missing required parameters", async function () { + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdA, PIL_TYPE.COMMERCIAL_USE, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: mintingFee currency are required for commercial use PIL.`); + }); + + it("Register IP and attach COMMERCIAL_REMIX PilTerms fail as missing required parameters", async function () { + await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdA, PIL_TYPE.COMMERCIAL_REMIX, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: mintingFee, currency and commercialRevShare are required for commercial remix PIL.`); + }); + + it("Register IP and attach NON_COMMERCIAL_REMIX PilTerms", async function () { + const response = await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: The contract function "registerIpAndAttachPILTerms" reverted with the following signature:`, `0x55d48f8d`); + }); + + it("Register IP and attach NON_COMMERCIAL_REMIX PilTerms with all optional parameters", async function () { + const tokenId = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdC); + + const response = await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenId, PIL_TYPE.NON_COMMERCIAL_REMIX, false, metadataURI, metadataHash, nftMetadataHash, 1000n, "100", 20, mintingFeeTokenAddress) + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: The contract function "registerIpAndAttachPILTerms" reverted with the following signature:`, `0x55d48f8d`); + }); + + it("Register IP and attach COMMERCIAL_USE PilTerms", async function () { + const deadline = await(getBlockTimestamp()) + 1000n; + const response = await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdB, PIL_TYPE.COMMERCIAL_USE, true, metadataURI, metadataHash, nftMetadataHash, deadline, "100", undefined, mintingFeeTokenAddress) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + expect(response.ipId).to.be.a("string").and.not.empty; + }); + + it("Register IP and attach COMMERCIAL_USE PilTerms with all optional parameters", async function () { + const tokenId = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdC); + + const response = await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenId, PIL_TYPE.COMMERCIAL_USE, undefined, metadataURI, metadataHash, nftMetadataHash, 1000n, "100", 20, mintingFeeTokenAddress) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTermsId).to.not.be.exist; + expect(response.ipId).to.not.be.exist; + }); + + it("Register IP and attach COMMERCIAL_REMIX PilTerms", async function () { + const deadline = await(getBlockTimestamp()) + 1000n; + const response = await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenIdC, PIL_TYPE.COMMERCIAL_REMIX, true, metadataURI, metadataHash, nftMetadataHash, deadline, "100", 20, mintingFeeTokenAddress) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + expect(response.ipId).to.be.a("string").and.not.empty; + }); + + it("Register IP and attach COMMERCIAL_REMIX PilTerms with all optional parameters", async function () { + const tokenId = await mintNFTWithRetry(privateKeyA, nftCollectionAddress); + checkMintResult(tokenIdC); + + const response = await expect( + registerIpAndAttachPilTerms("A", nftCollectionAddress, tokenId, PIL_TYPE.COMMERCIAL_REMIX, true, metadataURI, metadataHash, nftMetadataHash, 1000n, "100", 20, mintingFeeTokenAddress) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + expect(response.ipId).to.be.a("string").and.not.empty; + }); + }); +}); diff --git a/test/license/attachLicenseTerms.test.ts b/test/license/attachLicenseTerms.test.ts new file mode 100644 index 0000000..ea936ea --- /dev/null +++ b/test/license/attachLicenseTerms.test.ts @@ -0,0 +1,233 @@ +import { privateKeyA, privateKeyB, privateKeyC, nftContractAddress } from '../../config/config'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { registerIpAsset, attachLicenseTerms, registerDerivative } from '../../utils/sdkUtils'; +import { comUseLicenseTermsId1, comUseLicenseTermsId2, comRemixLicenseTermsId1 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; + +const waitForTransaction: boolean = true; + +describe("SDK Test", function () { + describe("Attach license terms - license.attachLicenseTerms", async function () { + before("Register license terms and IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseA = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + ipIdA = responseA.ipId; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const responseB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, true) + ).to.not.be.rejected; + ipIdB = responseB.ipId; + + tokenIdC = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdC); + + const responseC = await expect( + registerIpAsset("A", nftContractAddress, tokenIdC, true) + ).to.not.be.rejected; + ipIdC = responseC.ipId; + }); + + describe("Attach license terms - negative tests", async function () { + it("Non-owner attach license terms", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdA, comUseLicenseTermsId1, true) + ).to.be.rejectedWith("The contract function \"attachLicenseTerms\" reverted with the following signature:"); + }); + + it("Attach license terms with ipId: undefined", async function () { + let ipId: any; + const response = await expect( + attachLicenseTerms("A", ipId, comUseLicenseTermsId1, true) + ).to.be.rejectedWith(`Failed to attach license terms: request.ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Attach license terms with an invalid ipId", async function () { + const response = await expect( + attachLicenseTerms("A", "0x0000", comUseLicenseTermsId1, true) + ).to.not.be.rejectedWith("InvalidAddressError: Address \"0x0000\" is invalid."); + }); + + it("Attach license terms with a non-existent ipId", async function () { + const response = await expect( + attachLicenseTerms("A", "0xA36F2A4A02f5C215d1b3630f71A4Ff55B5492AAB", comUseLicenseTermsId1, true) + ).to.be.rejectedWith("Failed to attach license terms: The IP with id 0xA36F2A4A02f5C215d1b3630f71A4Ff55B5492AAB is not registered."); + }); + + it("Attach license terms with licenseTermsId: undefined", async function () { + let licenseTermsId: any; + const response = await expect( + attachLicenseTerms("A", ipIdA, licenseTermsId, true) + ).to.be.rejectedWith("Cannot convert undefined to a BigInt"); + }); + + it("Attach license terms with an invalid licenseTermsId", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, "test", true) + ).to.be.rejectedWith("Cannot convert test to a BigInt"); + }); + + it("Attach license terms with a non-existent licenseTermsId", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, "999999", true) + ).to.be.rejectedWith("Failed to attach license terms: License terms id 999999 do not exist."); + }); + }) + + describe("Attach license terms", async function () { + it("Attach license terms with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Attach license terms with waitForTransaction: true", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, true) + ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Attach license terms that is already attached to the IP Asset", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.empty; + expect(response.success).to.be.equals(false); + }); + + it("Attach license terms with waitForTransaction: false", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdC, comUseLicenseTermsId1, false) + ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.not.be.exist; + }); + }) + + describe("Attach license terms to parent/derivative IP assets", async function () { + before("Register IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdB); + }) + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }) + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }) + + step("Wallet B register a derivative IP asset with ipIdA and comUseLicenseTermsId1", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Derivative IP asset can NOT attach more license terms", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId2, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0x1ae3058f"); + }); + + step("Parent IP asset can attach more license terms(commercial PIL)", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Parent IP asset can attach more license terms(non-commercial PIL)", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, 0n, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }) + + step("Wallet C register a derivative IP asset with ipIdC and comUseLicenseTermsId1", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdB], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Derivative IP asset (ipIdB) can NOT attach more license terms", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId2, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0x1ae3058f"); + }); + + step("Derivative IP asset (ipIdC) can NOT attach more license terms", async function () { + const response = await expect( + attachLicenseTerms("C", ipIdC, comRemixLicenseTermsId1, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0x1ae3058f"); + }); + }); + }); +}); diff --git a/test/license/getLicenseTerms.test.ts b/test/license/getLicenseTerms.test.ts new file mode 100644 index 0000000..6738ec2 --- /dev/null +++ b/test/license/getLicenseTerms.test.ts @@ -0,0 +1,118 @@ +import { royaltyPolicyLAPAddress } from '../../config/config'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { getLicenseTerms } from '../../utils/sdkUtils'; +import { nonComLicenseTermsId, comUseLicenseTermsId1, comRemixLicenseTermsId1, mintingFee1, commercialRevShare1 } from '../setup'; + +describe("SDK Test", function () { + describe("Get license terms - license.getLicenseTerms", async function () { + describe("Get license terms - Positive tests", async function () { + it("licenseTermsId: 0", async function () { + const response = await expect( + getLicenseTerms("A", 0) + ).to.not.be.rejected; + + expect(response.terms.transferable).to.be.a("boolean").and.to.be.false; + expect(response.terms.commercialUse).to.be.a("boolean").and.to.be.false; + expect(response.terms.commercialAttribution).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesAllowed).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesAttribution).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesApproval).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesReciprocal).to.be.a("boolean").and.to.be.false; + expect(response.terms.mintingFee).to.be.a("bigint").and.to.be.equal(0n); + expect(response.terms.expiration).to.be.a("bigint").and.to.be.equal(0n); + }); + + it("licenseTermsId: null", async function () { + const response = await expect( + getLicenseTerms("A", "") + ).to.not.be.rejected; + + expect(response.terms.transferable).to.be.a("boolean").and.to.be.false; + expect(response.terms.commercialUse).to.be.a("boolean").and.to.be.false; + expect(response.terms.commercialAttribution).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesAllowed).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesAttribution).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesApproval).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesReciprocal).to.be.a("boolean").and.to.be.false; + expect(response.terms.mintingFee).to.be.a("bigint").and.to.be.equal(0n); + expect(response.terms.expiration).to.be.a("bigint").and.to.be.equal(0n); + }); + + it("Non Commercial License Terms", async function () { + const response = await expect( + getLicenseTerms("A", nonComLicenseTermsId) + ).to.not.be.rejected; + + expect(response.terms.transferable).to.be.a("boolean").and.to.be.true; + expect(response.terms.commercialUse).to.be.a("boolean").and.to.be.false; + expect(response.terms.commercialAttribution).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesAllowed).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesAttribution).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesApproval).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesReciprocal).to.be.a("boolean").and.to.be.true; + expect(response.terms.mintingFee).to.be.a("bigint").and.to.be.equal(0n); + expect(response.terms.expiration).to.be.a("bigint").and.to.be.equal(0n); + }); + + it("Commercial Use License Terms", async function () { + const response = await expect( + getLicenseTerms("B", comUseLicenseTermsId1) + ).to.not.be.rejected; + + expect(response.terms.transferable).to.be.a("boolean").and.to.be.true; + expect(response.terms.royaltyPolicy).to.be.a("string").and.to.be.equal(royaltyPolicyLAPAddress); + expect(response.terms.commercialUse).to.be.a("boolean").and.to.be.true; + expect(response.terms.commercialAttribution).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesAllowed).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesAttribution).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesApproval).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesReciprocal).to.be.a("boolean").and.to.be.false; + expect(response.terms.mintingFee).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); + expect(response.terms.expiration).to.be.a("bigint").and.to.be.equal(0n); + }); + + it("Commercial Remix License Terms", async function () { + const response = await expect( + getLicenseTerms("C", comRemixLicenseTermsId1) + ).to.not.be.rejected; + + expect(response.terms.transferable).to.be.a("boolean").and.to.be.true; + expect(response.terms.royaltyPolicy).to.be.a("string").and.to.be.equal(royaltyPolicyLAPAddress); + expect(response.terms.commercialUse).to.be.a("boolean").and.to.be.true; + expect(response.terms.commercialAttribution).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesAllowed).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesAttribution).to.be.a("boolean").and.to.be.true; + expect(response.terms.derivativesApproval).to.be.a("boolean").and.to.be.false; + expect(response.terms.derivativesReciprocal).to.be.a("boolean").and.to.be.true; + expect(response.terms.mintingFee).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); + expect(response.terms.commercialRevShare).to.be.a("number").and.to.be.equal(commercialRevShare1 * 1000000); + expect(response.terms.expiration).to.be.a("bigint").and.to.be.equal(0n); + }); + }); + + describe("Get license terms - Negative tests", async function () { + it("Get license terms with invalid licenseTermsId: undefined", async function () { + let licenseTermsId: any; + const response = await expect( + getLicenseTerms("A", licenseTermsId) + ).to.be.rejectedWith("Failed to get license terms: Cannot convert undefined to a BigInt"); + }); + + it("Get license terms with invalid licenseTermsId: -1", async function () { + const response = await expect( + getLicenseTerms("A", "-1") + ).to.be.rejectedWith("Failed to get license terms: Number \"-1n\" is not in safe 256-bit unsigned integer range (0n to 115792089237316195423570985008687907853269984665640564039457584007913129639935n"); + }); + + it("Get license terms with invalid licenseTermsId: test", async function () { + const response = await expect( + getLicenseTerms("A", "test") + ).to.be.rejectedWith("Failed to get license terms: Cannot convert test to a BigInt"); + }); + }); + }); +}); diff --git a/test/license/mintLicenseTokens.test.ts b/test/license/mintLicenseTokens.test.ts new file mode 100644 index 0000000..cb4c664 --- /dev/null +++ b/test/license/mintLicenseTokens.test.ts @@ -0,0 +1,216 @@ +import { privateKeyA, accountB, nftContractAddress } from '../../config/config'; +import { attachLicenseTerms, mintLicenseTokens, registerIpAsset } from '../../utils/sdkUtils'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { expect } from 'chai'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address } from 'viem'; +import { nonComLicenseTermsId, comUseLicenseTermsId1, comRemixLicenseTermsId1 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Address; +let ipIdB: Address; + +const waitForTransaction: boolean = true; + +describe('SDK Test', function () { + describe('Test license.mintLicenseTokens Function', async function () { + before("Register license terms and IP assets",async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + tokenIdB = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdB); + + const responseA = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseA.txHash).to.be.a("string").and.not.empty; + expect(responseA.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseA.ipId; + + const responseB = await expect( + registerIpAsset("A", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(responseB.txHash).to.be.a("string").and.not.empty; + expect(responseB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseB.ipId; + }); + + describe('Mint License Tokens - Negative Tests', async function () { + it("Mint a license token fail as undefined ipId", async function () { + let ipIdA: any; + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, true) + ).to.be.rejectedWith(`Failed to mint license tokens: request.licensorIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Mint a license token fail as invalid ipId", async function () { + const response = await expect( + mintLicenseTokens("A", "0x0000", nonComLicenseTermsId, 2, accountB.address, true) + ).to.be.rejectedWith(`Failed to mint license tokens: request.licensorIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Mint a license token fail as non-existent ipId", async function () { + const response = await expect( + mintLicenseTokens("A", "0xA36F2A4A02f5C215d1b3630f71A4Ff55B5492AAB", nonComLicenseTermsId, 2, accountB.address, true) + ).to.be.rejectedWith("Failed to mint license tokens: The licensor IP with id 0xA36F2A4A02f5C215d1b3630f71A4Ff55B5492AAB is not registered."); + }); + + it("Mint a license token fail as undefined licenseTermsId", async function () { + let nonComLicenseTermsId: any; + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, true) + ).to.be.rejectedWith("Failed to mint license tokens: Cannot convert undefined to a BigInt"); + }); + + it("Mint a license token fail as invalid licenseTermsId", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, "test", 2, accountB.address, true) + ).to.be.rejectedWith("Failed to mint license tokens: Cannot convert test to a BigInt"); + }); + + it("Mint a license token fail as non-existent licenseTermsId", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, "9999999", 2, accountB.address, true) + ).to.be.rejectedWith("Failed to mint license tokens: License terms id 9999999 do not exist."); + }); + + it("Mint a license token fail as invalid amount value (-1)", async function () { + let receiver: any; + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, -1, receiver, true) + ).to.be.rejectedWith("Failed to mint license tokens: Number \"-1n\" is not in safe 256-bit unsigned integer range (0n to 115792089237316195423570985008687907853269984665640564039457584007913129639935n)"); + }); + + it("Mint a license token fail as invalid receiver address", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, "0x0000", true) + ).to.be.rejectedWith(`Failed to mint license tokens: request.receiver address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Mint a license token fail as not attached licenseTermsId", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdB, 0n, 2, "0x485FCfC79Ce0A082Ab2a5e729D6e6255A540342a", true) + ).to.be.rejectedWith("Failed to mint license tokens: License terms id 0 is not attached to the IP with id " + ipIdB); + }); + }); + + describe("Mint License Tokens - Positive Tests", async function () { + it("Mint a license token with undefined amount", async function () { + let amount: any; + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, amount, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + }); + + it("Mint a license token with amount: 0", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 0, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + }); + + it("Mint a license token by non-owner", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdA, nonComLicenseTermsId, 2, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint a license token with undefined receiver address", async function () { + let receiver: any; + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, receiver, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint a license token with waitForTransaction:true", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint a license token with the same parameters before", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint a license token with undefined waitForTransaction", async function () { + let waitForTransaction: any; + const response = await expect( + mintLicenseTokens("B", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Mint License Tokens - IP asset attached multiple license terms", async function () { + before("Register 2 license terms and 2 IP assets", async function () { + const responseAttachLicenseTerms1 = await expect( + attachLicenseTerms("A", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms1.txHash).to.be.a("string").and.not.empty; + + const responseAttachLicenseTerms2 = await expect( + attachLicenseTerms("A", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms2.txHash).to.be.a("string").and.not.empty; + }); + + it("Mint a license token with ipIdB and nonComLicenseTermsId", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdB, nonComLicenseTermsId, 2, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint a license token with ipIdB and comUsenonComLicenseTermsId", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdB, comUseLicenseTermsId1, 2, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + }); + + it("Mint a license token with ipIdB and comRemixnonComLicenseTermsId", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdB, comRemixLicenseTermsId1, 2, accountB.address, false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.not.be.exist; + }); + }); + }); +}); diff --git a/test/license/registerPIL.test.ts b/test/license/registerPIL.test.ts new file mode 100644 index 0000000..9a36b1a --- /dev/null +++ b/test/license/registerPIL.test.ts @@ -0,0 +1,184 @@ +import { mintingFeeTokenAddress } from '../../config/config'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { registerCommercialRemixPIL, registerCommercialUsePIL, registerNonComSocialRemixingPIL } from '../../utils/sdkUtils'; + +describe("SDK Test", function () { + describe("Register PIL", async function () { + describe("Register Non-Commercial Social Remixing PIL (license.registerNonComSocialRemixingPIL)", async function () { + it("Register Non-Commercial Social Remixing PIL with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + registerNonComSocialRemixingPIL("A", waitForTransaction) + ).to.not.be.rejected; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + }); + + it("Register Non-Commercial Social Remixing PIL with waitForTransaction: true", async function () { + const response = await expect( + registerNonComSocialRemixingPIL("A", true) + ).to.not.be.rejected; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + }); + + it("Register Non-Commercial Social Remixing PIL with waitForTransaction: false", async function () { + const response = await expect( + registerNonComSocialRemixingPIL("A", false) + ).to.not.be.rejected; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + }); + }) + + describe("Register Commercial Use PIL (license.registerCommercialUsePIL)", async function () { + it("Register Commercial Use PIL with mintingFee: undefined", async function () { + let mintingFee: any; + const response = await expect( + registerCommercialUsePIL("A", mintingFee, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial use PIL: mintingFee currency are required for commercial use PIL."); + }); + + it("Register Commercial Use PIL with an invalid mintingFee value (test)", async function () { + const response = await expect( + registerCommercialUsePIL("A", "test", mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial use PIL: Cannot convert test to a BigInt"); + }); + + it("Register Commercial Use PIL with an invalid mintingFee value (-1)", async function () { + const response = await expect( + registerCommercialUsePIL("A", "-1", mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial use PIL: Number \"-1n\" is not in safe 256-bit unsigned integer range"); + }); + + it("Register Commercial Use PIL with currency: undefined", async function () { + let currency: any; + const response = await expect( + registerCommercialUsePIL("A", "0", currency, true) + ).to.be.rejectedWith("Failed to register commercial use PIL: mintingFee currency are required for commercial use PIL."); + }); + + it("Register Commercial Use PIL with an invalid currency address", async function () { + const response = await expect( + registerCommercialUsePIL("A", "0", "0xA36F2A4A02f5C215d1b3630f71A4Ff55B5492AAB", true) + ).to.be.rejectedWith("Failed to register commercial use PIL: The contract function \"registerLicenseTerms\" reverted.", "Error: PILicenseTemplate__CurrencyTokenNotWhitelisted()"); + }); + + it("Register Commercial Use PIL with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + registerCommercialUsePIL("A", "0", mintingFeeTokenAddress, waitForTransaction) + ).to.not.be.rejected; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + }); + + it("Register Commercial Use PIL with waitForTransaction: true", async function () { + const response = await expect( + registerCommercialUsePIL("A", "0", mintingFeeTokenAddress, true) + ).to.not.be.rejected; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + }); + + it("Register Commercial Use PIL with waitForTransaction: false", async function () { + const response = await expect( + registerCommercialUsePIL("A", "16", mintingFeeTokenAddress, false) + ).to.not.be.rejected; + + if (response.licenseTermsId) { + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + } else { + expect(response.txHash).to.be.a("string").and.not.to.be.empty; + expect(response.licenseTermsId).not.to.be.exist; + }; + }); + }) + + describe("Register Commercial Remix PIL (license.registerCommercialRemixPIL)", async function () { + it("Register Commercial Remix PIL with mintingFee: undefined", async function () { + let mintingFee: any; + const response = await expect( + registerCommercialRemixPIL("A", mintingFee, 100, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: mintingFee, currency and commercialRevShare are required for commercial remix PIL."); + }); + + it("Register Commercial Remix PIL with an invalid mintingFee value (test)", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "test", 100, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: Cannot convert test to a BigInt"); + }); + + it("Register Commercial Remix PIL with an invalid mintingFee value (-1)", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "-1", 100, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: Number \"-1n\" is not in safe 256-bit unsigned integer range"); + }); + + it("Register Commercial Remix PIL with commercialRevShare: undefined", async function () { + let commercialRevShare: any; + const response = await expect( + registerCommercialRemixPIL("A", "0", commercialRevShare, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: mintingFee, currency and commercialRevShare are required for commercial remix PIL."); + }); + + it("Register Commercial Remix PIL with an invalid commercialRevShare value (-1)", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "0", -1, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: commercialRevShare should be between 0 and 100."); + }); + + it("Register Commercial Remix PIL with an invalid commercialRevShare value (101)", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "0", 101, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: commercialRevShare should be between 0 and 100."); + }); + + it("Register Commercial Remix PIL with currency: undefined", async function () { + let currency: any; + const response = await expect( + registerCommercialRemixPIL("A", "0", 0, currency, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: mintingFee, currency and commercialRevShare are required for commercial remix PIL."); + }); + + it("Register Commercial Remix PIL with an invalid currency address", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "0", 0, "0xA36F2A4A02f5C215d1b3630f71A4Ff55B5492AAB", true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: The contract function \"registerLicenseTerms\" reverted.", "Error: PILicenseTemplate__CurrencyTokenNotWhitelisted()"); + }); + + it("Register Commercial Remix PIL with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + registerCommercialRemixPIL("A", "0", 0, mintingFeeTokenAddress, waitForTransaction) + ).to.not.be.rejected; + + if (response.licenseTermsId) { + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + } else { + expect(response.txHash).to.be.a("string").and.not.to.be.empty; + expect(response.licenseTermsId).not.to.be.exist; + }; + }); + + it("Register Commercial Remix PIL with waitForTransaction: true", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "0", 100, mintingFeeTokenAddress, true) + ).to.not.be.rejected; + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + }); + + it("Register Commercial Remix PIL with waitForTransaction: false", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "16", 100, mintingFeeTokenAddress, false) + ).to.not.be.rejected; + + if (response.licenseTermsId) { + expect(response.licenseTermsId).to.be.a("bigint").and.to.be.ok; + } else { + expect(response.txHash).to.be.a("string").and.not.to.be.empty; + expect(response.licenseTermsId).not.to.be.exist; + }; + }); + }) + }); +}); \ No newline at end of file diff --git a/test/nftClient/createNFTCollection.test.ts b/test/nftClient/createNFTCollection.test.ts new file mode 100644 index 0000000..e7340a4 --- /dev/null +++ b/test/nftClient/createNFTCollection.test.ts @@ -0,0 +1,115 @@ +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { createNFTCollection } from '../../utils/sdkUtils'; +import { accountA, mintingFeeTokenAddress } from '../../config/config'; + +describe("SDK Test", function () { + describe("Create NFT Collection - nftClient.createNFTCollection", async function () { + it("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; + }); + + it("Create NFT collection with empyt name and symbol", async function () { + const response = await expect( + createNFTCollection("A", "", "", 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; + }); + + it("Create NFT collection with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + createNFTCollection("A", "sdk-e2e-test", "test", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.nftContract).to.not.be.exist; + }); + + it("Create NFT collection with waitForTransaction: false", async function () { + const response = await expect( + createNFTCollection("A", "sdk-e2e-test", "test", false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.nftContract).to.not.be.exist; + }); + + it("Create NFT collection with optional parameters", async function () { + const options = { + maxSupply: 100n, + mintCost: 1, + mintToken: mintingFeeTokenAddress, + owner: accountA.address + }; + + const response = await expect( + createNFTCollection("A", "sdk-e2e-test", "test", true, options) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.nftContract).to.be.a("string").and.not.empty; + }); + + it("Create NFT collection with multi undefined parameters", async function () { + let maxSupply: any; + let mintCost: any; + let mintToken: any; + let owner: any; + + const options = { + maxSupply: maxSupply, + mintCost: mintCost, + mintToken: mintToken, + owner: owner + }; + + const response = await expect( + createNFTCollection("A", "sdk-e2e-test", "test", true, options) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.nftContract).to.be.a("string").and.not.empty; + }); + + it("Create NFT collection with invalid type for maxSupply", async function () { + const options = { + maxSupply: "test" + }; + + const response = await expect( + createNFTCollection("A", "sdk-e2e-test", "test", true, options) + ).to.be.rejectedWith("Failed to create a SPG NFT collection: Cannot convert test to a BigInt"); + }); + + it("Create NFT collection with invalid type for owner", async function () { + const options = { + owner: "test" + }; + + const response = await expect( + createNFTCollection("A", "sdk-e2e-test", "test", true, options) + ).to.be.rejectedWith(`Failed to create a SPG NFT collection: request.owner address is invalid: test, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Create NFT collection with owner: 0x0000", async function () { + const options = { + owner: "0x0000" + }; + + const response = await expect( + createNFTCollection("A", "sdk-e2e-test", "test", true, options) + ).to.be.rejectedWith(`Failed to create a SPG NFT collection: request.owner address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + }); +}); diff --git a/test/permission/permission.test.ts b/test/permission/permission.test.ts new file mode 100644 index 0000000..cf8c0c2 --- /dev/null +++ b/test/permission/permission.test.ts @@ -0,0 +1,131 @@ +import { nftContractAddress, privateKeyA, accountB, licensingModuleAddress } from '../../config/config'; +import { registerIpAsset, setPermission } from '../../utils/sdkUtils'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { expect } from 'chai'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; + +let tokenIdA: string; +let ipIdA: Address; + +describe('SDK Test', function () { + describe('Test permission.setPermission Function', async function () { + before("Mint NFT and Register IP Asset",async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, 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; + + ipIdA = response.ipId + }); + + it("Non-owner set permission", async function () { + const response = await expect( + setPermission("B", ipIdA, accountB.address, licensingModuleAddress, 1, true) + ).to.be.rejectedWith(`Failed to set permissions: The contract function "setPermission" reverted.`, + `Error: AccessController__CallerIsNotIPAccountOrOwner()`); + }); + + it("Set permission with an empty IP id", async function () { + let testIpId:any; + const response = await expect( + setPermission("A", testIpId, accountB.address, licensingModuleAddress, 1, true) + ).to.be.rejectedWith(`Failed to set permissions: ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Set permission with a non-existent IP id", async function () { + const response = await expect( + setPermission("B", "0x1954631f55AC9a79CC4ec57103D23A9b2e8aDBfa", accountB.address, licensingModuleAddress, 1, true) + ).to.be.rejectedWith(`Failed to set permissions: IP id with 0x1954631f55AC9a79CC4ec57103D23A9b2e8aDBfa is not registered.`); + }); + + it("Set permission with an invalid IP id", async function () { + const response = await expect( + setPermission("A", "0x00000", accountB.address, licensingModuleAddress, 1, true) + ).to.be.rejectedWith(`Failed to set permissions: ipId address is invalid: 0x00000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Set permission with an empty signer address", async function () { + let accountAddress:any; + const response = await expect( + setPermission("A", ipIdA, accountAddress, licensingModuleAddress, 1, true) + ).to.be.rejectedWith("Failed to set permissions: Address \"undefined\" is invalid."); + }); + + it("Set permission with an invalid signer address", async function () { + const response = await expect( + setPermission("A", ipIdA, "0x00000", licensingModuleAddress, 1, true) + ).to.be.rejectedWith("Failed to set permissions: Address \"0x00000\" is invalid."); + }); + + it("Set permission with an emty license module address", async function () { + let testLicenseAddress: any; + const response = await expect( + setPermission("A", ipIdA, accountB.address, testLicenseAddress, 1, true) + ).to.be.rejectedWith("Failed to set permissions: Address \"undefined\" is invalid."); + }); + + it("Set permission with an invalid license module address", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, "0x0000", 1, true) + ).to.be.rejectedWith("Failed to set permissions: Address \"0x0000\" is invalid."); + }); + + it("Set permission with an invalid permission id (-1)", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, -1, true) + ).to.be.rejectedWith("Failed to set permissions: Number \"-1\" is not in safe 256-bit unsigned integer range"); + }); + + it("Set permission with an invalid permission id (4)", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 4, true) + ).to.be.rejectedWith(`Failed to set permissions: The contract function "setPermission" reverted.`, + `Error: AccessController__PermissionIsNotValid()`); + }); + + it("Set permission (permission id: 1) to wallet B", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 1, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true + }); + + it("Set permission (permission id: 1) that is already set 1 to wallet B", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 1, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true + }); + + it("Set permission (permission id: 2) to wallet B", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 2, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true + }); + + it("Set permission (permission id: 0) to wallet B", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 0, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true + }); + }); +}); diff --git a/test/royalty/claimRevenue.test.ts b/test/royalty/claimRevenue.test.ts new file mode 100644 index 0000000..33652ec --- /dev/null +++ b/test/royalty/claimRevenue.test.ts @@ -0,0 +1,185 @@ +import { privateKeyA, privateKeyB, nftContractAddress, mintingFeeTokenAddress } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, registerDerivative, royaltyClaimRevenue, royaltySnapshot } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { comRemixLicenseTermsId1, mintingFee1 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Address; +let ipIdB: Address; +let snapshotId1: bigint; +const waitForTransaction: boolean = true; + +describe("SDK Test", function () { + describe("Test royalty.claimRevenue Function", async function () { + before("Register parent and derivative IP assets, capture snapshot", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const responseAttachLicenseTerms1 = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms1.txHash).to.be.a("string").and.not.empty; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const responseRegisterIpAssetB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAssetB.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAssetB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpAssetB.ipId; + + const responseRegisterDerivative1 = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterDerivative1.txHash).to.be.a("string").and.not.empty; + + const tokenId = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenId); + + const responseSnapshot = await expect( + royaltySnapshot("A", ipIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseSnapshot.txHash).to.be.a("string").and.not.empty; + expect(responseSnapshot.snapshotId).to.be.a("bigint").and.to.be.ok; + + snapshotId1 = responseSnapshot.snapshotId; + }); + + it("Claim revenue fail as undefined snapshotId", async function () { + let snapshotId: any; + const response = await expect( + royaltyClaimRevenue("A", [snapshotId], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: Cannot convert undefined to a BigInt"); + }); + + it("Claim revenue fail as invalid snapshotId", async function () { + const response = await expect( + royaltyClaimRevenue("A", ["test"], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: Cannot convert test to a BigInt"); + }); + + it("Claim revenue fail as non-existent snapshotId", async function () { + const response = await expect( + royaltyClaimRevenue("A", ["999"], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: Failed to execute the IP Account transaction: The contract function \"execute\" reverted with the following reason:", + "ERC20Snapshot: nonexistent id"); + }); + + it("Claim revenue fail as undefined royaltyVaultIpId", async function () { + let royaltyVaultIpId: any; + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], royaltyVaultIpId, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith(`Failed to claim revenue: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Claim revenue fail as invalid royaltyVaultIpId", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], "0x0000", mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith(`Failed to claim revenue: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Claim revenue fail as non-existent royaltyVaultIpId", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], "0xe967f54D03acc01CF624b54e0F24794a2f8f229b", mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: The royalty vault IP with id 0xE967F54d03aCC01Cf624b54E0f24794A2F8F229b is not registered."); + }); + + it("Claim revenue with undefined account address", async function () { + let accountAddress: any; + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, accountAddress, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.claimableToken).to.be.a("bigint").and.equal(0n); + }); + + it("Claim revenue fail as invalid account address", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, "0x00000", waitForTransaction) + ).to.be.rejectedWith(`ailed to claim revenue: request.account address is invalid: 0x00000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Claim revenue fail as non-existent account address", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, "0xe967f54D03acc01CF624b54e0F24794a2f8f229c", waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: Failed to execute the IP Account transaction: The contract function \"execute\" returned no data (\"0x\")."); + }); + + it("Claim revenue fail as undefined token address", async function () { + let tokenAddress: any; + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, tokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: Address \"undefined\" is invalid."); + }); + + it("Claim revenue fail as invalid token address", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, "0x0000", ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: Address \"0x0000\" is invalid."); + }); + + it("Claim revenue fail as non-existent token address", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, "0xe967f54D03acc01CF624b54e0F24794a2f8f229c", ipIdA, waitForTransaction) + ).to.be.rejectedWith(`Failed to claim revenue: Address "0xe967f54D03acc01CF624b54e0F24794a2f8f229c" is invalid.`); + }); + + it("Claim revenue with waitForTransaction: true", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.claimableToken).to.be.a("bigint").and.equal(BigInt(mintingFee1)); + }); + + it("Claim revenue with waitForTransaction: false", async function () { + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.claimableToken).to.not.be.exist; + }); + + it("Claim revenue with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.claimableToken).to.not.be.exist; + }); + + it("Claim revenue fail by non-owner", async function () { + const response = await expect( + royaltyClaimRevenue("B", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to claim revenue: Failed to execute the IP Account transaction: The contract function \"execute\" reverted with the following signature:", "0x8ea0b111"); + }); + }); +}); diff --git a/test/royalty/claimableRevenue.test.ts b/test/royalty/claimableRevenue.test.ts new file mode 100644 index 0000000..7564351 --- /dev/null +++ b/test/royalty/claimableRevenue.test.ts @@ -0,0 +1,182 @@ +import { privateKeyA, privateKeyB, nftContractAddress, mintingFeeTokenAddress } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, registerDerivative, royaltyClaimableRevenue, royaltySnapshot } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { comRemixLicenseTermsId1, mintingFee1 } from '../setup'; + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Address; +let ipIdB: Address; +let snapshotId1: bigint; +const waitForTransaction: boolean = true; + +describe("SDK Test", function () { + describe("Test royalty.claimableRevenue Function", async function () { + before("Register parent and derivative IP assets, capture snapshot", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const responseAttachLicenseTerms1 = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms1.txHash).to.be.a("string").and.not.empty; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const responseRegisterIpAssetB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAssetB.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAssetB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpAssetB.ipId; + + const responseRegisterDerivative1 = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterDerivative1.txHash).to.be.a("string").and.not.empty; + + const tokenId = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenId); + + const responseSnapshot = await expect( + royaltySnapshot("A", ipIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseSnapshot.txHash).to.be.a("string").and.not.empty; + expect(responseSnapshot.snapshotId).to.be.a("bigint").and.to.be.ok; + + snapshotId1 = responseSnapshot.snapshotId; + }); + + it("Check claimable revenue fail as undefined royaltyVaultIpId", async function () { + let royaltyVaultIpId: any; + const response = await expect( + royaltyClaimableRevenue("A", royaltyVaultIpId, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith(`ailed to calculate claimable revenue: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Check claimable revenue fail as invalid parentIpId", async function () { + const response = await expect( + royaltyClaimableRevenue("A", "0x0000", ipIdA, "1", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Check claimable revenue fail as non-existent parentIpId", async function () { + const response = await expect( + royaltyClaimableRevenue("A", "0xe967f54D03acc01CF624b54e0F24794a2f8f229a", ipIdA, "1", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith("Failed to calculate claimable revenue: The royalty vault IP with id 0xe967F54d03ACc01CF624B54e0F24794A2f8f229a is not registered."); + }); + + it("Check claimable revenue fail as undefined account address", async function () { + let account: any; + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, account, "1", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.account address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Check claimable revenue fail as invalid account address", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, "0x0000", "1", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.account address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Check claimable revenue fail as undefined snapshotId", async function () { + let snapshotId: any; + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId, mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith("Failed to calculate claimable revenue: Cannot convert undefined to a BigInt"); + }); + + it("Check claimable revenue fail as invalid snapshotId", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, "test", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith("Failed to calculate claimable revenue: Cannot convert test to a BigInt"); + }); + + it("Check claimable revenue fail as invalid snapshotId (-1)", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, "-1", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith("Failed to calculate claimable revenue: Number \"-1n\" is not in safe 256-bit unsigned integer range (0n to 115792089237316195423570985008687907853269984665640564039457584007913129639935n)"); + }); + + it("Check claimable revenue fail as non-existent snapshotId", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, "999", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith("Failed to calculate claimable revenue: The contract function \"claimableRevenue\" reverted with the following reason:", + "ERC20Snapshot: nonexistent id"); + }); + + it("Check claimable revenue fail as invalid snapshotId (0)", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, "999", mintingFeeTokenAddress, waitForTransaction) + ).to.be.rejectedWith("Failed to calculate claimable revenue: The contract function \"claimableRevenue\" reverted with the following reason:", + "ERC20Snapshot: id is 0"); + }); + + it("Check claimable revenue fail as undefined token address", async function () { + let tokenAddress: any; + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, tokenAddress, waitForTransaction) + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.token address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Check claimable revenue fail as invalid token address", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, "0x0000", waitForTransaction) + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.token address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Check claimable revenue with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) + ).to.not.be.rejected; + + expect(response).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); + }); + + it("Check claimable revenue with waitForTransaction: true", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, true) + ).to.not.be.rejected; + + expect(response).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); + }); + + it("Check claimable revenue with waitForTransaction: false", async function () { + const response = await expect( + royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, false) + ).to.not.be.rejected; + + expect(response).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); + }); + + it("Check claimable revenue by non-owner", async function () { + const response = await expect( + royaltyClaimableRevenue("C", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, false) + ).to.not.be.rejected; + + expect(response).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); + }); + }); +}); diff --git a/test/royalty/collectRoyaltyTokens.test.ts b/test/royalty/collectRoyaltyTokens.test.ts new file mode 100644 index 0000000..f2bc3f0 --- /dev/null +++ b/test/royalty/collectRoyaltyTokens.test.ts @@ -0,0 +1,218 @@ +import { privateKeyA, privateKeyB, privateKeyC, nftContractAddress } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult, sleep } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, registerDerivative, collectRoyaltyTokens } from '../../utils/sdkUtils'; +import { Address, Hex } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { comRemixLicenseTermsId1, comRemixLicenseTermsId2, commercialRevShare1, commercialRevShare2 } from '../setup'; + +const waitForTransaction: boolean = true; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let tokenIdD: string; +let tokenIdE: string; +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; +let ipIdD: Address; +let ipIdE: Address; + +describe("SDK Test", function () { + describe("Test royalty.collectRoyaltyTokens Function", async function () { + before("Register parent and derivative IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const responseAttachLicenseTerms1 = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms1.txHash).to.be.a("string").and.not.empty; + + const responseAttachLicenseTerms2 = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms2.txHash).to.be.a("string").and.not.empty; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const responseregisterIpAssetB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; + expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseregisterIpAssetB.ipId; + + const responseRegisterDerivative1 = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterDerivative1.txHash).to.be.a("string").and.not.empty; + + tokenIdE = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdE); + + const responseregisterIpAssetE = await expect( + registerIpAsset("C", nftContractAddress, tokenIdE, waitForTransaction) + ).to.not.be.rejected; + + ipIdE = responseregisterIpAssetE.ipId; + + await sleep(20); + }); + + it("Collect royalty tokens fail as undefined parentIpId", async function () { + let parentIpId: any; + const response = await expect( + collectRoyaltyTokens("B", parentIpId, ipIdB, waitForTransaction) + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.parentIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Collect royalty tokens fail as invalid parentIpId", async function () { + const response = await expect( + collectRoyaltyTokens("B", "0x0000", ipIdB, waitForTransaction) + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.parentIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Collect royalty tokens fail as non-existent parentIpId", async function () { + const response = await expect( + collectRoyaltyTokens("B", "0xe967f54D03acc01CF624b54e0F24794a2f8f229a", ipIdB, waitForTransaction) + ).to.be.rejectedWith("Failed to collect royalty tokens: The parent IP with id 0xe967f54D03acc01CF624b54e0F24794a2f8f229a is not registered."); + }); + + it("Collect royalty tokens fail as undefined royaltyVaultIpId", async function () { + let royaltyVaultIpId: any; + const response = await expect( + collectRoyaltyTokens("B", ipIdA, royaltyVaultIpId, waitForTransaction) + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Collect royalty tokens fail as invalid royaltyVaultIpId", async function () { + const response = await expect( + collectRoyaltyTokens("B", ipIdA, "0x0000", waitForTransaction) + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Collect royalty tokens fail as non-existent royaltyVaultIpId", async function () { + const response = await expect( + collectRoyaltyTokens("B", ipIdA, "0xe967f54D03acc01CF624b54e0F24794a2f8f229b", waitForTransaction) + ).to.be.rejectedWith("Failed to collect royalty tokens: The royalty vault IP with id 0xE967F54d03aCC01Cf624b54E0f24794A2F8F229b is not registered."); + }); + + it("Collect royalty tokens with waitForTransaction: true", async function () { + const response = await expect( + collectRoyaltyTokens("B", ipIdA, ipIdB, true) + ).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 * 1000000)); + }); + + it("Collect royalty tokens fail as already claimed", async function () { + const response = await expect( + collectRoyaltyTokens("A", ipIdA, ipIdB, true) + ).to.be.rejectedWith("Failed to collect royalty tokens: The contract function \"collectRoyaltyTokens\" reverted.", + "Error: IpRoyaltyVault__AlreadyClaimed()"); + }); + + it("Collect royalty tokens for derivative IP only attached 1 license terms", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + + const responseregisterIpAssetC = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + ipIdC = responseregisterIpAssetC.ipId; + + const responseRegisterDerivative2 = await expect( + registerDerivative("C", ipIdC, [ipIdA], [comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterDerivative2.txHash).to.be.a("string").and.not.empty; + + const response = await expect( + collectRoyaltyTokens("C", ipIdA, ipIdC, true) + ).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 * 1000000)); + }); + + it("Collect royalty tokens for derivative IP attached multiple license terms", async function () { + tokenIdD = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdD); + + const responseregisterIpAssetD = await expect( + registerIpAsset("B", nftContractAddress, tokenIdD, waitForTransaction) + ).to.not.be.rejected; + + ipIdD = responseregisterIpAssetD.ipId; + + const responseRegisterDerivative3 = await expect( + registerDerivative("B", ipIdD, [ipIdA, ipIdA], [comRemixLicenseTermsId1, comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterDerivative3.txHash).to.be.a("string").and.not.empty; + + const response = await expect( + collectRoyaltyTokens("B", ipIdA, ipIdD, true) + ).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 + commercialRevShare2) * 1000000)); + }); + + it("Collect royalty tokens fail as royaltyVaultIpId is not derivative IP", async function () { + const response = await expect( + collectRoyaltyTokens("B", ipIdA, ipIdE, waitForTransaction) + ).to.be.rejectedWith("Failed to collect royalty tokens: Cannot read properties of undefined (reading 'royaltyTokensCollected')"); + }); + + it("Collect royalty tokens fail as royaltyVaultIpId is the root IP id", async function () { + const response = await expect( + collectRoyaltyTokens("A", ipIdA, ipIdA, waitForTransaction) + ).to.be.rejectedWith("Failed to collect royalty tokens: The contract function \"collectRoyaltyTokens\" reverted.", + "Error: IpRoyaltyVault__ClaimerNotAnAncestor()"); + }); + + it("Collect royalty tokens fail as parentIpId is not the root IP id", async function () { + const response = await expect( + collectRoyaltyTokens("A", ipIdB, ipIdC, waitForTransaction) + ).to.be.rejectedWith("Failed to collect royalty tokens: The contract function \"collectRoyaltyTokens\" reverted.", + "Error: IpRoyaltyVault__ClaimerNotAnAncestor()"); + }); + + it("Collect royalty tokens with waitForTransaction: false", async function () { + const responseRegisterDerivative4 = await expect( + registerDerivative("C", ipIdE, [ipIdC], [comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterDerivative4.txHash).to.be.a("string").and.not.empty; + + const response = await expect( + collectRoyaltyTokens("A", ipIdC, ipIdE, false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); +}); diff --git a/test/royalty/payRoyaltyOnBehalf.test.ts b/test/royalty/payRoyaltyOnBehalf.test.ts new file mode 100644 index 0000000..a07f9a5 --- /dev/null +++ b/test/royalty/payRoyaltyOnBehalf.test.ts @@ -0,0 +1,220 @@ +import { privateKeyA, privateKeyB, privateKeyC, nftContractAddress, mintingFeeTokenAddress } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult } from '../../utils/utils'; +import { registerIpAsset, payRoyaltyOnBehalf, attachLicenseTerms, registerDerivative } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { comUseLicenseTermsId1 } from '../setup'; + +const waitForTransaction: boolean = true; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; + +describe("SDK Test", function () { + describe("Test royalty.payRoyaltyOnBehalf Function", async function () { + before("Register parent and derivative IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const responseAttachLicenseTerms = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const responseregisterIpAssetB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; + expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseregisterIpAssetB.ipId; + + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); + + const responseregisterIpAssetC = await expect( + registerIpAsset("C", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + ipIdC = responseregisterIpAssetC.ipId; + }); + + it("Pay royalty on behalf fail as undefined receiverIpId", async function () { + let receiverIpId: any; + const response = await expect( + payRoyaltyOnBehalf("B", receiverIpId, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.receiverIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Pay royalty on behalf fail as invalid receiverIpId", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", "0x0000", ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.receiverIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Pay royalty on behalf fail as non-existent receiverIpId", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", "0xe967f54D03acc01CF624b54e0F24794a2f8f229a", ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: The receiver IP with id 0xe967f54D03acc01CF624b54e0F24794a2f8f229a is not registered."); + }); + + it("Pay royalty on behalf fail as undefined payerIpId", async function () { + let payerIpId: any; + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, payerIpId, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.payerIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Pay royalty on behalf fail as invalid payerIpId", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, "0x0000", mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.payerIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Pay royalty on behalf fail as non-existent payerIpId", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, "0xe967f54D03acc01CF624b54e0F24794a2f8f229b", mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: The payer IP with id 0xe967f54D03acc01CF624b54e0F24794a2f8f229b is not registered."); + }); + + it("Pay royalty on behalf fail as undefined token address", async function () { + let mintingFeeTokenAddress: any; + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.token address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Pay royalty on behalf fail as invalid token address", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, ipIdB, "0x0000", "100", waitForTransaction) + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.token address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + }); + + it("Pay royalty on behalf fail as non-existent token address", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, ipIdB, "0xe967f54D03acc01CF624b54e0F24794a2f8f229c", "100", waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: The contract function \"payRoyaltyOnBehalf\" reverted.", "Error: RoyaltyModule__NotWhitelistedRoyaltyToken()"); + }); + + it("Pay royalty on behalf fail as undefined pay amount", async function () { + let amount: any; + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, ipIdB, mintingFeeTokenAddress, amount, waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: Cannot convert undefined to a BigInt"); + }); + + it("Pay royalty on behalf fail as invalid pay amount", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, ipIdB, mintingFeeTokenAddress, "test", waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: Cannot convert test to a BigInt"); + }); + + it("Pay royalty on behalf with waitForTransaction: true", async function () { + const response = await expect( + payRoyaltyOnBehalf("B", ipIdA, ipIdB, mintingFeeTokenAddress, "100", true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty;; + }); + + it("Pay royalty on behalf with waitForTransaction: false", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdA, ipIdB, mintingFeeTokenAddress, "100", false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Pay royalty on behalf with waitForTransaction: undefined", async function () { + let waitForTransaction: any; + const response = await expect( + payRoyaltyOnBehalf("C", ipIdA, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Pay royalty on behalf by non-owner", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdA, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Pay royalty on behalf fail as payer is parent IP", async function () { + const response = await expect( + payRoyaltyOnBehalf("A", ipIdB, ipIdA, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.be.rejectedWith("Failed to pay royalty on behalf: The contract function \"payRoyaltyOnBehalf\" reverted.", + "Error: RoyaltyModule__NoRoyaltyPolicySet()"); + }); + + it("Pay royalty on behalf - derivate IP to parent IP", async function () { + const response = await expect( + payRoyaltyOnBehalf("A", ipIdA, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Pay royalty on behaf - derivate IP to any unrelated IP", async function () { + const response = await expect( + payRoyaltyOnBehalf("A", ipIdC, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Pay royalty on behalf - any unrelated IP to parent IP", async function () { + const response = await expect( + payRoyaltyOnBehalf("A", ipIdA, ipIdC, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Pay royalty on behalf - any unrelated IP to derivative IP", async function () { + const response = await expect( + payRoyaltyOnBehalf("A", ipIdB, ipIdC, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + it("Pay royalty on behalf - same receiver and payer", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdB, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); +}); \ No newline at end of file diff --git a/test/royalty/snapshot.test.ts b/test/royalty/snapshot.test.ts new file mode 100644 index 0000000..6061c6e --- /dev/null +++ b/test/royalty/snapshot.test.ts @@ -0,0 +1,140 @@ +import { privateKeyA, privateKeyB, nftContractAddress } from '../../config/config'; +import { mintNFTWithRetry, checkMintResult, sleep } from '../../utils/utils'; +import { registerIpAsset, royaltySnapshot, attachLicenseTerms, registerDerivative } from '../../utils/sdkUtils'; +import { Address } from 'viem'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; +chai.use(chaiAsPromised); +import '../setup'; +import { comUseLicenseTermsId1 } from '../setup'; + +const waitForTransaction: boolean = true; + +let tokenIdA: string; +let tokenIdB: string; +let tokenIdC: string; +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; + +describe("SDK Test", function () { + describe("Test royalty.snapshot function", async function () { + before("Register parent and derivative IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAsset = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpAsset.ipId; + + const responseAttachLicenseTerms = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + const responseregisterIpAssetB = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; + expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseregisterIpAssetB.ipId; + + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + + tokenIdC = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); + + const responseRegisterIpAssetC = await expect( + registerIpAsset("A", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAssetC.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAssetC.ipId).to.be.a("string").and.not.empty; + + ipIdC = responseRegisterIpAssetC.ipId; + }); + + it("Captue snapshot fail as undefined ipId", async function () { + let ipIdA: any; + const response = await expect( + royaltySnapshot("A", ipIdA, waitForTransaction) + ).to.be.rejectedWith(`Failed to snapshot: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + + }); + + it("Captue snapshot fail as invalid ipId", async function () { + const response = await expect( + royaltySnapshot("A", "0x0000", waitForTransaction) + ).to.be.rejectedWith(`Failed to snapshot: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); + + }); + + it("Captue snapshot fail as non-existent ipId", async function () { + let ipIdA: any; + const response = await expect( + royaltySnapshot("A", "0x7F51F6AC36B5d618545345baDbe22E40ed113e2a", waitForTransaction) + ).to.be.rejectedWith("Failed to snapshot: The royalty vault IP with id 0x7f51f6AC36B5D618545345badBe22e40eD113e2A is not registered."); + }); + + it("Captue snapshot by non-owner", async function () { + const response = await expect( + royaltySnapshot("B", ipIdA, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; + }); + + it("Captue snapshot for no valut account", async function () { + const response = await expect( + royaltySnapshot("C", ipIdC, true) + ).to.be.rejectedWith("Failed to snapshot: The contract function \"snapshot\" returned no data (\"0x\")."); + }); + + it("Captue snapshot with waitForTransaction: true", async function () { + await sleep(20); + const response = await expect( + royaltySnapshot("C", ipIdB, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; + }); + + it("Captue snapshot with waitForTransaction: false", async function () { + const response = await expect( + royaltySnapshot("A", ipIdA, false) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.snapshotId).to.not.be.exist; + }); + + it("Captue snapshot with waitForTransaction: undefined", async function () { + await sleep(10); + let waitForTransaction: any; + const response = await expect( + royaltySnapshot("C", ipIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.snapshotId).to.not.be.exist; + }); + }); +}); \ No newline at end of file diff --git a/test/setup.ts b/test/setup.ts new file mode 100644 index 0000000..4e33975 --- /dev/null +++ b/test/setup.ts @@ -0,0 +1,86 @@ +import addContext = require("mochawesome/addContext"); +import { captureConsoleLogs } from "../utils/utils"; +import { mintingFeeTokenAddress } from '../config/config'; +import { registerNonComSocialRemixingPIL, registerCommercialUsePIL, registerCommercialRemixPIL } from '../utils/sdkUtils'; +import { expect } from 'chai'; + +let consoleLogs: string[] = []; +let nonComLicenseTermsId: bigint; +let comUseLicenseTermsId1: bigint; +let comUseLicenseTermsId2: bigint; +let comRemixLicenseTermsId1: bigint; +let comRemixLicenseTermsId2: bigint; + +const mintingFee1: string = "100"; +const mintingFee2: string = "60"; +const commercialRevShare1: number = 10; +const commercialRevShare2: number = 20; + +beforeEach(function () { + consoleLogs = captureConsoleLogs(consoleLogs); +}); + +afterEach(function () { + if (consoleLogs.length > 0) { + addContext(this, { + title: 'Test Result', + value: consoleLogs.join('\n'), + }); + consoleLogs = []; + }; +}); + +before("Register License Terms", async function () { + it("Register Non-Commercial Social Remixing License Terms", async function () { + const responseNonComLicenseTerms = await expect( + registerNonComSocialRemixingPIL("A", true) + ).to.not.be.rejected; + + expect(responseNonComLicenseTerms.licenseTermsId).to.be.a("bigint").and.to.be.ok; + nonComLicenseTermsId = responseNonComLicenseTerms.licenseTermsId; + }); + + it("Register Commercial Use License Terms", async function () { + const responseComUseLicenseTerms1 = await expect( + registerCommercialUsePIL("A", mintingFee1, mintingFeeTokenAddress, true) + ).to.not.be.rejected; + + expect(responseComUseLicenseTerms1.licenseTermsId).to.be.a("bigint").and.to.be.ok; + comUseLicenseTermsId1 = responseComUseLicenseTerms1.licenseTermsId; + + const responseComUseLicenseTerms2 = await expect( + registerCommercialUsePIL("A", mintingFee2, mintingFeeTokenAddress, true) + ).to.not.be.rejected; + + expect(responseComUseLicenseTerms1.licenseTermsId).to.be.a("bigint").and.to.be.ok; + comUseLicenseTermsId2 = responseComUseLicenseTerms2.licenseTermsId; + }); + + it("Register Commercial Remix License Terms", async function () { + const responseComRemixLicenseTerms1 = await expect( + registerCommercialRemixPIL("A", mintingFee1, commercialRevShare1, mintingFeeTokenAddress, true) + ).to.not.be.rejected; + + expect(responseComRemixLicenseTerms1.licenseTermsId).to.be.a("bigint").and.to.be.ok; + comRemixLicenseTermsId1 = responseComRemixLicenseTerms1.licenseTermsId; + + const responseComRemixLicenseTerms2 = await expect( + registerCommercialRemixPIL("A", mintingFee2, commercialRevShare2, mintingFeeTokenAddress, true) + ).to.not.be.rejected; + + expect(responseComRemixLicenseTerms1.licenseTermsId).to.be.a("bigint").and.to.be.ok; + comRemixLicenseTermsId2 = responseComRemixLicenseTerms2.licenseTermsId; + }); +}); + +export { + nonComLicenseTermsId, + comUseLicenseTermsId1, + comUseLicenseTermsId2, + comRemixLicenseTermsId1, + comRemixLicenseTermsId2, + mintingFee1, + mintingFee2, + commercialRevShare1, + commercialRevShare2 +}; diff --git a/test/testUtils.ts b/test/testUtils.ts new file mode 100644 index 0000000..47d5e28 --- /dev/null +++ b/test/testUtils.ts @@ -0,0 +1,213 @@ +import { nftContractAddress, mintingFeeTokenAddress} from '../config/config'; +import { checkMintResult, mintNFTWithRetry } from '../utils/utils'; +import { registerIpAsset, attachLicenseTerms, registerDerivative, royaltySnapshot, collectRoyaltyTokens, royaltyClaimableRevenue, royaltyClaimRevenue, getRoyaltyVaultAddress, ipAccountExecute, storyClients, ipAccountExecuteWithSig } from '../utils/sdkUtils'; +import { expect } from 'chai'; + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import { Address, Hex, encodeFunctionData } from 'viem'; + +const waitForTransaction: boolean = true; + +export const mintNFTCreateRootIPandAttachPIL = async function( + wallet: keyof typeof storyClients, + walletPrivateKey: Address, + licenseTermsId: string | number | bigint +): Promise
{ + const tokenId = await mintNFTWithRetry(walletPrivateKey); + checkMintResult(tokenId); + + const responseRegisterIpAsset = await expect( + registerIpAsset(wallet, nftContractAddress, tokenId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + const ipId = responseRegisterIpAsset.ipId; + + const responseAttachLicenseTerms = await expect( + attachLicenseTerms(wallet, ipId, licenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + + return ipId; +}; + +export const mintNFTAndRegisterDerivative = async function( + wallet: keyof typeof storyClients, + walletPrivateKey: Address, + parentIpIds: Address[], + licenseTermsIds: string[] | bigint[] | number[] +): Promise
{ + const tokenId = await mintNFTWithRetry(walletPrivateKey); + checkMintResult(tokenId); + + const responseregisterIpAsset = await expect( + registerIpAsset(wallet, nftContractAddress, tokenId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseregisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseregisterIpAsset.ipId).to.be.a("string").and.not.empty; + + const ipId = responseregisterIpAsset.ipId; + + const response = await expect( + registerDerivative(wallet, ipId, parentIpIds, licenseTermsIds, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + + return ipId; +}; + +export const checkRoyaltyTokensCollected = async function( + caller: keyof typeof storyClients, + parentIpId: Address, + royaltyVaultIpId: Address, + expectedRoyaltyTokensCollected: bigint +){ + const responseAFromB = await expect( + collectRoyaltyTokens(caller, parentIpId, royaltyVaultIpId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAFromB.txHash).to.be.a("string").and.not.empty; + expect(responseAFromB.royaltyTokensCollected).to.be.a('bigint').and.to.be.equal(expectedRoyaltyTokensCollected); +}; + +export const getSnapshotId = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address +): Promise{ + const response = await expect( + royaltySnapshot(caller, royaltyVaultIpId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; + + const snapshotId = response.snapshotId; + return snapshotId; +}; + +export const checkClaimableRevenue = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address, + account: Address, + snapshotId: bigint, + expectedClaimableRevenue: bigint +){ + const response = await expect( + royaltyClaimableRevenue(caller, royaltyVaultIpId, account, snapshotId, mintingFeeTokenAddress, waitForTransaction) + ).to.not.be.rejected; + + // expect(response).to.be.a("bigint").and.to.be.equal(expectedClaimableRevenue); +}; + +export const claimRevenueByEOA = async function ( + caller: keyof typeof storyClients, + snapshotIds: bigint[], + royaltyVaultIpId: Address, + expectedClaimableToken: bigint +) { + const response = await expect( + royaltyClaimRevenue(caller, snapshotIds, royaltyVaultIpId, mintingFeeTokenAddress, undefined, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + // expect(response.claimableToken).to.be.a("bigint").to.be.equal(expectedClaimableToken); +}; + +export const claimRevenueByIPA = async function ( + caller: keyof typeof storyClients, + snapshotIds: bigint[], + royaltyVaultIpId: Address, + ipAccount: Address, + expectedClaimableToken: bigint +) { + const response = await expect( + royaltyClaimRevenue(caller, snapshotIds, royaltyVaultIpId, mintingFeeTokenAddress, ipAccount, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + // expect(response.claimableToken).to.be.a("bigint").to.be.equal(expectedClaimableToken); +}; + +export const transferTokenToEOA = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address, + toAddress: Address, + amount: bigint +){ + const royaltyVaultAddress = await getRoyaltyVaultAddress(caller, royaltyVaultIpId); + console.log(royaltyVaultAddress); + + const data = { + abi: [ + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" } + ], + name: "transfer", + outputs: [ + { internalType: "bool", name: "", type: "bool" } + ], + stateMutability: "nonpayable", + type: "function", + }, + ], + functionName: "transfer", + args: [toAddress as Hex, amount] + }; + + // const response = await expect( + const response = await + ipAccountExecute(caller, royaltyVaultAddress, 0, royaltyVaultIpId, encodeFunctionData(data), true) + console.log(response); + // ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; +}; + +export const transferTokenToEOAWithSig = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address, + toAddress: Address, + amount: bigint, + signer: Address, + deadline: number | bigint | string, + signature: Address +){ + const royaltyVaultAddress = await getRoyaltyVaultAddress(caller, royaltyVaultIpId); + console.log(royaltyVaultAddress); + + const data = { + abi: [ + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" } + ], + name: "transfer", + outputs: [ + { internalType: "bool", name: "", type: "bool" } + ], + stateMutability: "nonpayable", + type: "function", + }, + ], + functionName: "transfer", + args: [toAddress as Hex, amount] + }; + + // const response = await expect( + const response = await + ipAccountExecuteWithSig(caller, royaltyVaultAddress, toAddress, 0, encodeFunctionData(data), signer, deadline, signature, true) + console.log(response); + // ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ec628e6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "exclude": ["node_modules", "policy_backup"], + "compilerOptions": { + "composite": true, + "module": "commonjs", + "target": "ES2020", + "esModuleInterop": true, + "strict": true + }, + "include": ["test", "config", "utils"], +} \ No newline at end of file diff --git a/utils/sdkUtils.ts b/utils/sdkUtils.ts new file mode 100644 index 0000000..6389fec --- /dev/null +++ b/utils/sdkUtils.ts @@ -0,0 +1,589 @@ +import { Hex, Address, encodeFunctionData } from "viem"; +import { clientA, clientB, clientC, } from '../config/config'; +import { PIL_TYPE } from "@story-protocol/core-sdk"; +import { processResponse } from "./utils"; + +export const storyClients = { + A: clientA, + B: clientB, + C: clientC, +}; + +function getStoryClient(wallet: keyof typeof storyClients) { + return storyClients[wallet]; +}; + +interface PolicyOptions { + [key: string]: any; +}; + +function formatValue(value: any): string { + if (typeof value === 'bigint') { + return value.toString() + 'n'; + } + return String(value); +}; + +export const registerIpAsset = async function ( + wallet: keyof typeof storyClients, + nftContractAddress: Address, + tokenId: string | number | bigint, + waitForTransaction: boolean | undefined, + metadataURI?: string | undefined, + metadataHash?: `0x${string}` | undefined, + nftMetadataHash?: `0x${string}` | undefined, + deadline?: string | number | bigint | undefined +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAsset.register({ + nftContract: nftContractAddress, + tokenId: tokenId, + metadata: { + metadataURI: metadataURI, + metadataHash: metadataHash, + nftMetadataHash: nftMetadataHash + }, + deadline: deadline, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const registerDerivative = async function ( + wallet: keyof typeof storyClients, + childIpId: Hex, + parentIpIds: `0x${string}`[], + licenseTermsIds: string[] | bigint[] | number[], + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAsset.registerDerivative({ + childIpId: childIpId, + parentIpIds: parentIpIds, + licenseTermsIds: licenseTermsIds, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const registerDerivativeIp = async function ( + wallet: keyof typeof storyClients, + nftContract: Hex, + tokenId: string | number | bigint, + parentIpIds: `0x${string}`[], + licenseTermsIds: string[] | bigint[] | number[], + waitForTransaction?: boolean, + licenseTemplate?: `0x${string}` | undefined, + metadataURI?: string | undefined, + metadataHash?: `0x${string}` | undefined, + nftMetadataHash?: `0x${string}` | undefined, + deadline?: string | number | bigint | undefined +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAsset.registerDerivativeIp({ + nftContract: nftContract, + tokenId: tokenId, + derivData: { + parentIpIds: parentIpIds, + licenseTermsIds: licenseTermsIds, + licenseTemplate: licenseTemplate + }, + metadata: { + metadataURI: metadataURI, + metadataHash: metadataHash, + nftMetadataHash: nftMetadataHash, + }, + deadline: deadline, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const registerDerivativeWithLicenseTokens = async function ( + wallet: keyof typeof storyClients, + childIpId: Address, + licenseTokenIds: string[] | bigint[] | number[], + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAsset.registerDerivativeWithLicenseTokens({ + childIpId: childIpId, + licenseTokenIds: licenseTokenIds, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const mintAndRegisterIpAssetWithPilTerms = async function ( + wallet: keyof typeof storyClients, + nftContract: Address, + pilType: PIL_TYPE, + waitForTransaction?: boolean, + metadataURI?: string | undefined, + metadataHash?: `0x${string}` | undefined, + nftMetadataHash?: `0x${string}` | undefined, + recipient?: `0x${string}` | undefined, + mintingFee?: string | undefined, + commercialRevShare?: number | undefined, + currency?: `0x${string}` | undefined +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAsset.mintAndRegisterIpAssetWithPilTerms({ + nftContract: nftContract, + pilType: pilType, + metadata: { + metadataURI: metadataURI, + metadataHash: metadataHash, + nftMetadataHash: nftMetadataHash, + }, + recipient: recipient, + mintingFee: mintingFee, + commercialRevShare: commercialRevShare, + currency: currency, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const registerIpAndAttachPilTerms = async function ( + wallet: keyof typeof storyClients, + nftContract: Address, + tokenId: string | number | bigint, + pilType: PIL_TYPE, + waitForTransaction?: boolean, + metadataURI?: string | undefined, + metadataHash?: `0x${string}` | undefined, + nftMetadataHash?: `0x${string}` | undefined, + deadline?: string | number | bigint | undefined, + mintingFee?: string | undefined, + commercialRevShare?: number | undefined, + currency?: `0x${string}` | undefined +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAsset.registerIpAndAttachPilTerms({ + nftContract: nftContract, + tokenId: tokenId, + pilType: pilType, + metadata: { + metadataURI: metadataURI, + metadataHash: metadataHash, + nftMetadataHash: nftMetadataHash, + }, + deadline: deadline, + mintingFee: mintingFee, + commercialRevShare: commercialRevShare, + currency: currency, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const registerNonComSocialRemixingPIL = async function ( + wallet: keyof typeof storyClients, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.license.registerNonComSocialRemixingPIL({ + txOptions: { + waitForTransaction: waitForTransaction, + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const registerCommercialRemixPIL = async function ( + wallet: keyof typeof storyClients, + mintingFee: string | number | bigint, + commercialRevShare: number, + currency: Hex, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.license.registerCommercialRemixPIL({ + mintingFee: mintingFee, + commercialRevShare: commercialRevShare, + currency: currency, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const registerCommercialUsePIL = async function ( + wallet: keyof typeof storyClients, + mintingFee: string | number | bigint, + currency: `0x${string}`, + waitForTransaction?: boolean | undefined +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.license.registerCommercialUsePIL({ + mintingFee: mintingFee, + currency: currency, + txOptions: { + waitForTransaction: waitForTransaction, + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const attachLicenseTerms = async function ( + wallet: keyof typeof storyClients, + ipId: Address, + licenseTermsId: string | number | bigint, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.license.attachLicenseTerms({ + ipId: ipId, + licenseTermsId: licenseTermsId, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const getLicenseTerms = async function ( + wallet: keyof typeof storyClients, + selectedLicenseTermsId: string | number | bigint +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.license.getLicenseTerms(selectedLicenseTermsId); + + const responseJson: { [key: string]: string | bigint } = {}; + Object.entries(response["terms"]).forEach(([key, value]) => { + if (typeof value === "bigint") { + responseJson[key] = value.toString() + 'n'; + } else { + responseJson[key] = value as string; + } + }); + console.log(JSON.stringify(responseJson)); + + return response; +}; + +export const mintLicenseTokens = async function ( + wallet: keyof typeof storyClients, + licensorIpId: Address, + licenseTermsId: string | number | bigint, + amount: number, + receiver: Address, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.license.mintLicenseTokens({ + licensorIpId: licensorIpId, + licenseTermsId: licenseTermsId, + amount: amount, + receiver: receiver, + txOptions: { + waitForTransaction: waitForTransaction, + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const setPermission = async function ( + wallet: keyof typeof storyClients, + ipId: Hex, + signer: Hex, + to: Hex, + permission: number, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.permission.setPermission({ + ipId: ipId, + signer: signer, + to: to, + permission: permission, + txOptions: { + waitForTransaction: waitForTransaction, + } + }) + console.log(JSON.stringify(response)); + return response; +}; + +export const royaltySnapshot = async function ( + wallet: keyof typeof storyClients, + royaltyVaultIpId: Address, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.royalty.snapshot({ + royaltyVaultIpId: royaltyVaultIpId, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const payRoyaltyOnBehalf = async function ( + wallet: keyof typeof storyClients, + receiverIpId: Hex, + payerIpId: Hex, + token: Address, + amount: string | number | bigint, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.royalty.payRoyaltyOnBehalf({ + receiverIpId: receiverIpId, + payerIpId: payerIpId, + token: token, + amount: amount, + txOptions: { + waitForTransaction: waitForTransaction + } + }) + console.log(JSON.stringify(response)); + return response; +}; + +export const collectRoyaltyTokens = async function ( + wallet: keyof typeof storyClients, + parentIpId: Hex, + royaltyVaultIpId: Hex, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.royalty.collectRoyaltyTokens({ + parentIpId: parentIpId, + royaltyVaultIpId: royaltyVaultIpId, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const royaltyClaimableRevenue = async function ( + wallet: keyof typeof storyClients, + royaltyVaultIpId: Address, + account: Address, + snapshotId: string | number | bigint, + token: Address, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.royalty.claimableRevenue({ + royaltyVaultIpId: royaltyVaultIpId, + account: account, + snapshotId: snapshotId, + token: token + }) + + console.log(response); + return response; +}; + +export const royaltyClaimRevenue = async function ( + wallet: keyof typeof storyClients, + snapshotIds:string[] | bigint[] | number[], + royaltyVaultIpId: Address, + token: Address, + account?: Address | undefined, + waitForTransaction?: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.royalty.claimRevenue({ + snapshotIds: snapshotIds, + royaltyVaultIpId: royaltyVaultIpId, + account: account, + token: token, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const getRoyaltyVaultAddress = async function ( + wallet: keyof typeof storyClients, + royaltyVaultIpId: Hex +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.royalty.getRoyaltyVaultAddress(royaltyVaultIpId); + + console.log(response); + return response; +}; + +export const raiseDispute = async function ( + wallet: keyof typeof storyClients, + targetIpId: Hex, + arbitrationPolicy: Hex, + linkToDisputeEvidence: string, + targetTag: string, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.dispute.raiseDispute({ + targetIpId: targetIpId, + arbitrationPolicy: arbitrationPolicy, + linkToDisputeEvidence: linkToDisputeEvidence, + targetTag: targetTag, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + + const responseJson = processResponse(response); + console.log(JSON.stringify(responseJson)); + return response; +}; + +export const cancelDispute = async function ( + wallet: keyof typeof storyClients, + disputeId: string | number | bigint, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.dispute.cancelDispute({ + disputeId: disputeId, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const resolveDispute = async function ( + wallet: keyof typeof storyClients, + disputeId: string | number | bigint, + data: Hex, + waitForTransaction: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.dispute.resolveDispute({ + disputeId: disputeId, + data: data, + txOptions: { + waitForTransaction: waitForTransaction + } + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const createNFTCollection = async function ( + wallet: keyof typeof storyClients, + name: string, + symbol: string, + waitForTransaction: boolean, + options?: { [key: string]: any } +) { + const storyClient = getStoryClient(wallet); + storyClient.nftClient.spgClient + const response = await storyClient.nftClient.createNFTCollection({ + name: name, + symbol: symbol, + txOptions: { + waitForTransaction: waitForTransaction + }, + ...options + }); + console.log(JSON.stringify(response)); + return response; +}; + + +export const ipAccountExecute = async function ( + wallet: keyof typeof storyClients, + toAddress: Address, + value: number, + ipId: Address, + data: Address, + waitForTransaction?: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAccount.execute({ + to: toAddress, + value: value, + ipId: ipId, + data: data, + txOptions: { + waitForTransaction: waitForTransaction + }, + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const ipAccountExecuteWithSig = async function ( + wallet: keyof typeof storyClients, + ipId: Address, + to: Address, + value: number, + data: Address, + signer: Address, + deadline: number | bigint | string, + signature: Address, + waitForTransaction?: boolean | undefined +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAccount.executeWithSig({ + ipId: ipId, + to: to, + value: value, + data: data, + deadline: deadline, + signer: signer, + signature: signature, + txOptions: { + waitForTransaction: waitForTransaction, + }, + }); + console.log(JSON.stringify(response)); + return response; +}; + diff --git a/utils/utils.ts b/utils/utils.ts new file mode 100644 index 0000000..afbfba9 --- /dev/null +++ b/utils/utils.ts @@ -0,0 +1,461 @@ +import { Hex, http, Address, createWalletClient, createPublicClient, Chain } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { sepolia } from 'viem/chains'; +import fs from 'fs'; +import { chainStringToViemChain, nftContractAddress, rpcProviderUrl, royaltyPolicyLAPAddress, royaltyApproveAddress, disputeModuleAddress, ipAssetRegistryAddress, licenseTokenAddress } from "../config/config"; +import { getLicenseTokenOwnerAbi, transferLicenseTokenAbi } from '../config/abi'; + +const TEST_ENV = process.env.TEST_ENV as string | undefined; + +let chainId: Chain; +if (TEST_ENV == "sepolia") { + chainId = sepolia; +// } else if (TEST_ENV == "storyTestnet") { +// chainId = chainStringToViemChain("storyTestnet"); +} else { + throw new Error(`Unknown TEST_ENV value: ${TEST_ENV}`); +}; + +export function sleep(second: number) { + return new Promise((resolve) => setTimeout(resolve, second * 1000)); +}; + +export function writeToCSV(filename: string, headers: string[], data: any[]) { + const csvHeader = headers.join(','); + const csvData = data.map(row => headers.map(header => row[header]).join(',')).join('\n'); + const csvContent = `${csvHeader}\n${csvData}`; + fs.writeFileSync(filename, csvContent); +}; + +export function captureConsoleLogs(consoleLogs:string[]){ + consoleLogs = []; + const originalConsoleLog = console.log; + console.log = function (...args: any[]) { + consoleLogs.push(args.join(' ')); + originalConsoleLog.apply(console, args); + }; + return consoleLogs; +}; + +export function getWalletClient(WALLET_PRIVATE_KEY: Hex){ + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const walletClient = createWalletClient({ + chain: chainId, + transport: http(rpcProviderUrl), + account + }); + + return walletClient; +}; + +export async function mintNFT(WALLET_PRIVATE_KEY: Hex, NFT_COLLECTION_ADDRESS?: Address): Promise { + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const walletClient = createWalletClient({ + ...baseConfig, + account + }); + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function' + }; + + const requestArgs = { + address: NFT_COLLECTION_ADDRESS || nftContractAddress, + functionName: 'mint', + args: [account.address], + account: walletClient.account, + abi: [contractAbi] + }; + + // Mint an NFT to your account + await publicClient.simulateContract(requestArgs); + const hash = await walletClient.writeContract(requestArgs); + const { logs } = await publicClient.waitForTransactionReceipt({ + hash: hash + }); + + let tokenId: any; + if (logs[0].topics[3]) { + tokenId = parseInt(logs[0].topics[3], 16); + }; + + console.log(`Minted NFT successful with hash: ` + JSON.stringify(hash) + `\nMinted NFT tokenId: ` + JSON.stringify(tokenId)); + return String(tokenId); +}; + +export async function isRegistered(ipId: Address): Promise { + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [{ internalType: 'address', name: 'id', type: 'address' }], + name: 'isRegistered', + outputs: [ + { internalType: 'bool', name: '', type: 'bool' } + ], + stateMutability: 'view', + type: 'function' + }; + + const requestArgs = { + address: ipAssetRegistryAddress as Address, + functionName: 'isRegistered', + args: [ipId as Address], + abi: [contractAbi] + }; + + const result = await publicClient.readContract(requestArgs); + console.log(result); + + return Boolean(result); +}; + +export async function mintNFTWithTokenID(WALLET_PRIVATE_KEY: Hex, id: number, NFT_COLLECTION_ADDRESS?: Address): Promise { + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const walletClient = createWalletClient({ + ...baseConfig, + account + }); + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: "uint256", name: "tokenId",type: "uint256" } + ], + name: 'mintId', + outputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }; + + const requestArgs = { + address: NFT_COLLECTION_ADDRESS || nftContractAddress, + functionName: 'mintId', + args: [account.address, BigInt(id)], + account: walletClient.account, + abi: [contractAbi] + }; + + //Mint an NFT to your account + const { result } = await publicClient.simulateContract(requestArgs); + const hash = await walletClient.writeContract(requestArgs); + + const { logs } = await publicClient.waitForTransactionReceipt({ + hash: hash + }); + + let tokenId: any; + if (logs[0].topics[3]) { + tokenId = parseInt(logs[0].topics[3], 16); + }; + + console.log(`Minted NFT successful with hash: ` + JSON.stringify(hash) + `\nMinted NFT tokenId: ` + JSON.stringify(tokenId)); + return String(tokenId); +}; + +export async function approveSpender(WALLET_PRIVATE_KEY: Hex, value: number) { + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const walletClient = createWalletClient({ + ...baseConfig, + account + }); + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: "uint256", name: "value",type: "uint256" } + ], + name: 'approve', + outputs: [ + { internalType: 'bool', name: '', type: 'bool' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }; + + const requestArgs = { + account: account, + address: royaltyApproveAddress, + functionName: 'approve', + args: [royaltyPolicyLAPAddress, BigInt(value)], + abi: [contractAbi] + }; + + await publicClient.simulateContract(requestArgs); + const hash = await walletClient.writeContract(requestArgs); + await publicClient.waitForTransactionReceipt({ + hash: hash + }); +}; + +export async function mintAmount(WALLET_PRIVATE_KEY: Hex, amount: number){ + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const walletClient = createWalletClient({ + ...baseConfig, + account + }); + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: "uint256", name: "amount",type: "uint256" } + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }; + + const requestArgs = { + address: royaltyApproveAddress, + functionName: 'mint', + args: [account.address, BigInt(amount)], + abi: [contractAbi], + account: account + }; + + await publicClient.simulateContract(requestArgs); + const hash = await walletClient.writeContract(requestArgs); + await publicClient.waitForTransactionReceipt({ + hash: hash + }); +}; + +export async function setDisputeJudgement(WALLET_PRIVATE_KEY: Hex, disputeId: bigint, decision: boolean, data: Hex) { + try { + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const walletClient = createWalletClient({ + ...baseConfig, + account + }); + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [ + { internalType: "uint256", name: "disputeId", type: "uint256" }, + { internalType: "bool", name: "decision", type: "bool" }, + { internalType: "bytes", name: "data", type: "bytes" } + ], + name: 'setDisputeJudgement', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }; + + const requestArgs = { + address: disputeModuleAddress, + functionName: 'setDisputeJudgement', + args: [disputeId, decision, data], + abi: [contractAbi], + account: account + }; + + await publicClient.simulateContract(requestArgs); + const hash = await walletClient.writeContract(requestArgs); + await publicClient.waitForTransactionReceipt({ + hash: hash + }); + } catch (error) { + console.error(error); + } +}; + +export async function getLatestTokenId(): Promise { + const contractAddress = nftContractAddress; + let latestTokenId: number | undefined; + + try { + const res = await fetch(`https://story-network.explorer.caldera.xyz/api/v2/tokens/${contractAddress}/instances`); + if (res.ok) { + const { items } = await res.json(); + // console.log(items); + latestTokenId = items[0].id; + } + } catch (err) { + console.error(err); + } + + return Number(latestTokenId); +}; + +export async function mintNFTWithRetry(WALLET_PRIVATE_KEY: Hex, NFT_COLLECTION_ADDRESS?: Address): Promise { + let tokenId: string = ''; + + for (let i = 0; i < 3; i++) { + try { + tokenId = await mintNFT(WALLET_PRIVATE_KEY, NFT_COLLECTION_ADDRESS); + break; + } catch (error) { + if (i === 1) { + try{ + const latestTokenId = await getLatestTokenId(); + tokenId = await mintNFTWithTokenID(WALLET_PRIVATE_KEY, Number(latestTokenId) + 1, NFT_COLLECTION_ADDRESS); + break; + } catch (error) { + tokenId = ''; + }; + }; + }; + }; + + return tokenId; +}; + +export async function getTotalRTSupply(): Promise { + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [], + name: 'TOTAL_RT_SUPPLY', + outputs: [ + { internalType: 'uint32', name: '', type: 'uint32' } + ], + stateMutability: 'view', + type: 'function' + }; + + const requestArgs = { + address: royaltyPolicyLAPAddress as Address, + functionName: 'TOTAL_RT_SUPPLY', + abi: [contractAbi] + }; + + const result = await publicClient.readContract(requestArgs); + console.log(result); + + return Number(result); +}; + +export async function checkMintResult(tokenIdA: string){ + if (tokenIdA === '') { + throw new Error('Unable to mint NFT'); + }; +}; + +export async function getBlockTimestamp(): Promise { + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const publicClient = createPublicClient(baseConfig); + + return (await publicClient.getBlock()).timestamp; +}; + +export function processResponse(response: any): { [key: string]: string | string[] } { + const responseJson: { [key: string]: string | string[] } = {}; + Object.entries(response).forEach(([key, value]) => { + if (Array.isArray(value)) { + responseJson[key] = value.map((item: any) => { + if(typeof item === 'bigint') { + return item.toString() + 'n'; + } else { + return item as string; + } + }); + } else if (typeof value === 'bigint') { + responseJson[key] = value.toString() + 'n'; + } else { + responseJson[key] = value as string; + } + }); + return responseJson; +}; + +export const getDeadline = (deadline?: bigint | number | string): bigint => { + if (deadline && (isNaN(Number(deadline)) || BigInt(deadline) < 0n)) { + throw new Error("Invalid deadline value."); + } + const timestamp = BigInt(Date.now()); + return deadline ? timestamp + BigInt(deadline) : timestamp + 1000n; +}; + +export async function transferLicenseToken(WALLET_PRIVATE_KEY: Hex, from: Address, to: Address, licenseTokenId: number){ + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const walletClient = createWalletClient({ + ...baseConfig, + account + }); + const publicClient = createPublicClient(baseConfig); + + const requestArgs = { + address: licenseTokenAddress, + functionName: 'transferFrom', + args: [from, to, licenseTokenId], + abi: [transferLicenseTokenAbi], + account: account + }; + + await publicClient.simulateContract(requestArgs); + const hash = await walletClient.writeContract(requestArgs); + await publicClient.waitForTransactionReceipt({ + hash: hash + }); + + console.log(`Transaction hash: ${hash}`); + + return hash; +}; + +export async function getLicenseTokenOwner(tokenId: number): Promise
{ + let result: Address | unknown; + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + + const publicClient = createPublicClient(baseConfig); + + const requestArgs = { + address: licenseTokenAddress as Address, + args: [tokenId], + functionName: 'ownerOf', + abi: [getLicenseTokenOwnerAbi] + }; + + result = await publicClient.readContract(requestArgs); + console.log(`Owner: ${result}`); + + return result; +}; + + +