diff --git a/.eslintrc.js b/.eslintrc.js index ac5517c..0aefe87 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -13,4 +13,12 @@ module.exports = { }, ], }, + overrides: [ + { + files: ["*.test.ts", "*.test.tsx"], + rules: { + "@typescript-eslint/no-unused-expressions": "off", + }, + }, + ], }; diff --git a/src/__tests__/balanceCheck.test.ts b/src/__tests__/balanceCheck.test.ts index 8f6409f..fb7c525 100644 --- a/src/__tests__/balanceCheck.test.ts +++ b/src/__tests__/balanceCheck.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions */ import BigNumber from "bignumber.js"; import { expect } from "chai"; diff --git a/src/__tests__/parser.test.ts b/src/__tests__/parser.test.ts index ce5ebc8..e05df43 100644 --- a/src/__tests__/parser.test.ts +++ b/src/__tests__/parser.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions */ import { BigNumber } from "bignumber.js"; import * as chai from "chai"; import { expect } from "chai"; diff --git a/src/__tests__/tokenList.test.ts b/src/__tests__/tokenList.test.ts index 2971583..ee14b5a 100644 --- a/src/__tests__/tokenList.test.ts +++ b/src/__tests__/tokenList.test.ts @@ -1,19 +1,77 @@ import { expect } from "chai"; +import { ethers } from "ethers"; import { fetchTokenList } from "../hooks/token"; import { networkInfo } from "../networks"; -describe("fetchTokenList()", () => { +beforeEach(() => { + jest.spyOn(window, "fetch").mockImplementation(() => { + return Promise.resolve({ + json: () => + Promise.resolve({ + tokens: [ + { + name: "Gnosis", + address: "0x6810e776880c02933d47db1b9fc05908e5386b96", + symbol: "GNO", + decimals: 18, + }, + { + name: "Dai Stablecoin", + address: "0x6b175474e89094c44da98b954eedeac495271d0f", + symbol: "DAI", + decimals: 18, + }, + { + name: "Spam Token", + address: "", + symbol: "SPAM", + decimals: 0, + }, + ], + }), + status: 200, + } as any); + }); +}); + +describe("Mainnet tokenlist", () => { + it("Should parse its response correctly", async () => { + const resultingTokens = await fetchTokenList(1); + const gnoAddress = ethers.utils.getAddress("0x6810e776880c02933d47db1b9fc05908e5386b96"); + + expect(resultingTokens).to.have.lengthOf(2); + expect(resultingTokens.get(gnoAddress)?.symbol).to.equal("GNO"); + expect(resultingTokens.get(gnoAddress)?.address.toLowerCase()).eq(gnoAddress.toLowerCase()); + expect(resultingTokens.get(gnoAddress)?.decimals).to.equal(18); + }); + + it("Should not crash on errors", async () => { + jest.spyOn(window, "fetch").mockImplementation(() => { + return Promise.reject("Unexpected error."); + }); + + const resultingTokens = await fetchTokenList(1); + expect(resultingTokens).to.be.empty; + }); + + it("Should not crash on unsuccessful fetches", async () => { + jest.spyOn(window, "fetch").mockImplementation(() => { + return Promise.resolve({ + status: 404, + statusText: "Page not found", + } as any); + }); + + const resultingTokens = await fetchTokenList(1); + expect(resultingTokens).to.be.empty; + }); +}); + +describe("Fetch should resolve for all networks", () => { for (const chainId of networkInfo.keys()) { it(`fetches tokens for ${networkInfo.get(chainId)?.name} network`, () => { expect(() => fetchTokenList(chainId)).to.not.throw(); }); } }); - -describe("useTokenList()", () => { - it("Throws on unknown networks", () => { - // TODO - not sure how to test this. - expect(1).to.equal(1); - }); -}); diff --git a/src/hooks/token.ts b/src/hooks/token.ts index 973af8f..f48257f 100644 --- a/src/hooks/token.ts +++ b/src/hooks/token.ts @@ -26,7 +26,10 @@ export const fetchTokenList = async (chainId: number): Promise => { switch (chainId) { case 1: const mainnetTokenURL = "https://tokens.coingecko.com/uniswap/all.json"; - tokens = (await (await fetch(mainnetTokenURL)).json()).tokens; + tokens = await fetch(mainnetTokenURL) + .then((response) => response.json()) + .then((response) => response.tokens) + .catch(() => []); break; case 4: // Hardcoded this because the list provided at