Skip to content

Commit

Permalink
fix: validate chain with custom matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
maxklenk committed Jul 1, 2023
1 parent 67d39bb commit 04ea180
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/chains/supported.chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ export const supportedEVMChains: EVMChain[] = [

metamask: {
chainId: prefixChainId(1101),
blockExplorerUrls: ['https://zkevm.polygonscan.com'],
blockExplorerUrls: ['https://zkevm.polygonscan.com/'],
chainName: 'Polygon zkEVM',
nativeCurrency: {
name: 'ETH',
Expand Down Expand Up @@ -1054,7 +1054,7 @@ export const supportedEVMChains: EVMChain[] = [
multicallAddress: multicallAddresses[ChainId.OPTG],

metamask: {
chainId: prefixChainId(69),
chainId: prefixChainId(420),
blockExplorerUrls: ['https://blockscout.com/optimism/goerli/'],
chainName: 'Optimistic Ethereum Testnet Goerli',
nativeCurrency: {
Expand Down
2 changes: 1 addition & 1 deletion src/coins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1884,7 +1884,7 @@ export const wrappedTokens: { [ChainId: string]: StaticToken } = {
coinKey: 'WBNB' as CoinKey,
name: 'WBNB',
logoURI:
'https://zapper.fi/images/networks/binance-smart-chain/0x0000000000000000000000000000000000000000.png',
'https://static.debank.com/image/coin/logo_url/bnb/9784283a36f23a58982fc964574ea530.png',
},
[ChainId.LNAT]: {
// https://explorer.prealpha.zkevm.consensys.net/address/0x2C1b868d6596a18e32E61B901E4060C872647b6C
Expand Down
43 changes: 27 additions & 16 deletions test/coins.logo.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
import axios from "axios"
import { defaultCoins } from "../src"
import { expect, test } from '@jest/globals'
import './matchers'
import { defaultCoins, wrappedTokens } from "../src"

jest.setTimeout(20_000)

describe('Coin logo test', () => {
test.each(defaultCoins)(
'that the links for logoURI are working', async (coin) => {
const baseURL = coin.logoURI
const tokenSpecificURLs = Object.values(coin.chains).flatMap(({ logoURI }) => logoURI ? [logoURI] : [])
const failing: string[] = []
await Promise.allSettled([...new Set([
baseURL,
...tokenSpecificURLs
])]
.map(url => axios.get(url).catch(_ => failing.push(url))))
expect(failing).toHaveLength(0)
}
)
})
const allImages : string[] = []

// default coins
allImages.push(
...defaultCoins.map((coin) => {
const baseURL = coin.logoURI
const tokenSpecificURLs = Object.values(coin.chains).flatMap(({ logoURI }) => logoURI ? [logoURI] : [])
return [
baseURL,
...tokenSpecificURLs
]
}).flat()
)

// wrapped tokens
allImages.push(
...Object.values(wrappedTokens).map((token: any) => token.logoURI)
)

test.each([...new Set(allImages)])('that the links for logoURI are working', async (image) => {
expect(image).httpsUrl()
await expect(image).canGetUrl()
})
})
76 changes: 76 additions & 0 deletions test/matchers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import axios from 'axios'
import type { MatcherFunction } from 'expect'

const httpsUrl: MatcherFunction<[url: unknown]> = function (url) {
if (typeof url !== 'string') {
throw new Error('Url must be of type string!')
}

if (url.startsWith('https://')) {
return {
message: () => `Url ${url} is a secure https url`,
pass: true
}
} else {
return {
message: () => `Url ${url} is not a secure https url`,
pass: false
}
}
}

const endsWith: MatcherFunction<[value: unknown, check: unknown]> = function (value, check) {
if (typeof value !== 'string') {
throw new Error('Passed value must be of type string!')
}
if (typeof check !== 'string') {
throw new Error('Passed check must be of type string!')
}

if (value.endsWith(check)) {
return {
message: () => `Value ${value} ends with ${check}`,
pass: true
}
} else {
return {
message: () => `Value ${value} does not end with ${check}`,
pass: false
}
}
}

const canGetUrl: MatcherFunction<[value: unknown, check: unknown]> = async function (url) {
if (typeof url !== 'string') {
throw new Error('Url must be of type string!')
}

return axios.get(url)
.then(() => ({
message: () => `Was able to get ${url}`,
pass: true
}))
.catch(() => ({
message: () => `Not able to GET url: ${url}`,
pass: false
}))
}

expect.extend({
httpsUrl,
endsWith,
canGetUrl,
})

declare module 'expect' {
interface AsymmetricMatchers {
httpsUrl(): void
endsWith(check: string): void
canGetUrl(): Promise<void>
}
interface Matchers<R> {
httpsUrl(): R
endsWith(check: string): R
canGetUrl(): Promise<R>
}
}
26 changes: 24 additions & 2 deletions test/types.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { ChainId, ChainKey, getChainByKey, getChainById, supportedEVMChains, findDefaultToken, findWrappedGasOnChain, CoinKey } from '../src'
import { expect, test } from '@jest/globals'
import './matchers'

import { ChainId, ChainKey, getChainByKey, getChainById, supportedEVMChains, findDefaultToken, findWrappedGasOnChain, CoinKey, prefixChainId } from '../src'
import { findTokenByChainIdAndAddress } from '../src/coins';
test('getChainById', () => {
expect(getChainById(ChainId.ETH)).toBeDefined()
Expand Down Expand Up @@ -64,4 +67,23 @@ describe('findTokenByChainIdAndAddress', () => {
).toEqual('Goerli CXTT')
})
})
})
})

describe('validate chains', () => {
supportedEVMChains.forEach(chain => {
it(`validate chain ${chain.name}`, () => {
// blockExplorerUrls
expect(chain.metamask.blockExplorerUrls.length).toBeGreaterThan(0)
chain.metamask.blockExplorerUrls.forEach(blockExplorerUrl => {
expect(blockExplorerUrl).httpsUrl()
expect(blockExplorerUrl).endsWith('/')
})

// chain ids match
expect(prefixChainId(chain.id)).toEqual(chain.metamask.chainId)

// rpcs defined
expect(chain.metamask.rpcUrls.length).toBeGreaterThan(0)
})
})
})

0 comments on commit 04ea180

Please sign in to comment.