Skip to content

Commit

Permalink
Add unit tests about register and registerDerivative
Browse files Browse the repository at this point in the history
  • Loading branch information
bonnie57 committed Apr 16, 2024
1 parent c15d6fa commit 79db537
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 80 deletions.
10 changes: 5 additions & 5 deletions packages/core-sdk/src/resources/ipAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,16 @@ export class IPAssetClient {
try {
const isChildIpIdRegistered = await this.isRegistered(request.childIpId);
if (!isChildIpIdRegistered) {
throw new Error(`The child IP with id ${request.childIpId} is not registered`);
throw new Error(`The child IP with id ${request.childIpId} is not registered.`);
}
for (const parentId of request.parentIpIds) {
const isParentIpIdRegistered = await this.isRegistered(parentId);
if (!isParentIpIdRegistered) {
throw new Error(`The parent IP with id ${parentId} is not registered`);
throw new Error(`The parent IP with id ${parentId} is not registered.`);
}
}
if (request.parentIpIds.length !== request.licenseTermsIds.length) {
throw new Error("Parent IP IDs and License terms IDs must be provided in pairs");
throw new Error("Parent IP IDs and License terms IDs must be provided in pairs.");
}
for (let i = 0; i < request.parentIpIds.length; i++) {
const isAttachedLicenseTerms =
Expand All @@ -110,7 +110,7 @@ export class IPAssetClient {
});
if (!isAttachedLicenseTerms) {
throw new Error(
`License terms id ${request.licenseTermsIds[i]} must be attached to the parent ipId ${request.parentIpIds[i]} before registering derivative`,
`License terms id ${request.licenseTermsIds[i]} must be attached to the parent ipId ${request.parentIpIds[i]} before registering derivative.`,
);
}
}
Expand Down Expand Up @@ -172,7 +172,7 @@ export class IPAssetClient {
return { txHash: txHash };
}
} catch (error) {
handleError(error, "Failed to register derivative with license tokens");
handleError(error, "Failed to register derivative with license tokens.");
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core-sdk/test/unit/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe("Test StoryClient", function () {
});

it("should return client license", () => {
const license = new LicenseClient(rpcClient, wallet, storyAPIClient);
const license = new LicenseClient(rpcClient, wallet);
expect(client.license).to.not.equal(null);
expect(client.license).to.not.equal(undefined);
});
Expand Down
228 changes: 154 additions & 74 deletions packages/core-sdk/test/unit/resources/ipAsset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const expect = chai.expect;

const tokenContract: Hex = "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c";
const tokenId = "3";
const txHash: Hex = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997";
describe("Test IpAssetClient", function () {
let ipAssetClient: IPAssetClient;
let rpcMock: PublicClient;
Expand All @@ -28,26 +29,10 @@ describe("Test IpAssetClient", function () {
});

describe("Test ipAssetClient.register", async function () {
it("should throw readContract error if readContract throws an error", async () => {
rpcMock.readContract = sinon.stub().rejects(new Error("readContract error"));
try {
await ipAssetClient.register({
tokenContract: tokenContract,
tokenId: tokenId,
txOptions: {
waitForTransaction: false,
},
});
} catch (err) {
expect((err as Error).message).includes("readContract error");
}
});

const ipId = "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4";
it("should return ipId when register given tokenId have registered", async function () {
const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997";
rpcMock.readContract = sinon.stub().onCall(0).resolves(txHash).onCall(1).resolves(true);
rpcMock.simulateContract = sinon.stub().resolves({ request: null });
walletMock.writeContract = sinon.stub().resolves(txHash);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(true);

const res = await ipAssetClient.register({
tokenContract: tokenContract,
Expand All @@ -57,16 +42,14 @@ describe("Test IpAssetClient", function () {
},
});

expect(res.ipId).equal(txHash);
expect(res.ipId).equal(ipId);
expect(res.txHash).to.be.undefined;
});

it("should return txHash and txHash when register given tokenId have no registered", async function () {
const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997";
rpcMock.readContract = sinon.stub().onCall(0).resolves(txHash).onCall(1).resolves(false);
rpcMock.simulateContract = sinon.stub().resolves({ request: null });
walletMock.writeContract = sinon.stub().resolves(txHash);

it("should return txHash when register given tokenId have no registered", async function () {
sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "register").resolves(txHash);
const res = await ipAssetClient.register({
tokenContract: tokenContract,
tokenId: tokenId,
Expand All @@ -78,46 +61,21 @@ describe("Test IpAssetClient", function () {
expect(res.txHash).equal(txHash);
});

it("should return txHash when register", async function () {
const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997";
rpcMock.readContract = sinon.stub().resolves();
rpcMock.simulateContract = sinon.stub().resolves({ request: null });
walletMock.writeContract = sinon.stub().resolves(txHash);

const res = await ipAssetClient.register({
tokenContract: tokenContract,
tokenId: tokenId,
});

expect(res.txHash).equal(txHash);
});

it("should return ipId and txHash when register a IP and given waitForTransaction of true and tokenId is not registered ", async function () {
const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997";
rpcMock.readContract = sinon.stub().resolves();
rpcMock.simulateContract = sinon.stub().resolves({ request: null });
walletMock.writeContract = sinon.stub().resolves(txHash);
rpcMock.waitForTransactionReceipt = sinon.stub().resolves({
logs: [
{
address: "0x30c89bcb41277f09b18df0375b9438909e193bf0",
topics: [
"0x02ad3a2e0356b65fdfe4a73c825b78071ae469db35162978518b8c258abb3767",
"0x00000000000000000000000000000000000000000000000000000000000005e9",
"0x0000000000000000000000007c0004c6d352bc0a0531aad46d33a03d9d51ab1d",
"0x000000000000000000000000000000000000000000000000000000000000000d",
],
data: "0x000000000000000000000000d142822dc1674154eaf4ddf38bbf7ef8f0d8ece4000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000660cc2100000000000000000000000000000000000000000000000000000000000000014313531333a204d6f636b45524337323120233133000000000000000000000000000000000000000000000000000000000000000000000000000000000000002368747470733a2f2f73746f727970726f746f636f6c2e78797a2f6572633732312f31330000000000000000000000000000000000000000000000000000000000",
blockNumber: 478104n,
transactionHash: "0x10b563fc5722b9648ad95389280e71a16e10fab8cbd0aff1da18516c35704562",
transactionIndex: 1,
blockHash: "0xe9a24656b3c6c4ea66ad467300e39b63ae89af97481744d737d63ebe91857e34",
logIndex: 2,
removed: false,
},
],
});

sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "register").resolves(txHash);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "parseTxIpRegisteredEvent").returns([
{
ipId: ipId,
chainId: 0n,
tokenContract: tokenContract,
tokenId: 0n,
name: "",
uri: "",
registrationDate: 0n,
},
]);
const response = await ipAssetClient.register({
tokenContract: tokenContract,
tokenId: tokenId,
Expand All @@ -126,23 +84,145 @@ describe("Test IpAssetClient", function () {
},
});
expect(response.txHash).equal(txHash);
expect(response.ipId).equals("0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4");
expect(response.ipId).equals(ipId);
});

it("should throw error when request fails", async function () {
rpcMock.simulateContract = sinon.stub().resolves({ request: null });
rpcMock.readContract = sinon.stub().resolves();
walletMock.writeContract = sinon.stub().rejects(new Error("http 500"));

await expect(
ipAssetClient.register({
sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false);
sinon.stub(ipAssetClient.ipAssetRegistryClient, "register").throws(new Error("revert error"));
try {
await ipAssetClient.register({
tokenContract: tokenContract,
tokenId: tokenId,
txOptions: {
waitForTransaction: true,
},
}),
).to.be.rejectedWith("http 500");
});
} catch (err) {
expect((err as Error).message).equal("Failed to register IP: revert error");
}
});
});

describe("Test ipAssetClient.registerDerivative", async function () {
it("should throw childIpId error when registerDerivative given childIpId is not registered", async () => {
sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false);
try {
await ipAssetClient.registerDerivative({
childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c",
parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"],
licenseTermsIds: ["1"],
});
} catch (err) {
expect((err as Error).message).equal(
"Failed to register derivative: The child IP with id 0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c is not registered.",
);
}
});

it("should throw parentIpId error when registerDerivative given parentIpId is not registered", async () => {
sinon
.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered")
.onCall(0)
.resolves(true)
.onCall(1)
.resolves(false);
try {
await ipAssetClient.registerDerivative({
childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c",
parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"],
licenseTermsIds: ["1"],
});
} catch (err) {
expect((err as Error).message).equal(
"Failed to register derivative: The parent IP with id 0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a is not registered.",
);
}
});

it("should throw parentIpIds not match License terms ids error when registerDerivative given parentIds'length is not equal licenseTermsIds'length", async () => {
sinon
.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered")
.onCall(0)
.resolves(true)
.onCall(1)
.resolves(true);
sinon
.stub(ipAssetClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms")
.resolves(false);
try {
await ipAssetClient.registerDerivative({
childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c",
parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"],
licenseTermsIds: ["1", "2"],
});
} catch (err) {
expect((err as Error).message).equal(
"Failed to register derivative: Parent IP IDs and License terms IDs must be provided in pairs.",
);
}
});

it("should throw parentIpIds not match License terms ids error when registerDerivative given parentIds'length is not equal licenseTermsIds'length", async () => {
sinon
.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered")
.onCall(0)
.resolves(true)
.onCall(1)
.resolves(true);
try {
await ipAssetClient.registerDerivative({
childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c",
parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"],
licenseTermsIds: ["1", "2"],
});
} catch (err) {
expect((err as Error).message).equal(
"Failed to register derivative: Parent IP IDs and License terms IDs must be provided in pairs.",
);
}
});

it("should return txHash when registerDerivative given childIpId and parentIpIds are registered, and parentIpIds match License terms ids", async () => {
sinon
.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered")
.onCall(0)
.resolves(true)
.onCall(1)
.resolves(true);
sinon
.stub(ipAssetClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms")
.resolves(true);
sinon.stub(ipAssetClient.licensingModuleClient, "registerDerivative").resolves(txHash);
const res = await ipAssetClient.registerDerivative({
childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c",
parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"],
licenseTermsIds: ["1"],
});
expect(res.txHash).equal(txHash);
});

it("should return txHash when registerDerivative given correct childIpId, parentIpId, licenseTermsIds and waitForTransaction of true ", async () => {
sinon
.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered")
.onCall(0)
.resolves(true)
.onCall(1)
.resolves(true);
sinon
.stub(ipAssetClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms")
.resolves(true);
sinon.stub(ipAssetClient.licensingModuleClient, "registerDerivative").resolves(txHash);
const res = await ipAssetClient.registerDerivative({
childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c",
parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"],
licenseTermsIds: ["1"],
txOptions: {
waitForTransaction: true,
},
});
expect(res.txHash).equal(txHash);
});
});
});
3 changes: 3 additions & 0 deletions packages/core-sdk/test/unit/testUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import sinon from "sinon";

export function createMock<T>(obj = {}): T {
const mockObj: any = obj;
mockObj.waitForTransactionReceipt = sinon.stub().resolves({});
return mockObj;
}

Expand Down

0 comments on commit 79db537

Please sign in to comment.