Skip to content

Commit

Permalink
test: add integration and unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Ivaylo Nikolov <[email protected]>
  • Loading branch information
ivaylonikolov7 committed Dec 16, 2024
1 parent 863a356 commit 489de75
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 13 deletions.
43 changes: 43 additions & 0 deletions test/integration/MirrorNodeContractCallQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { setTimeout } from "timers/promises";
import {
MirrorNodeContractCallQuery,
ContractCreateTransaction,
FileCreateTransaction,
ContractFunctionParameters,
} from "../../src/exports.js";
import IntegrationTestEnv from "./client/NodeIntegrationTestEnv.js";

describe("MirrorNodeContractCallQuery", function () {
let env;

beforeEach(async function () {
env = await IntegrationTestEnv.new();
});

it("should get contract message", async function () {
const BYTECODE =
"60806040526040518060400160405280600581526020017f68656c6c6f0000000000000000000000000000000000000000000000000000008152505f90816100479190610293565b50348015610053575f80fd5b50610362565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806100d457607f821691505b6020821081036100e7576100e6610090565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026101497fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261010e565b610153868361010e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61019761019261018d8461016b565b610174565b61016b565b9050919050565b5f819050919050565b6101b08361017d565b6101c46101bc8261019e565b84845461011a565b825550505050565b5f90565b6101d86101cc565b6101e38184846101a7565b505050565b5b81811015610206576101fb5f826101d0565b6001810190506101e9565b5050565b601f82111561024b5761021c816100ed565b610225846100ff565b81016020851015610234578190505b610248610240856100ff565b8301826101e8565b50505b505050565b5f82821c905092915050565b5f61026b5f1984600802610250565b1980831691505092915050565b5f610283838361025c565b9150826002028217905092915050565b61029c82610059565b67ffffffffffffffff8111156102b5576102b4610063565b5b6102bf82546100bd565b6102ca82828561020a565b5f60209050601f8311600181146102fb575f84156102e9578287015190505b6102f38582610278565b86555061035a565b601f198416610309866100ed565b5f5b828110156103305784890151825560018201915060208501945060208101905061030b565b8683101561034d5784890151610349601f89168261025c565b8355505b6001600288020188555050505b505050505050565b6102178061036f5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063ce6d41de1461002d575b5f80fd5b61003561004b565b6040516100429190610164565b60405180910390f35b60605f8054610059906101b1565b80601f0160208091040260200160405190810160405280929190818152602001828054610085906101b1565b80156100d05780601f106100a7576101008083540402835291602001916100d0565b820191905f5260205f20905b8154815290600101906020018083116100b357829003601f168201915b5050505050905090565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156101115780820151818401526020810190506100f6565b5f8484015250505050565b5f601f19601f8301169050919050565b5f610136826100da565b61014081856100e4565b93506101508185602086016100f4565b6101598161011c565b840191505092915050565b5f6020820190508181035f83015261017c818461012c565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806101c857607f821691505b6020821081036101db576101da610184565b5b5091905056fea26469706673582212202a86c27939bfab6d4a2c61ebbf096d8424e17e22dfdd42320f6e2654863581e964736f6c634300081a0033";
const { fileId } = await (
await new FileCreateTransaction()
.setContents(BYTECODE)
.execute(env.client)
).getReceipt(env.client);

const { contractId } = await (
await new ContractCreateTransaction()
.setBytecodeFileId(fileId)
.setGas(200000)
.execute(env.client)
).getReceipt(env.client);

// wait 5 seconds for MN to update
await setTimeout(10000);

const result = await new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setBlockNumber("latest")
.setFunction("getMessage", new ContractFunctionParameters())
.execute();
expect(result).to.not.be.null;
});
});
43 changes: 43 additions & 0 deletions test/integration/MirrorNodeContractEstimateQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { setTimeout } from "timers/promises";
import {
MirrorNodeContractCallQuery,
ContractCreateTransaction,
FileCreateTransaction,
ContractFunctionParameters,
} from "../../src/exports.js";
import IntegrationTestEnv from "./client/NodeIntegrationTestEnv.js";

