diff --git a/src/controllers/json-rpc/bch/index.js b/src/controllers/json-rpc/bch/index.js index 5cb3ce9..2959c55 100644 --- a/src/controllers/json-rpc/bch/index.js +++ b/src/controllers/json-rpc/bch/index.js @@ -133,7 +133,7 @@ class BCHRPC { */ async balance (rpcData) { try { - console.log('createUser rpcData: ', rpcData) + // console.log('createUser rpcData: ', rpcData) const addrs = rpcData.payload.params.addresses diff --git a/test/e2e/manual/client/lib/test-utils.js b/test/e2e/manual/client/lib/test-utils.js deleted file mode 100644 index e87b14b..0000000 --- a/test/e2e/manual/client/lib/test-utils.js +++ /dev/null @@ -1,145 +0,0 @@ -/* - A class library of test utility functions. -*/ - -const BCHJS = require('@psf/bch-js') -const IpfsCoord = require('ipfs-coord') -const IPFS = require('ipfs') -const EventEmitter = require('events') - -let _this - -class TestUtils { - constructor (localConfig = {}) { - this.bchjs = new BCHJS() - this.eventEmitter = new EventEmitter() - - _this = this - } - - rpcHandler (inData) { - try { - console.log('inData: ', inData) - - _this.eventEmitter.emit('rpcData', inData) - } catch (err) { - console.error('Error in rpcHandler: ', err) - // Do not throw an error. This is a top-level function. - } - } - - async sendRPC (ipfsId, cmdStr) { - try { - await this.ipfsCoord.ipfs.orbitdb.sendToDb(ipfsId, cmdStr) - - let retData - - this.eventEmitter.on('rpcData', inData => { - retData = inData - }) - - const start = new Date() - let now = start - let timeDiff = 0 - - do { - await this.bchjs.Util.sleep(1000) - - now = new Date() - - timeDiff = now.getTime() - start.getTime() - console.log('timeDiff: ', timeDiff) - } while (!retData || timeDiff > 10000) // eslint-disable-line no-unmodified-loop-condition - - return retData - } catch (err) { - console.error('Error in sendRPC') - throw err - } - } - - async startIpfs () { - try { - // Start the IPFS node. - this.ipfs = await IPFS.create() - await this.ipfs.config.profiles.apply('server') - - // Start ipfs-coord. - this.ipfsCoord = new IpfsCoord({ - ipfs: this.ipfs, - type: 'node.js', - // type: 'browser', - bchjs: this.bchjs, - privateLog: this.rpcHandler, // Default to console.log - isCircuitRelay: false, - apiInfo: 'none', - announceJsonLd: announceJsonLd - }) - await this.ipfsCoord.ipfs.start() - await this.ipfsCoord.isReady() - - // Wait to let ipfs-coord connect to subnet peers. - await this.bchjs.Util.sleep(30000) - } catch (err) { - console.error('Error in startIpfs().') - throw err - } - } - - async connectToUut (addr) { - try { - await this.ipfs.swarm.connect(addr) - console.log(`E2E TEST: Connected to IPFS node ${addr}`) - } catch (err) { - console.error('Error in connectToUut()') - throw err - } - } - - // Get the balance for a BCH address over JSON RPC. - async getBalance (ipfsId) { - try { - const cmd = { - jsonrpc: '2.0', - id: '832', - method: 'bch', - params: { - endpoint: 'balance', - addresses: ['bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj'] - } - } - const cmdStr = JSON.stringify(cmd) - - console.log( - 'ipfs-coord peer info: ', - this.ipfsCoord.ipfs.peers.state.peers[ipfsId] - ) - - console.log(`Publishing message to ${ipfsId}`) - // await this.ipfsCoord.ipfs.pubsub.publishToPubsubChannel(ipfsId, cmdStr) - // await this.ipfsCoord.ipfs.orbitdb.sendToDb(ipfsId, cmdStr) - const result = await this.sendRPC(ipfsId, cmdStr) - console.log('E2E TEST: Balance command sent.') - - console.log('result: ', result) - } catch (err) { - console.error('Error in getBalance()') - throw err - } - } -} - -const announceJsonLd = { - '@context': 'https://schema.org/', - '@type': 'WebAPI', - name: 'e2e-test-client', - description: 'A test client runing e2e tests on ipfs-bch-wallet-service.', - documentation: 'https://ipfs-bch-wallet-service.fullstack.cash/', - provider: { - '@type': 'Organization', - name: 'Permissionless Software Foundation', - url: 'https://PSFoundation.cash' - } -} - -module.exports = TestUtils diff --git a/test/e2e/manual/client/README.md b/test/e2e/manual/consumer/README.md similarity index 57% rename from test/e2e/manual/client/README.md rename to test/e2e/manual/consumer/README.md index e5b7980..762466f 100644 --- a/test/e2e/manual/client/README.md +++ b/test/e2e/manual/consumer/README.md @@ -1,6 +1,6 @@ -# Client Simulation E2E Test +# Consumer Simulation E2E Test -The file in this directory simulates a client using JSON RPC over IPFS. It starts a new IPFS node that connects to the ipfs-bch-wallet-service and exercises each JSON RPC endpoint. +The files in this directory simulates a consumer of web services, using JSON RPC over IPFS. It starts a new IPFS node that connects to the ipfs-bch-wallet-service and exercises each JSON RPC endpoint. ## Instructions diff --git a/test/e2e/manual/client/client.e2e.js b/test/e2e/manual/consumer/consumer.e2e.js similarity index 56% rename from test/e2e/manual/client/client.e2e.js rename to test/e2e/manual/consumer/consumer.e2e.js index a7a8764..26c961a 100644 --- a/test/e2e/manual/client/client.e2e.js +++ b/test/e2e/manual/consumer/consumer.e2e.js @@ -10,11 +10,18 @@ const testData = require('./test-data.json') async function startTest () { try { + console.log('E2E TEST: Starting consumer E2E tests...') + await testUtils.startIpfs() - await testUtils.connectToUut(testData.uutAddr) + await testUtils.connectToUut(testData.uutAddr, testData.uutId) - await testUtils.getBalance(testData.uutId) + await testUtils.testBalance(testData.uutId) + + await testUtils.testTransaction(testData.uutId) + + console.log('E2E TEST: Tests completed successfully!') + process.exit() } catch (err) { console.error('Error in startTest(): ', err) } diff --git a/test/e2e/manual/consumer/lib/test-utils.js b/test/e2e/manual/consumer/lib/test-utils.js new file mode 100644 index 0000000..c208851 --- /dev/null +++ b/test/e2e/manual/consumer/lib/test-utils.js @@ -0,0 +1,217 @@ +/* + A class library of test utility functions. +*/ + +// Public npm libraries +const BCHJS = require('@psf/bch-js') +const IpfsCoord = require('ipfs-coord') +const IPFS = require('ipfs') +const EventEmitter = require('events') +const { v4: uid } = require('uuid') +const jsonrpc = require('jsonrpc-lite') + +let _this + +class TestUtils { + constructor (localConfig = {}) { + // Encapsulate dependencies. + this.bchjs = new BCHJS() + this.eventEmitter = new EventEmitter() + this.uid = uid + this.jsonrpc = jsonrpc + + _this = this + } + + // This handler function recieves data from other ipfs-coord peers, like + // the ipfs-bch-wallet-service that we're testing. + // It emits the data as an 'rpcData' event. The tests will listen for this + // event. + rpcHandler (inData) { + try { + // console.log('Data recieved by rpcHandler: ', inData) + + const jsonData = JSON.parse(inData) + + _this.eventEmitter.emit('rpcData', jsonData) + } catch (err) { + console.error('Error in rpcHandler: ', err) + // Do not throw an error. This is a top-level function. + } + } + + // Send the RPC command to the service, wait a period of time for a response. + // Timeout if a response is not recieved. + async sendRPC (ipfsId, cmdStr) { + try { + // Send the RPC command to the server/service. + await this.ipfsCoord.ipfs.orbitdb.sendToDb(ipfsId, cmdStr) + + let retData + + // This event is triggered when the response comes back. + this.eventEmitter.on('rpcData', inData => { + retData = inData + }) + + // Used for calculating the timeout. + const start = new Date() + let now = start + let timeDiff = 0 + + // Wait for the response from the server. Exit once the response is + // recieved, or a timeout occurs. + do { + await this.bchjs.Util.sleep(1000) + + now = new Date() + + timeDiff = now.getTime() - start.getTime() + // console.log('timeDiff: ', timeDiff) + } while ( + // Exit once the RPC data comes back, or if a period of time passes. + !retData || // eslint-disable-line no-unmodified-loop-condition + timeDiff > 10000 + ) + + return retData + } catch (err) { + console.error('Error in sendRPC') + throw err + } + } + + async startIpfs () { + try { + // Start the IPFS node. + this.ipfs = await IPFS.create() + await this.ipfs.config.profiles.apply('server') + + // Start ipfs-coord. + this.ipfsCoord = new IpfsCoord({ + ipfs: this.ipfs, + type: 'node.js', + // type: 'browser', + bchjs: this.bchjs, + privateLog: this.rpcHandler, // Default to console.log + isCircuitRelay: false, + apiInfo: 'none', + announceJsonLd: announceJsonLd + }) + await this.ipfsCoord.ipfs.start() + await this.ipfsCoord.isReady() + + // Wait to let ipfs-coord connect to subnet peers. + await this.bchjs.Util.sleep(30000) + } catch (err) { + console.error('Error in startIpfs().') + throw err + } + } + + // Connect to the unit under test (uut) + async connectToUut (addr, ipfsId) { + try { + try { + await this.ipfs.swarm.connect(addr) + console.log(`E2E TEST: Connected to IPFS node ${addr}`) + } catch (err) { + throw new Error('Could not connect to UUT IPFS node.') + } + + // console.log( + // 'ipfs-coord peer info: ', + // this.ipfsCoord.ipfs.peers.state.peers[ipfsId] + // ) + if (!this.ipfsCoord.ipfs.peers.state.peers[ipfsId]) { + throw new Error('Could not find UUT in ipfs-coord list of peers.') + } + } catch (err) { + console.error('Error in connectToUut()') + console.log( + 'Is the service running? Did you update the test-data.json file?' + ) + process.exit() + } + } + + // Get the balance for a BCH address over JSON RPC. + async testBalance (ipfsId) { + try { + // Generate the JSON RPC command + const id = uid() + const cmd = jsonrpc.request(id, 'bch', { + endpoint: 'balance', + addresses: ['bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj'] + }) + const cmdStr = JSON.stringify(cmd) + + // console.log(`Publishing message to ${ipfsId}`) + + console.log('E2E TEST: Sending Balance command...') + const result = await this.sendRPC(ipfsId, cmdStr) + // console.log('result: ', result) + + if (result.result.value.success && result.result.value.balances) { + console.log('E2E TEST: balance test passed.') + return true + } else { + console.log('E2E TEST: balance test failed.') + this.failTest() + } + } catch (err) { + console.error('Error in testBalance()') + throw err + } + } + + // Get the info a on transaction over JSON RPC. + async testTransaction (ipfsId) { + try { + // Generate the JSON RPC command + const id = uid() + const cmd = jsonrpc.request(id, 'bch', { + endpoint: 'transaction', + txid: '01517ff1587fa5ffe6f5eb91c99cf3f2d22330cd7ee847e928ce90ca95bf781b' + }) + const cmdStr = JSON.stringify(cmd) + + // console.log(`Publishing message to ${ipfsId}`) + + console.log('E2E TEST: Sending Transaction command...') + const result = await this.sendRPC(ipfsId, cmdStr) + // console.log('result: ', result) + + if (result.result.value.status && result.result.value.confirmations) { + console.log('E2E TEST: transaction test passed.') + return true + } else { + console.log('E2E TEST: transaction test failed.') + this.failTest() + } + } catch (err) { + console.error('Error in testTransaction()') + throw err + } + } + + failTest () { + console.log('Exiting test program.') + process.exit() + } +} + +const announceJsonLd = { + '@context': 'https://schema.org/', + '@type': 'WebAPI', + name: 'e2e-test-client', + description: 'A test client runing e2e tests on ipfs-bch-wallet-service.', + documentation: 'https://ipfs-bch-wallet-service.fullstack.cash/', + provider: { + '@type': 'Organization', + name: 'Permissionless Software Foundation', + url: 'https://PSFoundation.cash' + } +} + +module.exports = TestUtils diff --git a/test/e2e/manual/client/test-data.json b/test/e2e/manual/consumer/test-data.json similarity index 100% rename from test/e2e/manual/client/test-data.json rename to test/e2e/manual/consumer/test-data.json