Skip to content

Commit

Permalink
a working test setup
Browse files Browse the repository at this point in the history
  • Loading branch information
jfschwarz committed Oct 19, 2023
1 parent 649f58c commit 3d5a1e9
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 387 deletions.
426 changes: 213 additions & 213 deletions .yarn/releases/yarn-3.6.1.cjs → .yarn/releases/yarn-3.6.4.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

yarnPath: .yarn/releases/yarn-3.6.1.cjs
yarnPath: .yarn/releases/yarn-3.6.4.cjs
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
},
"author": "",
"license": "LGPL-3.0+",
"packageManager": "[email protected].1"
"packageManager": "[email protected].4"
}
8 changes: 4 additions & 4 deletions packages/gelato-web3-function/delay-dispatch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ Web3Function.onRun(async (context) => {

const QUERY = `
query DelayTransactions($id: String, $nonce: Int) {
delayMod(id: $id) {
delayModifier(id: $id) {
transactions(where: {nonce_gt: $nonce}) {
nonce
to
Expand Down Expand Up @@ -245,7 +245,7 @@ const fetchUpcomingTransactions = async ({
address: string;
currentNonce: number;
}): Promise<Transaction[]> => {
const data = (await ky
const { data } = (await ky
.post(SUBGRAPH[chainId as keyof typeof SUBGRAPH], {
timeout: 5_000,
retry: 1,
Expand All @@ -257,11 +257,11 @@ const fetchUpcomingTransactions = async ({
})
.json()) as any;

if (!data || !data.delayMod) {
if (!data || !data.delayModifier) {
return [];
}

const transactions = data.delayMod.transactions.map((tx: any) => ({
const transactions = data.delayModifier.transactions.map((tx: any) => ({
...tx,
operation: tx.operation === "Call" ? 0 : 1,
})) as Transaction[];
Expand Down
5 changes: 3 additions & 2 deletions packages/gelato-web3-function/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { Config } from "@jest/types";

const config: Config.InitialOptions = {
roots: ["<rootDir>"],
preset: "ts-jest",
// roots: ["<rootDir>"],
preset: "ts-jest/presets/js-with-ts",
testEnvironment: "node",
testRegex: "(/test|(\\.|/)(test|spec))\\.ts?$",
transformIgnorePatterns: ["node_modules/(?!ky/.*)"],
};
export default config;
4 changes: 2 additions & 2 deletions packages/gelato-web3-function/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
"@gelatonetwork/relay-sdk": "^5.5.1",
"@gelatonetwork/web3-functions-sdk": "^2.1.7",
"ethers": "^5.7.2",
"ky": "^0.32.2"
"ky": "^1.1.0"
},
"installConfig": {
"hoistingLimits": "workspaces"
}
}
}
132 changes: 59 additions & 73 deletions packages/gelato-web3-function/test/function.test.ts
Original file line number Diff line number Diff line change
@@ -1,83 +1,70 @@
import path from "path";
import { Web3Function } from "@gelatonetwork/web3-functions-sdk";
import { Web3FunctionContextData } from "@gelatonetwork/web3-functions-sdk";
import { Web3FunctionLoader } from "@gelatonetwork/web3-functions-sdk/loader";
import { GelatoRelay } from "@gelatonetwork/relay-sdk";
import { runWeb3Function } from "./utils";
import { providers } from "ethers";
import { runWeb3Function } from "./run";
import { BigNumber, providers } from "ethers";

// Mock and spy on Relay SDK sponsoredCall method
const mockImpl: typeof GelatoRelay.prototype.sponsoredCall = async () => {
return {
taskId: "123",
};
};
let sponsoredCallSpy = jest.fn(mockImpl);
jest.mock("@gelatonetwork/relay-sdk", () => {
return {
GelatoRelay: jest.fn().mockImplementation(() => {
return {
sponsoredCall: sponsoredCallSpy,
};
}),
};
});

const w3fName = "delay-dispatch";
const w3fRootDir = path.join(__dirname, "..");
const w3fPath = path.join(w3fRootDir, w3fName, "index.ts");
let estimateGasSpy = jest.fn(async () => BigNumber.from(123_000));

jest.useFakeTimers();
const provider = new providers.JsonRpcProvider(
"https://rpc.ankr.com/eth_goerli"
);
jest.spyOn(provider, "estimateGas").mockImplementation(estimateGasSpy);

describe("delay-dispatch web3 function", () => {
let context: Web3FunctionContextData;
let sponsoredCallSpy: jest.SpyInstance;
const provider = new providers.JsonRpcProvider(
"https://rpc.ankr.com/eth_goerli"
);

beforeAll(async () => {
const { secrets } = Web3FunctionLoader.load(w3fName, w3fRootDir);
const { gasPrice } = await provider.getFeeData();

if (gasPrice === null) throw new Error("gasPrice is null");

context = {
secrets,
storage: {},
gelatoArgs: {
chainId: 5,
gasPrice: gasPrice.toString(),
},
userArgs: {
delayMod: "0x0b7a9a6f1c4e739df11f55c6879d48c9851a2162",
gasAllowance: 10_000_000,
allowanceInterval: 7150,
},
};
// const relay = new GelatoRelay();
// // console.log(GelatoRelay.prototype);
// sponsoredCallSpy = jest
// .spyOn(relay, "sponsoredCall")
// .mockImplementation(async (params, apiKey, options) => {
// return { taskId: "123" };
// });
});
// let context: Web3FunctionContextData;
// const provider = new providers.JsonRpcProvider(
// "https://rpc.ankr.com/eth_goerli"
// );

let userArgs = {
delayMod: "0x0b7a9a6f1c4e739df11f55c6879d48c9851a2162",
gasAllowance: 10_000_000,
allowanceInterval: 7150,
};

beforeEach(() => {
estimateGasSpy.mockClear();
sponsoredCallSpy.mockClear();
});

it("throws if the secret or a userArg is not set", async () => {
await expect(
runWeb3Function(w3fPath, { ...context, secrets: {} }, [provider])
).rejects.toHaveProperty(
"message",
"Fail to run web3 function: Error: Missing RELAY_API_KEY secret"
);
runWeb3Function({ userArgs, secrets: {}, provider })
).rejects.toHaveProperty("message", "Missing RELAY_API_KEY secret");

await expect(
runWeb3Function(w3fPath, { ...context, userArgs: {} }, [provider])
).rejects.toHaveProperty(
"message",
"Fail to run web3 function: Error: Missing delayMod userArg"
);
runWeb3Function({ userArgs: {}, provider })
).rejects.toHaveProperty("message", "Missing delayMod userArg");
});

it("does nothing if the Delay mod does not yet exist", async () => {
const { result } = await runWeb3Function(
w3fPath,
{
...context,
userArgs: {
...context.userArgs,
delayMod: "0x0000000000000000000000000000000000000123",
},
const result = await runWeb3Function({
userArgs: {
...userArgs,
delayMod: "0x0000000000000000000000000000000000000123",
},
[provider]
);
provider,
});
expect(result).toEqual({
canExec: false,
message:
Expand All @@ -86,34 +73,33 @@ describe("delay-dispatch web3 function", () => {
});

it("does nothing if the Delay mod's queue is empty", async () => {
const { result } = await runWeb3Function(
w3fPath,
{
...context,
userArgs: {
...context.userArgs,
delayMod: "0xeff5b8593076b69ff1a6c5d0e13c76c614738738",
},
const result = await runWeb3Function({
userArgs: {
...userArgs,
delayMod: "0xeff5b8593076b69ff1a6c5d0e13c76c614738738",
},
[provider]
);
provider,
});
expect(result).toEqual({
canExec: false,
message: "No executable transactions found",
});
});

it.skip("skips over expired transactions to execute executable transactions", async () => {
it("skips over expired transactions to execute executable transactions", async () => {
const timeFirstTxIsExpired = QUEUE[0].createdAt + COOLDOWN + EXPIRATION + 1;
jest.setSystemTime(timeFirstTxIsExpired * 1000);
jest
.spyOn(Date, "now")
.mockImplementation(() => timeFirstTxIsExpired * 1000);

const { result } = await runWeb3Function(w3fPath, context, [provider]);
const result = await runWeb3Function({ userArgs, provider });
expect(result).toEqual({ canExec: true, callData: [] });

expect(sponsoredCallSpy).toHaveBeenCalledTimes(3);

expect(result).toEqual({
canExec: true,
calls: [],
callData: [],
});
});

Expand Down
62 changes: 62 additions & 0 deletions packages/gelato-web3-function/test/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
Web3FunctionContext,
Web3FunctionResult,
} from "@gelatonetwork/web3-functions-sdk";
import { Web3FunctionLoader } from "@gelatonetwork/web3-functions-sdk/loader";
import { providers } from "ethers";
import path from "path";

let taskFn: (ctx: Web3FunctionContext) => Promise<Web3FunctionResult>;
jest.mock("@gelatonetwork/web3-functions-sdk", () => ({
Web3Function: {
onRun: jest.fn().mockImplementation((fn) => {
taskFn = fn;
}),
},
}));

import "../delay-dispatch";

export const runWeb3Function = async ({
userArgs,
secrets: secretsOverride,
provider,
}: {
userArgs;
secrets?: {
[key: string]: string;
};
provider: providers.JsonRpcProvider;
}) => {
if (!taskFn) {
throw new Error("taskFn not defined");
}

const { secrets: envSecrets } = Web3FunctionLoader.load(
"delay-dispatch",
path.join(__dirname, "..")
);
const { gasPrice } = await provider.getFeeData();

if (gasPrice === null) throw new Error("gasPrice is null");

const secrets = secretsOverride || envSecrets;

const storage: { [key: string]: string | undefined } = {};

return await taskFn({
gelatoArgs: { chainId: 5, gasPrice },
userArgs,
secrets: { get: async (key: string) => secrets[key] },
multiChainProvider: { default: () => provider } as any,
storage: {
get: async (key: string) => storage[key],
set: async (key: string, value: string) => {
storage[key] = value;
},
delete: async (key: string) => {
delete storage[key];
},
},
});
};
86 changes: 0 additions & 86 deletions packages/gelato-web3-function/test/utils.ts

This file was deleted.

Loading

0 comments on commit 3d5a1e9

Please sign in to comment.