describe("MirrorNodeContractCallQuery", function () {
let env;

beforeEach(async function () {
env = await IntegrationTestEnv.new();
});

it("should get contract message", async function () {
const BYTECODE =
"60806040526040518060400160405280600581526020017f68656c6c6f0000000000000000000000000000000000000000000000000000008152505f90816100479190610293565b50348015610053575f80fd5b50610362565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806100d457607f821691505b6020821081036100e7576100e6610090565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026101497fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261010e565b610153868361010e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61019761019261018d8461016b565b610174565b61016b565b9050919050565b5f819050919050565b6101b08361017d565b6101c46101bc8261019e565b84845461011a565b825550505050565b5f90565b6101d86101cc565b6101e38184846101a7565b505050565b5b81811015610206576101fb5f826101d0565b6001810190506101e9565b5050565b601f82111561024b5761021c816100ed565b610225846100ff565b81016020851015610234578190505b610248610240856100ff565b8301826101e8565b50505b505050565b5f82821c905092915050565b5f61026b5f1984600802610250565b1980831691505092915050565b5f610283838361025c565b9150826002028217905092915050565b61029c82610059565b67ffffffffffffffff8111156102b5576102b4610063565b5b6102bf82546100bd565b6102ca82828561020a565b5f60209050601f8311600181146102fb575f84156102e9578287015190505b6102f38582610278565b86555061035a565b601f198416610309866100ed565b5f5b828110156103305784890151825560018201915060208501945060208101905061030b565b8683101561034d5784890151610349601f89168261025c565b8355505b6001600288020188555050505b505050505050565b6102178061036f5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063ce6d41de1461002d575b5f80fd5b61003561004b565b6040516100429190610164565b60405180910390f35b60605f8054610059906101b1565b80601f0160208091040260200160405190810160405280929190818152602001828054610085906101b1565b80156100d05780601f106100a7576101008083540402835291602001916100d0565b820191905f5260205f20905b8154815290600101906020018083116100b357829003601f168201915b5050505050905090565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156101115780820151818401526020810190506100f6565b5f8484015250505050565b5f601f19601f8301169050919050565b5f610136826100da565b61014081856100e4565b93506101508185602086016100f4565b6101598161011c565b840191505092915050565b5f6020820190508181035f83015261017c818461012c565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806101c857607f821691505b6020821081036101db576101da610184565b5b5091905056fea26469706673582212202a86c27939bfab6d4a2c61ebbf096d8424e17e22dfdd42320f6e2654863581e964736f6c634300081a0033";
const { fileId } = await (
await new FileCreateTransaction()
.setContents(BYTECODE)
.execute(env.client)
).getReceipt(env.client);

const { contractId } = await (
await new ContractCreateTransaction()
.setBytecodeFileId(fileId)
.setGas(200000)
.execute(env.client)
).getReceipt(env.client);

// wait 5 seconds for MN to update
await setTimeout(10000);

const result = await new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setBlockNumber("latest")
.setFunction("getMessage", new ContractFunctionParameters())
.execute();
expect(result).to.not.be.null;
});
});
20 changes: 9 additions & 11 deletions test/integration/client/BaseIntegrationTestEnv.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import {
TokenDeleteTransaction,
Hbar,
AccountId,
Wallet
Wallet,
} from "../../../src/exports.js";
import LocalProvider from '../../../src/LocalProvider.js'
import LocalProvider from "../../../src/LocalProvider.js";

