Skip to content

Commit 03bf859

Browse files
committed
[SDK] Test coverage TOOL-2241 (#5826)
Holiday project. Basically trying to improve test coverage, especially in those low-haning-fruit utils files <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on enhancing documentation, improving error handling, and adding tests across various modules in the codebase. It also corrects minor typos and ensures better code readability. ### Detailed summary - Added `@internal` documentation comments to `Queue` and `convertViemChain`. - Updated test cases to use `await expect(...)` for consistency. - Fixed typos in file imports and function names. - Introduced new tests for `namehash`, `encodeLabelhash`, and `parseNFT`. - Enhanced error handling in `parseNftUri`. - Improved the `toSemver` function and its tests. - Added tests for `replaceBigInts` and `toHex` functions. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent a7b6cb3 commit 03bf859

33 files changed

+1442
-29
lines changed

packages/thirdweb/src/auth/verify-hash.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe("verifyHash", async () => {
1616
privateKey: ANVIL_PKEY_A,
1717
});
1818

19-
expect(
19+
await expect(
2020
verifyHash({
2121
address: TEST_ACCOUNT_A.address,
2222
hash: hashMessage("hello world"),
@@ -33,7 +33,7 @@ describe("verifyHash", async () => {
3333
privateKey: ANVIL_PKEY_A,
3434
});
3535

36-
expect(
36+
await expect(
3737
verifyHash({
3838
address: TEST_ACCOUNT_A.address,
3939
hash: hashMessage("hello world"),
@@ -50,7 +50,7 @@ describe("verifyHash", async () => {
5050
privateKey: ANVIL_PKEY_A,
5151
});
5252

53-
expect(
53+
await expect(
5454
verifyHash({
5555
address: TEST_ACCOUNT_A.address,
5656
hash: hashMessage("hello world"),

packages/thirdweb/src/chains/utils.test.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ import { toSerializableTransaction } from "../transaction/actions/to-serializabl
99
import { privateKeyToAccount } from "../wallets/private-key.js";
1010
import { avalanche } from "./chain-definitions/avalanche.js";
1111
import { ethereum } from "./chain-definitions/ethereum.js";
12-
import type { LegacyChain } from "./types.js";
12+
import type { ChainMetadata, LegacyChain } from "./types.js";
1313

14+
import { base } from "viem/chains";
1415
import {
1516
CUSTOM_CHAIN_MAP,
1617
cacheChains,
18+
convertApiChainToChain,
1719
convertLegacyChain,
20+
convertViemChain,
1821
defineChain,
1922
getCachedChain,
2023
getChainDecimals,
@@ -237,4 +240,70 @@ describe("defineChain", () => {
237240
cacheChains([scroll]);
238241
expect(CUSTOM_CHAIN_MAP.get(scroll.id)).toStrictEqual(scroll);
239242
});
243+
244+
it("Chain converted from viem should have the blockExplorers being an array", () => {
245+
expect(Array.isArray(convertViemChain(base).blockExplorers)).toBe(true);
246+
});
247+
248+
it("convertApiChainToChain should work", () => {
249+
const ethChain: ChainMetadata = {
250+
chainId: 1,
251+
name: "Ethereum Mainnet",
252+
chain: "ETH",
253+
shortName: "eth",
254+
icon: {
255+
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
256+
width: 512,
257+
height: 512,
258+
format: "png",
259+
},
260+
nativeCurrency: {
261+
name: "Ether",
262+
symbol: "ETH",
263+
decimals: 18,
264+
},
265+
ens: {
266+
registry: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
267+
},
268+
explorers: [
269+
{
270+
name: "etherscan",
271+
url: "https://etherscan.io",
272+
standard: "EIP3091",
273+
},
274+
],
275+
rpc: ["https://1.rpc.thirdweb.com/${THIRDWEB_API_KEY}"],
276+
testnet: false,
277+
infoURL: "https://ethereum.org",
278+
slug: "ethereum",
279+
networkId: 1,
280+
stackType: "l1",
281+
};
282+
283+
expect(convertApiChainToChain(ethChain)).toStrictEqual({
284+
blockExplorers: [
285+
{
286+
apiUrl: "https://etherscan.io",
287+
name: "etherscan",
288+
url: "https://etherscan.io",
289+
},
290+
],
291+
faucets: undefined,
292+
icon: {
293+
format: "png",
294+
height: 512,
295+
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
296+
width: 512,
297+
},
298+
id: 1,
299+
name: "Ethereum Mainnet",
300+
nativeCurrency: {
301+
decimals: 18,
302+
name: "Ether",
303+
symbol: "ETH",
304+
},
305+
rpc: "https://1.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
306+
testnet: undefined,
307+
});
308+
});
240309
});

packages/thirdweb/src/chains/utils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ function isViemChain(
132132
return "rpcUrls" in chain && !("rpc" in chain);
133133
}
134134

135-
function convertViemChain(viemChain: ViemChain): Chain {
135+
/**
136+
* @internal
137+
*/
138+
export function convertViemChain(viemChain: ViemChain): Chain {
136139
const RPC_URL = getThirdwebDomains().rpc;
137140
return {
138141
id: viemChain.id,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { describe, expect, it } from "vitest";
2+
import { TEST_CLIENT } from "~test/test-clients.js";
3+
import { USDT_CONTRACT_ADDRESS } from "~test/test-contracts.js";
4+
import { ethereum } from "../chains/chain-definitions/ethereum.js";
5+
import { getContract } from "./contract.js";
6+
7+
describe("Contract - getContract", () => {
8+
it("should throw error if client is not passed", () => {
9+
expect(() =>
10+
// @ts-ignore Test purpose
11+
getContract({ address: "0x", chain: ethereum }),
12+
).toThrowError(
13+
`getContract validation error - invalid client: ${undefined}`,
14+
);
15+
});
16+
17+
it("should throw error if address is not valid", () => {
18+
expect(() =>
19+
getContract({ address: "0x", chain: ethereum, client: TEST_CLIENT }),
20+
).toThrowError("getContract validation error - invalid address: 0x");
21+
});
22+
23+
it("should throw error if chain is not passed", () => {
24+
expect(() =>
25+
// @ts-ignore Test purpose
26+
getContract({ address: USDT_CONTRACT_ADDRESS, client: TEST_CLIENT }),
27+
).toThrowError(
28+
`getContract validation error - invalid chain: ${undefined}`,
29+
);
30+
});
31+
32+
it("should throw error if chain doesn't have id", () => {
33+
expect(() =>
34+
getContract({
35+
address: USDT_CONTRACT_ADDRESS,
36+
client: TEST_CLIENT,
37+
// @ts-ignore Test
38+
chain: {},
39+
}),
40+
).toThrowError(`getContract validation error - invalid chain: ${{}}`);
41+
});
42+
});

packages/thirdweb/src/exports/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// bytecode
22
export { detectMethod } from "../utils/bytecode/detectExtension.js";
33
export { extractIPFSUri } from "../utils/bytecode/extractIPFS.js";
4-
export { extractMinimalProxyImplementationAddress } from "../utils/bytecode/extractMnimalProxyImplementationAddress.js";
4+
export { extractMinimalProxyImplementationAddress } from "../utils/bytecode/extractMinimalProxyImplementationAddress.js";
55
export { isContractDeployed } from "../utils/bytecode/is-contract-deployed.js";
66
export { ensureBytecodePrefix } from "../utils/bytecode/prefix.js";
77
export { resolveImplementation } from "../utils/bytecode/resolveImplementation.js";

packages/thirdweb/src/extensions/thirdweb/write/publish.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential("publishContract", () => {
105105

106106
expect(publishedContracts.length).toBe(1);
107107

108-
expect(
108+
await expect(
109109
sendAndConfirmTransaction({
110110
account: TEST_ACCOUNT_D,
111111
transaction: publishContract({
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { describe, expect, it } from "vitest";
2+
import { CADIcon } from "../../../icons/currencies/CADIcon.js";
3+
import { EURIcon } from "../../../icons/currencies/EURIcon.js";
4+
import { GBPIcon } from "../../../icons/currencies/GBPIcon.js";
5+
import { JPYIcon } from "../../../icons/currencies/JPYIcon.js";
6+
import { USDIcon } from "../../../icons/currencies/USDIcon.js";
7+
import { currencies, getCurrencyMeta, usdCurrency } from "./currencies.js";
8+
9+
describe("Currency Utilities", () => {
10+
it("should have correct number of currencies", () => {
11+
expect(currencies.length).toBe(5);
12+
});
13+
14+
it("should have USD as the first currency", () => {
15+
expect(currencies[0]).toEqual(usdCurrency);
16+
});
17+
18+
it("should have correct properties for each currency", () => {
19+
for (const currency of currencies) {
20+
expect(currency).toHaveProperty("shorthand");
21+
expect(currency).toHaveProperty("name");
22+
expect(currency).toHaveProperty("icon");
23+
}
24+
});
25+
26+
describe("getCurrencyMeta function", () => {
27+
it("should return correct currency meta for valid shorthand", () => {
28+
const cadMeta = getCurrencyMeta("CAD");
29+
expect(cadMeta.shorthand).toBe("CAD");
30+
expect(cadMeta.name).toBe("Canadian Dollar");
31+
expect(cadMeta.icon).toBe(CADIcon);
32+
});
33+
34+
it("should be case-insensitive", () => {
35+
const eurMeta = getCurrencyMeta("eur");
36+
expect(eurMeta.shorthand).toBe("EUR");
37+
expect(eurMeta.name).toBe("Euro");
38+
expect(eurMeta.icon).toBe(EURIcon);
39+
});
40+
41+
it("should return unknown currency for invalid shorthand", () => {
42+
const unknownMeta = getCurrencyMeta("XYZ");
43+
expect(unknownMeta.shorthand).toBe("XYZ");
44+
expect(unknownMeta.name).toBe("XYZ");
45+
expect(unknownMeta.icon).not.toBe(USDIcon);
46+
expect(unknownMeta.icon).not.toBe(CADIcon);
47+
expect(unknownMeta.icon).not.toBe(GBPIcon);
48+
expect(unknownMeta.icon).not.toBe(EURIcon);
49+
expect(unknownMeta.icon).not.toBe(JPYIcon);
50+
});
51+
});
52+
});

0 commit comments

Comments
 (0)