From 1ec280c3568bfc90fdde5975a637964ba81beaad Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Mon, 25 May 2020 08:46:55 +0200 Subject: [PATCH] Add data parity tests for epoch details (#177) * Add data parity tests for epoch details * Refactor transactions data parity tests Reduce number of API calls, change array to set as the different order of elements in array for rest vs graphql response caused one test to fail. Co-authored-by: Rhys Bartels-Waller --- .../dataparitytests/blocks.parity.test.ts | 17 +- .../dataparitytests/epochs.parity.test.ts | 122 +++++++ src/__test__/dataparitytests/index.ts | 1 + .../transactions.parity.test.ts | 316 +++--------------- src/__test__/util.ts | 10 + 5 files changed, 192 insertions(+), 274 deletions(-) create mode 100644 src/__test__/dataparitytests/epochs.parity.test.ts create mode 100644 src/__test__/util.ts diff --git a/src/__test__/dataparitytests/blocks.parity.test.ts b/src/__test__/dataparitytests/blocks.parity.test.ts index 45a708bf..24dd53a7 100644 --- a/src/__test__/dataparitytests/blocks.parity.test.ts +++ b/src/__test__/dataparitytests/blocks.parity.test.ts @@ -1,32 +1,27 @@ import gql from 'graphql-tag' import { TestClient } from '../TestClient' -import fetch from 'node-fetch' - -async function getDataFromAPI (path: string) { - const response = await fetch(`https://explorer.cardano.org/api/${path}`) - return response.json() -} +import { getDataFromAPI } from '../util' export function blocksTests (createClient: () => Promise) { - describe('blocks', () => { + describe('blocks ', () => { let client: TestClient beforeEach(async () => { client = await createClient() }, 60000) - it('returns the same height', async () => { + it('return the same height', async () => { const restResult = await getDataFromAPI('blocks/pages') const graphQLResult = await client.query({ query: gql`query Blockheight { cardano { blockHeight - } + } }` }) - const restResultBlockHeight = restResult['Right'][1][0]['cbeBlkHeight'] - const graphQLBlockHeight = graphQLResult['data']['cardano']['blockHeight'] + const restResultBlockHeight = restResult.Right[1][0].cbeBlkHeight + const graphQLBlockHeight = graphQLResult.data.cardano.blockHeight // As we're calling an external API to check equality on something that changes every 20 seconds // there is a small delta in the test condition to allow for this where the second API value can be diff --git a/src/__test__/dataparitytests/epochs.parity.test.ts b/src/__test__/dataparitytests/epochs.parity.test.ts new file mode 100644 index 00000000..e4f5896b --- /dev/null +++ b/src/__test__/dataparitytests/epochs.parity.test.ts @@ -0,0 +1,122 @@ +import gql from 'graphql-tag' +import { TestClient } from '../TestClient' +import { getDataFromAPI, timestampToIsoStringWithoutTimezone } from '../util' + +export function epochsTests (createClient: () => Promise) { + describe('epochs ', () => { + let client: TestClient + let restData: any + let graphQLData: any + const epoch = 111 + const slot = 3313 + + beforeAll(async () => { + client = await createClient() + const restResult = await getDataFromAPI(`epochs/${epoch}/${slot}`) + restData = restResult.Right[0] + const graphQLResult = await client.query({ + query: gql`query EpochDetails{ + epochs(where: {number:{_eq:${epoch}}}){ + number + startedAt + lastBlockTime + blocks (where: {slotWithinEpoch:{_eq:${slot}}}){ + slotNo + epochNo + slotWithinEpoch + number + hash + createdAt + transactionsCount + transactions{ + totalOutput + } + size + createdBy + fees + } + output + } + }` + }) + graphQLData = graphQLResult.data.epochs[0].blocks[0] + }, 30000) + + it('return the same epoch number', async () => { + const restResultEpochNumber = restData.cbeEpoch + const graphQLEpochNumber = graphQLData.epochNo + + expect(restResultEpochNumber).toEqual(graphQLEpochNumber) + }) + + it('return the same slot number', async () => { + const restResultSlotNumber = restData.cbeSlot + const graphQLSlotNumber = graphQLData.slotWithinEpoch + + expect(restResultSlotNumber).toEqual(graphQLSlotNumber) + }) + + it('return the same block height', async () => { + const restResultBlockHeight = restData.cbeBlkHeight + const graphQLBlockHeight = graphQLData.number + + expect(restResultBlockHeight).toEqual(graphQLBlockHeight) + }) + + it('return the same block hash', async () => { + const restResultBlockHash = restData.cbeBlkHash + const graphQLBlockHash = graphQLData.id + + expect(restResultBlockHash).toEqual(graphQLBlockHash) + }) + + it('return the same block creation time', async () => { + const restResultBlockCreationUnixEpochTime = restData.cbeTimeIssued + const graphQLBlockCreationDateTime = graphQLData.createdAt + const restResultBlockCreationDateTime = timestampToIsoStringWithoutTimezone(restResultBlockCreationUnixEpochTime) + + expect(restResultBlockCreationDateTime).toEqual(graphQLBlockCreationDateTime) + }) + + it('return the same transactions count', async () => { + const restResultTxCount = restData.cbeTxNum + const graphQLTxCount = parseInt(graphQLData.transactionsCount) + + expect(restResultTxCount).toEqual(graphQLTxCount) + }) + + it('return the same total output', async () => { + const restResultTotalSent = parseInt(restData.cbeTotalSent.getCoin) + let graphQLTotalSent = 0 + + graphQLData.transactions.forEach( + (tx: any) => { + graphQLTotalSent += parseInt(tx.totalOutput) + } + ) + + expect(restResultTotalSent).toEqual(graphQLTotalSent) + }) + + it('return the same block size', async () => { + const restResultBlockSize = restData.cbeSize + const graphQLBlockSize = graphQLData.size + + expect(restResultBlockSize).toEqual(graphQLBlockSize) + }) + + it('return the same block leader', async () => { + const restResultBlockLeader = restData.cbeBlockLead + const graphQLBlockLeader = graphQLData.createdBy.split('-')[1] + + expect(restResultBlockLeader).toMatch(graphQLBlockLeader) + }) + + it('return the same fee', async () => { + const restResultFee = parseInt(restData.cbeFees.getCoin) + const graphQLFee = graphQLData.fees + + expect(restResultFee).toEqual(graphQLFee) + }) + }) +} diff --git a/src/__test__/dataparitytests/index.ts b/src/__test__/dataparitytests/index.ts index a15a4a13..239b167b 100644 --- a/src/__test__/dataparitytests/index.ts +++ b/src/__test__/dataparitytests/index.ts @@ -1,2 +1,3 @@ export * from './blocks.parity.test' export * from './transactions.parity.test' +export * from './epochs.parity.test' diff --git a/src/__test__/dataparitytests/transactions.parity.test.ts b/src/__test__/dataparitytests/transactions.parity.test.ts index 87611081..12484196 100644 --- a/src/__test__/dataparitytests/transactions.parity.test.ts +++ b/src/__test__/dataparitytests/transactions.parity.test.ts @@ -1,367 +1,157 @@ import gql from 'graphql-tag' import { TestClient } from '../TestClient' -import fetch from 'node-fetch' - -async function getDataFromAPI (path: string) { - const response = await fetch(`https://explorer.cardano.org/api/${path}`) - return response.json() -} - -function timestampToIsoStringWithoutTimezone (timestamp: number): string { - return new Date(timestamp * 1000).toISOString().substr(0, 19) -} +import { getDataFromAPI, timestampToIsoStringWithoutTimezone } from '../util' export function transactionTests (createClient: () => Promise) { describe('transactions', () => { let client: TestClient + let restData: any + let graphQLData: any - beforeEach(async () => { + beforeAll(async () => { client = await createClient() - }, 60000) - - it('return the correct hash', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - hash - } - }` - }) - - const restResultHash = restResult['Right']['ctsId'] - const graphQLHash = graphQLResult['data']['transactions'][0]['hash'] - - expect(graphQLHash).toEqual(restResultHash) - }) - - it('return the correct Result Fee', async () => { const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') + restData = restResult.Right const graphQLResult = await client.query({ query: gql`query TxByHash{ transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - fee - } - }` - }) - - const restResultFee = restResult['Right']['ctsFees']['getCoin'] - const graphQLFee = graphQLResult['data']['transactions'][0]['fee'] - - expect(graphQLFee).toEqual(parseInt(restResultFee)) - }) - - it('return the correct Total Output', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - totalOutput - } - }` - }) - - const restResultTotalOutput = restResult['Right']['ctsTotalOutput']['getCoin'] - const graphQLTotalOutput = graphQLResult['data']['transactions'][0]['totalOutput'] - - expect(graphQLTotalOutput).toEqual(restResultTotalOutput) - }) - - it('return the correct Block Height', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { + { hash fee block{ number createdAt } - inputs { + inputs(order_by: { index: asc }) { address value sourceTxHash sourceTxIndex } - outputs{ + outputs(order_by: { index: asc }) { address index value } - + totalOutput includedAt } }` }) + graphQLData = graphQLResult.data.transactions[0] + }, 30000) - const restResultTotalOutput = restResult['Right']['ctsBlockHeight'] - const graphQLTotalOutput = graphQLResult['data']['transactions'][0]['block']['number'] + it('return the correct hash', async () => { + const restResultId = restData.ctsId + const graphQLHash = graphQLData.hash + + expect(graphQLHash).toEqual(restResultId) + }) + + it('return the correct Result Fee', async () => { + const restResultFee = restData.ctsFees.getCoin + const graphQLFee = graphQLData.fee + + expect(graphQLFee).toEqual(parseInt(restResultFee)) + }) + + it('return the correct Total Output', async () => { + const restResultTotalOutput = restData.ctsTotalOutput.getCoin + const graphQLTotalOutput = graphQLData.totalOutput expect(graphQLTotalOutput).toEqual(restResultTotalOutput) }) - it('return the correct Input Addresses', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - hash - fee - block{ - number - createdAt - } - inputs(order_by: { index: asc }) { - address - value - sourceTxHash - sourceTxIndex - } - outputs(order_by: { index: asc }){ - address - index - value - } - - totalOutput - includedAt - } - }` - }) + it('return the correct Block Height', async () => { + const restResultTotalOutput = restData.ctsBlockHeight + const graphQLTotalOutput = graphQLData.block.number + + expect(graphQLTotalOutput).toEqual(restResultTotalOutput) + }) - const restResultInputs = restResult['Right']['ctsInputs'] + it('return the correct Input Addresses', async () => { + const restResultInputs = restData.ctsInputs const restResultAddresses = [] for (const input of restResultInputs) { restResultAddresses.push(input[0]) } - const graphQLInputs = graphQLResult['data']['transactions'][0]['inputs'] + const graphQLInputs = graphQLData.inputs const graphQLAddresses = [] for (const input of graphQLInputs) { - graphQLAddresses.push(input['address']) + graphQLAddresses.push(input.address) } expect(graphQLAddresses).toEqual(restResultAddresses) }) it('return the correct Input Values', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - hash - fee - block{ - number - createdAt - } - inputs { - address - value - sourceTxHash - sourceTxIndex - } - outputs{ - address - index - value - } - - totalOutput - includedAt - } - }` - }) - - const restResultInputs = restResult['Right']['ctsInputs'] + const restResultInputs = restData.ctsInputs let restResultValues = 0 for (const input of restResultInputs) { - restResultValues += Number(input[1]['getCoin']) + restResultValues += Number(input[1].getCoin) } - const graphQLInputs = graphQLResult['data']['transactions'][0]['inputs'] + const graphQLInputs = graphQLData.inputs let graphQLValues = 0 for (const input of graphQLInputs) { - graphQLValues += Number(input['value']) + graphQLValues += Number(input.value) } expect(graphQLValues).toEqual(restResultValues) }) it('return the correct Output Addresses', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - hash - fee - block{ - number - createdAt - } - inputs(order_by: { index: asc }) { - address - value - sourceTxHash - sourceTxIndex - } - outputs(order_by: { index: asc }){ - address - index - value - } - - totalOutput - includedAt - } - }` - }) - - const restResultOutputs = restResult['Right']['ctsOutputs'] + const restResultOutputs = restData.ctsOutputs const restResultAddresses = [] for (const output of restResultOutputs) { restResultAddresses.push(output[0]) } - const graphQLOutputs = graphQLResult['data']['transactions'][0]['outputs'] + const graphQLOutputs = graphQLData.outputs const graphQLAddresses = [] for (const output of graphQLOutputs) { - graphQLAddresses.push(output['address']) + graphQLAddresses.push(output.address) } expect(graphQLAddresses).toEqual(restResultAddresses) }) it('return the correct Output Values', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - hash - fee - block{ - number - createdAt - } - inputs { - address - value - sourceTxHash - sourceTxIndex - } - outputs{ - address - index - value - } - - totalOutput - includedAt - } - }` - }) - - const restResultOutputs = restResult['Right']['ctsOutputs'] + const restResultOutputs = restData.ctsOutputs let restResultValues = 0 for (const output of restResultOutputs) { - restResultValues += Number(output[1]['getCoin']) + restResultValues += Number(output[1].getCoin) } - const graphQLOutputs = graphQLResult['data']['transactions'][0]['outputs'] + const graphQLOutputs = graphQLData.outputs let graphQLValues = 0 for (const output of graphQLOutputs) { - graphQLValues += Number(output['value']) + graphQLValues += Number(output.value) } expect(graphQLValues).toEqual(restResultValues) }) it('have the same block creation time', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - hash - fee - block{ - number - createdAt - } - inputs { - address - value - sourceTxHash - sourceTxIndex - } - outputs{ - address - index - value - } - - totalOutput - includedAt - } - }` - }) - - const restResultBlockTime = restResult['Right']['ctsBlockTimeIssued'] - const graphQLBlockTime = graphQLResult['data']['transactions'][0]['block']['createdAt'] + const restResultBlockTime = restData.ctsBlockTimeIssued + const graphQLBlockTime = graphQLData.block.createdAt expect(graphQLBlockTime).toEqual(timestampToIsoStringWithoutTimezone(restResultBlockTime)) }) it('have the same transaction inclusion time', async () => { - const restResult = await getDataFromAPI('txs/summary/1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762') - const graphQLResult = await client.query({ - query: gql`query TxByHash{ - transactions (where: {hash: {_eq:"1ac36644733c367ee4c551413d799d2e395d6ddfe14bebf1c281e6e826901762"}}) - { - hash - fee - block{ - number - createdAt - } - inputs { - address - value - sourceTxHash - sourceTxIndex - } - outputs{ - address - index - value - } - - totalOutput - includedAt - } - }` - }) - - const restResultTransactionTime = restResult['Right']['ctsTxTimeIssued'] - const graphQLTransactionTime = graphQLResult['data']['transactions'][0]['includedAt'] + const restResultTransactionTime = restData.ctsTxTimeIssued + const graphQLTransactionTime = graphQLData.includedAt expect(graphQLTransactionTime).toEqual(timestampToIsoStringWithoutTimezone(restResultTransactionTime)) }) diff --git a/src/__test__/util.ts b/src/__test__/util.ts new file mode 100644 index 00000000..3a60dd44 --- /dev/null +++ b/src/__test__/util.ts @@ -0,0 +1,10 @@ +import fetch from 'node-fetch' + +export async function getDataFromAPI (path: string) { + const response = await fetch(`https://explorer.cardano.org/api/${path}`) + return response.json() +} + +export function timestampToIsoStringWithoutTimezone (timestamp: number): string { + return new Date(timestamp * 1000).toISOString().substr(0, 19) +}