/**
* @typedef {import("../../../src/exports.js").TokenId} TokenId
Expand Down Expand Up @@ -79,11 +79,11 @@ export default class BaseIntegrationTestEnv {
});
} else if (options.env.CONFIG_FILE != null) {
client = await options.client.fromConfigFile(
options.env.CONFIG_FILE
options.env.CONFIG_FILE,
);
} else {
throw new Error(
"Failed to construct client for IntegrationTestEnv"
"Failed to construct client for IntegrationTestEnv",
);
}

Expand All @@ -92,7 +92,9 @@ export default class BaseIntegrationTestEnv {
options.env.OPERATOR_KEY != null
) {
const operatorId = AccountId.fromString(options.env.OPERATOR_ID);
const operatorKey = PrivateKey.fromStringED25519(options.env.OPERATOR_KEY);
const operatorKey = PrivateKey.fromStringECDSA(
options.env.OPERATOR_KEY,
);

client.setOperator(operatorId, operatorKey);
}
Expand Down Expand Up @@ -127,19 +129,15 @@ export default class BaseIntegrationTestEnv {
const response = await new AccountCreateTransaction()
.setKey(newOperatorKey)
.setInitialBalance(
new Hbar(options.balance != null ? options.balance : 100)
new Hbar(options.balance != null ? options.balance : 100),
)
.execute(client);

const newOperatorId = (await response.getReceipt(client)).accountId;

client.setOperator(newOperatorId, newOperatorKey);

wallet = new Wallet(
newOperatorId,
newOperatorKey,
new LocalProvider()
)
wallet = new Wallet(newOperatorId, newOperatorKey, new LocalProvider());

return new BaseIntegrationTestEnv({
client: client,
Expand Down
4 changes: 2 additions & 2 deletions test/integration/client/TestnetIntegrationTestEnv.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export default class TestnetIntegrationTestEnv extends BaseIntegrationTestEnv {
return BaseIntegrationTestEnv.new({
client: Client,
env: {
OPERATOR_ID: "0.0.8920",
OPERATOR_ID: "0.0.4481103",
OPERATOR_KEY:
"07f9f9c355d32c5c93a50024b596ed3ccc39954ba1963c68ac21cb7802fd5f83",
"3d11515c6794311c87dfdeaac90d4c223c22f3634db8f24690b557ea0ca97c11",
HEDERA_NETWORK: "testnet",
},
nodeAccountIds: options.nodeAccountIds,
Expand Down
28 changes: 28 additions & 0 deletions test/unit/MirrorNodeContractCallQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { AccountId, MirrorNodeContractCallQuery } from "../../src/exports.js";

describe("MirrorNodeContractCallQuery", function () {
const SENDER = new AccountId(1);
const CONTRACT_ID = new AccountId(1);
const VALUE = 100;
const GAS_LIMIT = 100;
const GAS_PRICE = 100;
const BLOCK_NUMBER = 100;

it("should throw an error without calldata", async function () {
const query = new MirrorNodeContractCallQuery()
.setBlockNumber(BLOCK_NUMBER)
.setSender(SENDER)
.setValue(VALUE)
.setGasLimit(GAS_LIMIT)
.setGasPrice(GAS_PRICE)
.setContractId(CONTRACT_ID);

let err = false;
try {
await query.execute();
} catch (e) {
err = e.message.includes("Call data is required.");
}
expect(err).to.equal(true);
});
});
31 changes: 31 additions & 0 deletions test/unit/MirrorNodeContractEstimateQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
AccountId,
MirrorNodeContractEstimateQuery,
} from "../../src/exports.js";

describe("MirrorNodeContractCallQuery", function () {
const SENDER = new AccountId(1);
const CONTRACT_ID = new AccountId(1);
const VALUE = 100;
const GAS_LIMIT = 100;
const GAS_PRICE = 100;
const BLOCK_NUMBER = 100;

it("should throw an error without calldata", async function () {
const query = new MirrorNodeContractEstimateQuery()
.setBlockNumber(BLOCK_NUMBER)
.setSender(SENDER)
.setValue(VALUE)
.setGasLimit(GAS_LIMIT)
.setGasPrice(GAS_PRICE)
.setContractId(CONTRACT_ID);

let err = false;
try {
await query.execute();
} catch (e) {
err = e.message.includes("Call data is required.");
}
expect(err).to.equal(true);
});
});
111 changes: 111 additions & 0 deletions test/unit/MirrorNodeContractQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { AccountId } from "../../src/exports.js";
import MirrorNodeContractQuery from "../../src/query/MirrorNodeContractQuery.js";

describe("MirrorNodeContractQuery", function () {
const SENDER = new AccountId(1);
const SENDER_EVM_ADDRESS = "0000000000000000000000000000000000000001";
const CONTRACT_EVM_ADDRESS = "0000000000000000000000000000000000000001";
const CONTRACT_ID = new AccountId(1);
const FUNCTION_NAME = "getMessage";
const FUNCTION_SELECTOR = new Uint8Array([206, 109, 65, 222]); // getMessage()
const VALUE = 100;
const GAS_LIMIT = 100;
const GAS_PRICE = 100;
const BLOCK_NUMBER = 100;

it("should set query parameters", function () {
const query = new MirrorNodeContractQuery()
.setBlockNumber(BLOCK_NUMBER)
.setSender(SENDER)
.setFunction(FUNCTION_NAME)
.setValue(VALUE)
.setGasLimit(GAS_LIMIT)
.setGasPrice(GAS_PRICE)
.setContractId(CONTRACT_ID);

expect(query.sender).to.be.instanceOf(AccountId);
expect(query.senderEvmAddress).to.be.equal(SENDER_EVM_ADDRESS);
expect(query.contractEvmAddress).to.be.equal(CONTRACT_EVM_ADDRESS);
expect(query.callData).to.be.deep.equal(FUNCTION_SELECTOR);
expect(query.value).to.be.equal(VALUE);
expect(query.gasLimit).to.be.equal(GAS_LIMIT);
expect(query.gasPrice).to.be.equal(GAS_PRICE);
expect(query.blockNumber).to.be.equal(BLOCK_NUMBER);
expect(query.contractId).to.be.equal(CONTRACT_ID);
});

it("should throw an error when no contract id sent", async function () {
const query = new MirrorNodeContractQuery()
.setBlockNumber(BLOCK_NUMBER)
.setSender(SENDER)
.setFunction(FUNCTION_NAME)
.setValue(VALUE)
.setGasLimit(GAS_LIMIT)
.setGasPrice(GAS_PRICE);

let err = false;
try {
query.contractEvmAddress;
} catch (e) {
err = e.message.includes("Contract ID is not set");
}
expect(err).to.be.true;
/*
err = false;
try {
await query.execute();
} catch (e) {
console.log(e);
err = e.message.includes("Contract ID is not set");
}
expect(err).to.be.true;
*/
});

