/* TODO: -getRawMempool --Add tests for 'verbose' input values -getMempoolEntry & getMempoolEntryBulk --Needs e2e test to create unconfirmed tx, for real-world test. */ "use strict" const chai = require("chai") const assert = chai.assert const sinon = require("sinon") const Blockchain = require("../../src/routes/v3/full-node/blockchain2") const uut = new Blockchain() const util = require("util") util.inspect.defaultOptions = { depth: 1 } if (!process.env.TEST) process.env.TEST = "unit" // Mocking data. const { mockReq, mockRes } = require("./mocks/express-mocks") const mockData = require("./mocks/blockchain-mock") let originalEnvVars // Used during transition from integration to unit tests. describe("#BlockchainRouter2", () => { let req, res let sandbox // local node will be started in regtest mode on the port 48332 //before(panda.runLocalNode) before(() => { // Save existing environment variables. originalEnvVars = { BITCOINCOM_BASEURL: process.env.BITCOINCOM_BASEURL, RPC_BASEURL: process.env.RPC_BASEURL, RPC_USERNAME: process.env.RPC_USERNAME, RPC_PASSWORD: process.env.RPC_PASSWORD } // Set default environment variables for unit tests. if (process.env.TEST === "unit") { process.env.BITCOINCOM_BASEURL = "http://fakeurl/api/" process.env.RPC_BASEURL = "http://fakeurl/api" process.env.RPC_USERNAME = "fakeusername" process.env.RPC_PASSWORD = "fakepassword" } }) // Setup the mocks before each test. beforeEach(() => { // Mock the req and res objects used by Express routes. req = mockReq res = mockRes // Explicitly reset the parmas and body. req.params = {} req.body = {} sandbox = sinon.createSandbox() }) afterEach(() => { // Restore Sandbox sandbox.restore() }) after(() => { // otherwise the panda will run forever //process.exit() // Restore any pre-existing environment variables. process.env.BITCOINCOM_BASEURL = originalEnvVars.BITCOINCOM_BASEURL process.env.RPC_BASEURL = originalEnvVars.RPC_BASEURL process.env.RPC_USERNAME = originalEnvVars.RPC_USERNAME process.env.RPC_PASSWORD = originalEnvVars.RPC_PASSWORD }) describe("#root", () => { it("should respond to GET for base route", async () => { const result = uut.root(req, res) assert.equal(result.status, "blockchain", "Returns static string") }) }) describe("getBestBlockHash()", () => { it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" const result = await uut.getBestBlockHash(req, res) // console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) const result = await uut.getBestBlockHash(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) const result = await uut.getBestBlockHash(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getBestBlockHash", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockBlockHash } }) } const result = await uut.getBestBlockHash(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isString(result) assert.equal(result.length, 64, "Hash string is fixed length") }) describe("getBlockchainInfo()", () => { it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" const result = await uut.getBlockchainInfo(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) const result = await uut.getBestBlockHash(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) const result = await uut.getBestBlockHash(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getBlockchainInfo", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockBlockchainInfo } }) } const result = await uut.getBlockchainInfo(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAnyKeys(result, [ "chain", "blocks", "headers", "bestblockhash", "difficulty", "mediantime", "verificationprogress", "chainwork", "pruned", "softforks", "bip9_softforks" ]) }) }) describe("getBlockCount()", () => { it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" const result = await uut.getBlockCount(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) const result = await uut.getBlockCount(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) const result = await uut.getBlockCount(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getBlockCount", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: 126769 } }) } const result = await uut.getBlockCount(req, res) //console.log(`result: ${util.inspect(result)}`) assert.isNumber(result) }) }) }) describe("getBlockHeaderSingle()", async () => { it("should throw 400 error if hash is missing", async () => { const result = await uut.getBlockHeaderSingle(req, res) // console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "hash can not be empty") }) it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" req.params.hash = "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" const result = await uut.getBlockHeaderSingle(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Network error: Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.params.hash = "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" const result = await uut.getBlockHeaderSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.params.hash = "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" const result = await uut.getBlockHeaderSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET block header", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox.stub(uut.axios, "request").resolves({ data: { result: "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c" } }) } req.params.hash = "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" const result = await uut.getBlockHeaderSingle(req, res) // console.log(`result: ${util.inspect(result)}`) assert.isString(result) assert.equal( result, "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c" ) }) it("should GET verbose block header", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockBlockHeader } }) } req.query.verbose = true req.params.hash = "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" const result = await uut.getBlockHeaderSingle(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, [ "hash", "confirmations", "height", "version", "versionHex", "merkleroot", "time", "mediantime", "nonce", "bits", "difficulty", "chainwork", "previousblockhash", "nextblockhash" ]) }) }) // describe("#getBlockHeaderBulk", () => { it("should throw an error for an empty body", async () => { req.body = {} const result = await uut.getBlockHeaderBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "hashes needs to be an array", "Proper error message" ) }) it("should error on non-array single hash", async () => { req.body.hashes = "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" const result = await uut.getBlockHeaderBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "hashes needs to be an array", "Proper error message" ) }) it("should throw 400 error if addresses array is too large", async () => { const testArray = [] for (var i = 0; i < 25; i++) testArray.push("") req.body.hashes = testArray const result = await uut.getBlockHeaderBulk(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "Array too large") }) it("should throw a 400 error for an invalid hash", async () => { req.body.hashes = ["badHash"] await uut.getBlockHeaderBulk(req, res) // console.log(`result: ${util.inspect(result)}`) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") }) it("should throw 500 when network issues", async () => { const savedUrl = process.env.BITCOINCOM_BASEURL try { req.body.hashes = [ "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" ] // Switch the Insight URL to something that will error out. process.env.BITCOINCOM_BASEURL = "http://fakeurl/api/" const result = await uut.getBlockHeaderBulk(req, res) // Restore the saved URL. process.env.BITCOINCOM_BASEURL = savedUrl assert.equal(res.statusCode, 500, "HTTP status code 500 expected.") assert.include(result.error, "ENOTFOUND", "Error message expected") } catch (err) { // Restore the saved URL. process.env.BITCOINCOM_BASEURL = savedUrl } }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.body.hashes = [ "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" ] const result = await uut.getBlockHeaderBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.body.hashes = [ "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" ] const result = await uut.getBlockHeaderBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should get concise block header for a single hash", async () => { req.body.hashes = [ "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" ] // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockBlockHeaderConcise } }) } // Call the details API. const result = await uut.getBlockHeaderBulk(req, res) // console.log(`result: ${util.inspect(result)}`) // Assert that required fields exist in the returned object. assert.isArray(result) assert.equal( result[0], "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c" ) }) it("should get verbose block header for a single hash", async () => { req.body = { hashes: [ "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" ], verbose: true } // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockBlockHeader } }) } // Call the details API. const result = await uut.getBlockHeaderBulk(req, res) //console.log(`result: ${util.inspect(result)}`) // Assert that required fields exist in the returned object. assert.isArray(result) assert.hasAllKeys(result[0], [ "hash", "confirmations", "height", "version", "versionHex", "merkleroot", "time", "mediantime", "nonce", "bits", "difficulty", "chainwork", "previousblockhash", "nextblockhash" ]) }) it("should get details for multiple block heights", async () => { req.body.hashes = [ "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0", "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" ] // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockBlockHeaderConcise } }) } // Call the details API. const result = await uut.getBlockHeaderBulk(req, res) //console.log(`result: ${util.inspect(result)}`) assert.isArray(result) assert.equal(result.length, 2, "2 outputs for 2 inputs") }) }) describe("getChainTips()", () => { it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" const result = await uut.getChainTips(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) const result = await uut.getChainTips(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) const result = await uut.getChainTips(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getChainTips", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockChainTips } }) } const result = await uut.getChainTips(req, res) //console.log(`result: ${util.inspect(result)}`) assert.isArray(result) assert.hasAnyKeys(result[0], ["height", "hash", "branchlen", "status"]) }) }) describe("getDifficulty()", () => { it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" const result = await uut.getDifficulty(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) const result = await uut.getDifficulty(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) const result = await uut.getDifficulty(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getDifficulty", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: 4049809.205246544 } }) } const result = await uut.getDifficulty(req, res) //console.log(`result: ${util.inspect(result)}`) assert.isNumber(result) }) }) describe("getMempoolInfo()", () => { it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" const result = await uut.getMempoolInfo(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) const result = await uut.getMempoolInfo(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) const result = await uut.getMempoolInfo(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getMempoolInfo", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockMempoolInfo } }) } const result = await uut.getMempoolInfo(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAnyKeys(result, [ "result", "bytes", "usage", "maxmempool", "mempoolminfree" ]) }) }) describe("getRawMempool()", () => { it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" const result = await uut.getRawMempool(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) const result = await uut.getRawMempool(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) const result = await uut.getRawMempool(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getMempoolInfo", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockRawMempool } }) } const result = await uut.getRawMempool(req, res) //console.log(`result: ${util.inspect(result)}`) assert.isArray(result) // Not sure what other assertions should be made here. }) }) describe("getMempoolEntrySingle()", () => { it("should throw 400 if txid is empty", async () => { const result = await uut.getMempoolEntrySingle(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "txid can not be empty") }) it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolEntrySingle(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolEntrySingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolEntrySingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getMempoolEntry", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox.stub(uut.axios, "request").resolves({ data: { result: { error: "Transaction not in mempool" } } }) } req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolEntrySingle(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.isString(result.error) assert.equal(result.error, "Transaction not in mempool") }) }) describe("#getMempoolEntryBulk", () => { it("should throw an error for an empty body", async () => { req.body = {} const result = await uut.getMempoolEntryBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "txids needs to be an array", "Proper error message" ) }) it("should error on non-array single txid", async () => { req.body.txids = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolEntryBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "txids needs to be an array", "Proper error message" ) }) it("should throw 400 error if addresses array is too large", async () => { const testArray = [] for (var i = 0; i < 25; i++) testArray.push("") req.body.txids = testArray const result = await uut.getMempoolEntryBulk(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "Array too large") }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.body.txids = [ `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` ] const result = await uut.getMempoolEntryBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.body.txids = [ `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` ] const result = await uut.getMempoolEntryBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) // Only execute on integration tests. if (process.env.TEST !== "unit") { // Dev-note: This test passes because it expects an error. TXIDs do not // stay in the mempool for long, so it does not work well for a unit or // integration test. it("should retrieve single mempool entry", async () => { req.body.txids = [ `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` ] const result = await uut.getMempoolEntryBulk(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.isString(result.error) assert.equal(result.error, "Transaction not in mempool") }) // Dev-note: This test passes because it expects an error. TXIDs do not // stay in the mempool for long, so it does not work well for a unit or // integration test. it("should retrieve multiple mempool entries", async () => { req.body.txids = [ `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde`, `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` ] const result = await uut.getMempoolEntryBulk(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.isString(result.error) assert.equal(result.error, "Transaction not in mempool") }) } }) describe("getMempoolAncestorsSingle()", () => { it("should throw 400 if txid is empty", async () => { const result = await uut.getMempoolAncestorsSingle(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "txid can not be empty") }) it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolAncestorsSingle(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolAncestorsSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getMempoolAncestorsSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getMempoolAncestorsSingle", async () => { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockAncestors } }) req.params.txid = `bb0d349892d351da2767f8c45f6f7949713ff09bd12838d53e76158ddee3ce93` const result = await uut.getMempoolAncestorsSingle(req, res) // console.log(`result: ${util.inspect(result)}`) assert.isArray(result) }) }) describe("getTxOut()", () => { it("should throw 400 if txid is empty", async () => { const result = await uut.getTxOut(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "txid can not be empty") }) it("should throw 400 if n is empty", async () => { req.params.txid = `sometxid` const result = await uut.getTxOut(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "n can not be empty") }) it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` req.params.n = 0 const result = await uut.getTxOut(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.params.txid = `197dcda59864b1eee05498fd3c52cad787ec56ab7e635503cb39f9ab6f295d5d` req.params.n = 0 req.query.include_mempool = "true" const result = await uut.getTxOut(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.params.txid = `197dcda59864b1eee05498fd3c52cad787ec56ab7e635503cb39f9ab6f295d5d` req.params.n = 0 req.query.include_mempool = "true" const result = await uut.getTxOut(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) // This test can only run for unit tests. See TODO at the top of this file. it("should GET /getTxOut", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockTxOut } }) } req.params.txid = `197dcda59864b1eee05498fd3c52cad787ec56ab7e635503cb39f9ab6f295d5d` req.params.n = 0 req.query.include_mempool = "true" const result = await uut.getTxOut(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.hasAllKeys(result, [ "bestblock", "confirmations", "value", "scriptPubKey", "coinbase" ]) assert.hasAllKeys(result.scriptPubKey, [ "asm", "hex", "reqSigs", "type", "addresses" ]) assert.isArray(result.scriptPubKey.addresses) }) }) describe("getTxOutProofSingle()", () => { it("should throw 400 if txid is empty", async () => { const result = await uut.getTxOutProofSingle(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "txid can not be empty") }) it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getTxOutProofSingle(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.params.txid = `197dcda59864b1eee05498fd3c52cad787ec56ab7e635503cb39f9ab6f295d5d` req.params.n = 0 req.query.include_mempool = "true" const result = await uut.getTxOutProofSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.params.txid = `197dcda59864b1eee05498fd3c52cad787ec56ab7e635503cb39f9ab6f295d5d` req.params.n = 0 req.query.include_mempool = "true" const result = await uut.getTxOutProofSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /getTxOutProof", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockTxOutProof } }) } req.params.txid = `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` const result = await uut.getTxOutProofSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isString(result) }) }) describe("#getTxOutProofBulk", () => { it("should throw an error for an empty body", async () => { req.body = {} const result = await uut.getTxOutProofBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "txids needs to be an array", "Proper error message" ) }) it("should error on non-array single txid", async () => { req.body.txids = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` const result = await uut.getTxOutProofBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "txids needs to be an array", "Proper error message" ) }) it("should throw 400 error if addresses array is too large", async () => { const testArray = [] for (var i = 0; i < 25; i++) testArray.push("") req.body.txids = testArray const result = await uut.getTxOutProofBulk(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "Array too large") }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.body.txids = [ `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` ] const result = await uut.getTxOutProofBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.body.txids = [ `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` ] const result = await uut.getTxOutProofBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET proof for single txid", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockTxOutProof } }) } req.body.txids = [ `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` ] const result = await uut.getTxOutProofBulk(req, res) //console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isArray(result) assert.isString(result[0]) }) it("should GET proof for multiple txids", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: mockData.mockTxOutProof } }) } req.body.txids = [ `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266`, `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` ] const result = await uut.getTxOutProofBulk(req, res) //console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isArray(result) assert.equal(result.length, 2, "Correct length of returned array") }) }) describe("verifyTxOutProofSingle()", () => { it("should throw 400 if proof is empty", async () => { const result = await uut.verifyTxOutProofSingle(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "proof can not be empty") }) it("should throw 503 when network issues", async () => { // Save the existing RPC URL. const savedUrl2 = process.env.RPC_BASEURL // Manipulate the URL to cause a 500 network error. process.env.RPC_BASEURL = "http://fakeurl/api/" req.params.proof = mockData.mockTxOutProof const result = await uut.verifyTxOutProofSingle(req, res) //console.log(`result: ${util.inspect(result)}`) // Restore the saved URL. process.env.RPC_BASEURL = savedUrl2 assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.params.proof = "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" const result = await uut.verifyTxOutProofSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.params.proof = "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" const result = await uut.verifyTxOutProofSingle(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should GET /verifyTxOutProof", async () => { const expected = "2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266" // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: [expected] } }) } req.params.proof = "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" const result = await uut.verifyTxOutProofSingle(req, res) //console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isArray(result) assert.isString(result[0]) assert.equal(result[0], expected) }) }) describe("#verifyTxOutProofBulk", () => { it("should throw an error for an empty body", async () => { req.body = {} const result = await uut.verifyTxOutProofBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "proofs needs to be an array", "Proper error message" ) }) it("should error on non-array single txid", async () => { req.body.proofs = mockData.mockTxOutProof const result = await uut.verifyTxOutProofBulk(req, res) assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") assert.include( result.error, "proofs needs to be an array", "Proper error message" ) }) it("should throw 400 error if addresses array is too large", async () => { const testArray = [] for (var i = 0; i < 25; i++) testArray.push("") req.body.proofs = testArray const result = await uut.verifyTxOutProofBulk(req, res) //console.log(`result: ${util.inspect(result)}`) assert.hasAllKeys(result, ["error"]) assert.include(result.error, "Array too large") }) it("returns proper error when downstream service stalls", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) req.body.proofs = [ "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" ] const result = await uut.verifyTxOutProofBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("returns proper error when downstream service is down", async () => { // Mock the timeout error. sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) req.body.proofs = [ "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" ] const result = await uut.verifyTxOutProofBulk(req, res) // console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") assert.include( result.error, "Could not communicate with full node", "Error message expected" ) }) it("should get single proof", async () => { const expected = "2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266" // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: [expected] } }) } req.body.proofs = [ "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" ] const result = await uut.verifyTxOutProofBulk(req, res) //console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isArray(result) assert.isString(result[0]) assert.equal(result[0], expected) }) it("should get multiple proofs", async () => { const expected = "2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266" // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { sandbox .stub(uut.axios, "request") .resolves({ data: { result: [expected] } }) } req.body.proofs = [ "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700", "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" ] const result = await uut.verifyTxOutProofBulk(req, res) //console.log(`result: ${JSON.stringify(result, null, 2)}`) assert.isArray(result) assert.isString(result[0]) assert.equal(result[0], expected) assert.equal(result.length, 2) }) }) })