Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add end-to-end tests 🧪 #110

Merged
merged 1 commit into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"extends": ["standard-with-typescript", "prettier"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
"sourceType": "module",
"project": "./tsconfig.json"
},
"rules": {
"func-style": ["error", "declaration", { "allowArrowFunctions": true }]
Expand Down
119 changes: 119 additions & 0 deletions e2e/xcm.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { describe, it, expect, beforeAll } from 'vitest'
import {
Builder,
type TNode,
createApiInstanceForNode,
NODE_NAMES,
getAllAssetsSymbols,
getRelayChainSymbol,
NoXCMSupportImplementedError,
ScenarioNotSupportedError
} from '../src'
import { type ApiPromise } from '@polkadot/api'

const MOCK_AMOUNT = 1000
const MOCK_ADDRESS = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'
const MOCK_POLKADOT_NODE: TNode = 'Acala'
const MOCK_KUSAMA_NODE: TNode = 'Karura'

const getAssetsForNode = (node: TNode): string[] => {
if (node === 'Pendulum') return ['PEN']
if (node === 'Nodle') return ['NODL']
if (node === 'Crust') return ['EQD']
if (node === 'Genshiro') return ['GENS']
if (node === 'CrustShadow') return ['KAR']
if (node === 'Integritee') return getAllAssetsSymbols(node).filter(asset => asset !== 'KSM')
return getAllAssetsSymbols(node)
}

const filteredNodes = NODE_NAMES.filter(node => node !== 'Quartz')

const findTransferableNodeAndAsset = (
from: TNode
): { nodeTo: TNode | undefined; asset: string | undefined } => {
const allFromAssets = getAssetsForNode(from)

const nodeTo = NODE_NAMES.filter(
node => getRelayChainSymbol(node) === getRelayChainSymbol(from)
).find(node => {
const nodeAssets = getAllAssetsSymbols(node)
const commonAsset = nodeAssets.filter(asset => allFromAssets.includes(asset))[0]
return commonAsset !== undefined
})

const foundAsset =
nodeTo !== undefined
? getAllAssetsSymbols(nodeTo).filter(asset => allFromAssets.includes(asset))[0]
: undefined

return { nodeTo, asset: foundAsset }
}

describe.sequential('XCM - e2e', () => {
describe.sequential('RelayToPara', () => {
it('should create transfer tx - DOT from Relay to Para', async () => {
const api = await createApiInstanceForNode('Polkadot')
const tx = Builder(api)
.to(MOCK_POLKADOT_NODE)
.amount(MOCK_AMOUNT)
.address(MOCK_ADDRESS)
.build()
expect(tx).toBeDefined()
})
it('should create transfer tx - KSM from Relay to Para', async () => {
const api = await createApiInstanceForNode('Kusama')
const tx = Builder(api).to(MOCK_KUSAMA_NODE).amount(MOCK_AMOUNT).address(MOCK_ADDRESS).build()
expect(tx).toBeDefined()
})
})

filteredNodes.forEach(node => {
describe.sequential(`${node} ParaToPara & ParaToRelay`, () => {
let api: ApiPromise
const { nodeTo, asset } = findTransferableNodeAndAsset(node)
beforeAll(async () => {
api = await createApiInstanceForNode(node)
})
it(`should create transfer tx - ParaToPara ${asset} from ${node} to ${nodeTo}`, async () => {
expect(nodeTo).toBeDefined()
try {
const tx = Builder(api)
.from(node)
.to(nodeTo ?? MOCK_POLKADOT_NODE)
.currency(asset ?? 'DOT')
.amount(MOCK_AMOUNT)
.address(MOCK_ADDRESS)
.build()
expect(tx).toBeDefined()
} catch (error) {
if (error instanceof NoXCMSupportImplementedError) {
expect(error).toBeInstanceOf(NoXCMSupportImplementedError)
} else if (error instanceof ScenarioNotSupportedError) {
expect(error).toBeInstanceOf(ScenarioNotSupportedError)
} else {
throw error
}
}
})

if (node !== 'Integritee' && node !== 'Crust' && node !== 'CrustShadow') {
it(`should create transfer tx - ParaToRelay ${getRelayChainSymbol(
node
)} from ${node} to Relay`, async () => {
try {
const tx = Builder(api).from(node).amount(MOCK_AMOUNT).address(MOCK_ADDRESS).build()
expect(tx).toBeDefined()
} catch (error) {
if (error instanceof NoXCMSupportImplementedError) {
expect(error).toBeInstanceOf(NoXCMSupportImplementedError)
} else if (error instanceof ScenarioNotSupportedError) {
expect(error).toBeInstanceOf(ScenarioNotSupportedError)
} else {
throw error
}
}
})
}
})
})
})
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"updateAssets": "node --loader ts-node/esm --experimental-specifier-resolution=node ./scripts/updateAssets.ts",
"updatePallets": "node --loader ts-node/esm --experimental-specifier-resolution=node ./scripts/updatePallets.ts",
"release": "pnpm runAll && pnpm build && standard-version && git push --follow-tags",
"runAll": "pnpm compile && pnpm format:write && pnpm lint && pnpm test"
"runAll": "pnpm compile && pnpm format:write && pnpm lint && pnpm test",
"test:e2e": "vitest run --config ./vitest.config.e2e.ts --sequence.concurrent"
},
"pnpm": {
"peerDependencyRules": {
Expand Down Expand Up @@ -58,7 +59,7 @@
"@rollup/plugin-json": "^6.0.1",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@vitest/coverage-v8": "^0.32.2",
"@vitest/coverage-v8": "^1.1.3",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-standard-with-typescript": "^40.0.0",
Expand All @@ -74,7 +75,7 @@
"ts-node": "^10.9.1",
"tslib": "^2.6.2",
"typescript": "^5.2.2",
"vitest": "^0.34.4"
"vitest": "^1.1.3"
},
"packageManager": "[email protected]"
}
Loading