Skip to content

Commit d660b6c

Browse files
gregfromstljnsdls
andauthored
React tests & deterministic deploy cleanup (#2969)
Co-authored-by: Jonas Daniels <jonas.daniels@outlook.com>
1 parent c744935 commit d660b6c

File tree

8 files changed

+188
-189
lines changed

8 files changed

+188
-189
lines changed

.changeset/violet-queens-train.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Fixes deterministic deploys of contracts with no constructor

packages/thirdweb/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@
212212
"@vitejs/plugin-react": "^4.2.1",
213213
"@vitest/ui": "1.5.0",
214214
"cross-spawn": "7.0.3",
215-
"jsdom": "^24.0.0",
215+
"happy-dom": "^14.10.1",
216216
"vitest": "1.5.0"
217217
}
218218
}

packages/thirdweb/src/contract/deployment/deploy-deterministic.test.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, expect, it } from "vitest";
22
import {
3+
ANVIL_CHAIN,
34
FORKED_ETHEREUM_CHAIN,
45
FORKED_OPTIMISM_CHAIN,
56
} from "../../../test/src/chains.js";
@@ -14,13 +15,13 @@ import { prepareDeterministicDeployTransaction } from "./deploy-deterministic.js
1415
describe.runIf(process.env.TW_SECRET_KEY)("deployFromMetadata", () => {
1516
it("should deploy contracts at the same address", async () => {
1617
const tx1 = prepareDeterministicDeployTransaction({
17-
chain: FORKED_ETHEREUM_CHAIN,
18+
chain: ANVIL_CHAIN,
1819
client: TEST_CLIENT,
1920
contractId: "AccountFactory",
2021
constructorParams: [TEST_ACCOUNT_A.address, ENTRYPOINT_ADDRESS_v0_6],
2122
});
2223
const tx2 = prepareDeterministicDeployTransaction({
23-
chain: FORKED_OPTIMISM_CHAIN,
24+
chain: ANVIL_CHAIN,
2425
client: TEST_CLIENT,
2526
contractId: "AccountFactory",
2627
constructorParams: [TEST_ACCOUNT_A.address, ENTRYPOINT_ADDRESS_v0_6],
@@ -52,4 +53,17 @@ describe.runIf(process.env.TW_SECRET_KEY)("deployFromMetadata", () => {
5253
]);
5354
expect(tx1Result !== tx2Result).toBe(true);
5455
});
56+
// TODO: Replace these tests' live contracts with mocks
57+
it("should deploy a published contract with no constructor", async () => {
58+
const tx = prepareDeterministicDeployTransaction({
59+
client: TEST_CLIENT,
60+
chain: ANVIL_CHAIN,
61+
contractId: "Counter",
62+
publisher: "0x4a706de5CE9bfe2f9C37BA945805e396d1810824",
63+
constructorParams: [],
64+
});
65+
66+
const txResult = await simulateTransaction({ transaction: tx });
67+
expect(txResult).toBeDefined();
68+
});
5569
});
Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,53 @@
1-
import { describe, expect, it } from "vitest";
1+
import {
2+
afterAll,
3+
beforeAll,
4+
beforeEach,
5+
describe,
6+
expect,
7+
it,
8+
vi,
9+
} from "vitest";
210
import { render, screen } from "../../../../../test/src/react-render.js";
311
import { TEST_CLIENT } from "../../../../../test/src/test-clients.js";
412
import { ConnectButton } from "./ConnectButton.js";
513

614
describe("ConnectButton", () => {
7-
it("renders", () => {
8-
render(<ConnectButton client={TEST_CLIENT} />);
9-
expect(screen.getByRole("button")).toBeInTheDocument();
15+
beforeAll(() => {
16+
vi.mock("./locale/getConnectLocale.js", () => ({
17+
useConnectLocale: vi.fn().mockReturnValue({
18+
data: {
19+
defaultButtonTitle: "Connect Wallet",
20+
},
21+
isLoading: false,
22+
}),
23+
}));
24+
});
25+
26+
afterAll(() => {
27+
vi.clearAllMocks();
28+
});
29+
30+
describe("defaults", () => {
31+
beforeEach(() => {
32+
render(<ConnectButton client={TEST_CLIENT} />);
33+
});
34+
35+
it("should render", () => {
36+
expect(screen.getByRole("button")).toBeInTheDocument();
37+
});
38+
39+
it("should display 'Connect Wallet' on initial render", () => {
40+
expect(screen.getByText("Connect Wallet")).toBeInTheDocument();
41+
});
42+
});
43+
44+
it("should override default text", () => {
45+
render(
46+
<ConnectButton
47+
client={TEST_CLIENT}
48+
connectButton={{ label: "Sign In" }}
49+
/>,
50+
);
51+
expect(screen.getByText("Sign In")).toBeInTheDocument();
1052
});
1153
});
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import {
2+
afterAll,
3+
afterEach,
4+
beforeAll,
5+
beforeEach,
6+
describe,
7+
expect,
8+
it,
9+
vi,
10+
} from "vitest";
11+
import { ANVIL_CHAIN } from "../../../../../test/src/chains.js";
12+
import { render, screen } from "../../../../../test/src/react-render.js";
13+
import { TEST_CLIENT } from "../../../../../test/src/test-clients.js";
14+
import { TEST_ACCOUNT_A } from "../../../../../test/src/test-wallets.js";
15+
import { prepareTransaction, toWei } from "../../../../exports/thirdweb.js";
16+
import { TransactionButton } from "./index.js";
17+
18+
vi.mock("../../../../transaction/actions/send-transaction.js", () => ({
19+
sendTransaction: vi.fn(),
20+
}));
21+
22+
const TRANSFER_TX = prepareTransaction({
23+
client: TEST_CLIENT,
24+
chain: ANVIL_CHAIN,
25+
to: TEST_ACCOUNT_A.address,
26+
value: BigInt(toWei("100")),
27+
});
28+
29+
const mocks = vi.hoisted(() => {
30+
return {
31+
activeAccount: vi.fn(),
32+
activeWallet: vi.fn(),
33+
switchActiveWalletChain: vi.fn(),
34+
transaction: vi.fn(),
35+
};
36+
});
37+
38+
describe.sequential("TransactionButton", () => {
39+
beforeAll(() => {
40+
vi.mock("../../../core/hooks/wallets/wallet-hooks.js", () => ({
41+
useActiveAccount: mocks.activeAccount,
42+
useActiveWallet: mocks.activeWallet,
43+
useSwitchActiveWalletChain: mocks.switchActiveWalletChain,
44+
}));
45+
});
46+
47+
afterAll(() => {
48+
vi.clearAllMocks();
49+
});
50+
51+
afterEach(() => {
52+
vi.restoreAllMocks();
53+
});
54+
55+
beforeEach(() => {
56+
mocks.transaction.mockReturnValue(TRANSFER_TX);
57+
render(
58+
<TransactionButton transaction={mocks.transaction}>
59+
Send ETH
60+
</TransactionButton>,
61+
);
62+
});
63+
64+
describe("defaults", () => {
65+
it("should render", () => {
66+
expect(screen.getByRole("button")).toBeInTheDocument();
67+
});
68+
69+
it("should display text on initial render", () => {
70+
expect(screen.getByText("Send ETH")).toBeInTheDocument();
71+
});
72+
});
73+
74+
describe("with account", () => {
75+
beforeAll(() => {
76+
mocks.activeAccount.mockReturnValue(TEST_ACCOUNT_A);
77+
});
78+
79+
it("should be enabled", () => {
80+
const button = screen.getByRole("button", { name: "Send ETH" });
81+
expect(button).not.toBeDisabled();
82+
});
83+
});
84+
85+
describe("without account", () => {
86+
beforeAll(() => {
87+
mocks.activeAccount.mockReturnValue(undefined);
88+
});
89+
90+
it("should be disabled", () => {
91+
const button = screen.getByRole("button", { name: "Send ETH" });
92+
expect(button).toBeDisabled();
93+
});
94+
});
95+
});

packages/thirdweb/src/utils/any-evm/compute-published-contract-deploy-info.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export async function computeDeploymentInfoFromMetadata(args: {
5656
(abi) => abi.type === "constructor",
5757
) as AbiConstructor) || [];
5858
const encodedArgs = encodeAbiParameters(
59-
constructorAbi.inputs,
59+
constructorAbi.inputs ?? [],
6060
constructorParams,
6161
);
6262
const initBytecodeWithsalt = getInitBytecodeWithSalt({

packages/thirdweb/test/vitest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default defineConfig({
3333
include: ["src/**"],
3434
},
3535
environmentMatchGlobs: [
36-
["src/react/**/*.test.tsx", "jsdom"],
36+
["src/react/**/*.test.tsx", "happy-dom"],
3737
["src/**/*.test.ts", "node"],
3838
["src/**/*", "node"], // all other files use node
3939
],

0 commit comments

Comments
 (0)