it("should throw an error when no sender sent", async function () {
const query = new MirrorNodeContractQuery()
.setBlockNumber(BLOCK_NUMBER)
.setFunction(FUNCTION_NAME)
.setValue(VALUE)
.setGasLimit(GAS_LIMIT)
.setGasPrice(GAS_PRICE)
.setContractId(CONTRACT_ID);
expect(query.sender).to.be.null;

let err = false;
try {
query.senderEvmAddress;
} catch (e) {
err = e.message.includes("Sender is not set");
}
expect(err).to.be.true;

/*
err = false;
try {
await query.execute();
} catch (e) {
err = e.message.includes("Sender is not set");
}
expect(err).to.be.true;
*/
});

it("should not be able to perform MN request without contract id", async function () {
const query = new MirrorNodeContractQuery()
.setBlockNumber(BLOCK_NUMBER)
.setSender(SENDER)
.setFunction(FUNCTION_NAME)
.setValue(VALUE)
.setGasLimit(GAS_LIMIT)
.setGasPrice(GAS_PRICE);

let err = false;
try {
await query.performMirrorNodeRequest("", "");
} catch (e) {
err = e.message.includes("Contract ID is not set");
}
expect(err).to.be.true;
});
});

0 comments on commit 489de75

Please sign in to comment.