diff --git a/api/controllers/blocks.js b/api/controllers/blocks.js new file mode 100644 index 00000000..f43ab0b2 --- /dev/null +++ b/api/controllers/blocks.js @@ -0,0 +1,30 @@ +'use strict'; + +var bitcore = require('bitcore'); +var Block = bitcore.Block; + +// mocks +var genesishex = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; +var genesisbuf = new Buffer(genesishex, 'hex'); +var mockBlock = new Block(genesisbuf); + +function Blocks() {} + + +// params +Blocks.blockHashParam = function(req, res, next, blockHash) { + blockHash.toString(); // TODO: fetch block from service + req.block = mockBlock; + next(); +}; + + +Blocks.getBlock = function(req, res) { + res.send(req.block.toObject()); +}; +Blocks.getBlockError = function(req, res) { + res.status(422); + res.send('blockHash parameter must be a 64 digit hex'); +}; + +module.exports = Blocks; diff --git a/api/routes/v1.js b/api/routes/v1.js index dec035bb..f5c925e3 100644 --- a/api/routes/v1.js +++ b/api/routes/v1.js @@ -1,6 +1,8 @@ 'use strict'; var express = require('express'); +var Blocks = require('../controllers/blocks'); + function initRouter(node) { var router = express.Router(); @@ -9,23 +11,27 @@ function initRouter(node) { res.send({'message': 'This is a mocked response'}); } + // parameter middleware + router.param('blockHash', Blocks.blockHashParam); + // Node routes router.get('/node', mockResponse); // Block routes router.get('/blocks', mockResponse); router.get('/blocks/latest', mockResponse); - router.get('/blocks/:blockHash', mockResponse); - router.get('/blocks/:height', mockResponse); + router.get('/blocks/:blockHash([A-Fa-f0-9]{64})', Blocks.getBlock); + router.get('/blocks/*', Blocks.getBlockError); + router.get('/blocks/:height([0-9]+)', mockResponse); router.get('/blocks/:blockHash/transactions/:txIndex', mockResponse); // Transaction routes router.get('/transactions', mockResponse); router.get('/transactions/:txHash', mockResponse); - router.post('/transactions/send', mockResponse); router.get('/transactions/:txHash/addresses', mockResponse); router.get('/transactions/:txHash/outputs/addresses', mockResponse); router.get('/transactions/:txHash/inputs/addresses', mockResponse); + router.post('/transactions/send', mockResponse); // Input routes router.get('/transactions/:txHash/inputs', mockResponse); diff --git a/api/test/routes.js b/api/test/routes.js index 70d987aa..a489476f 100644 --- a/api/test/routes.js +++ b/api/test/routes.js @@ -29,12 +29,5 @@ describe('BitcoreHTTP routes', function() { .expect(200) .expect('bitcore-node API', cb); }); - it('blocks', function(cb) { - agent.get('/v1/blocks/') - .expect(200) - .expect({ - 'message': 'This is a mocked response' - }, cb); - }); }); diff --git a/api/test/v1/blocks.js b/api/test/v1/blocks.js new file mode 100644 index 00000000..006c10cf --- /dev/null +++ b/api/test/v1/blocks.js @@ -0,0 +1,45 @@ +'use strict'; + +var chai = require('chai'); +var should = chai.should(); +var request = require('supertest'); + +var EventEmitter = require('eventemitter2').EventEmitter2; + +var BitcoreHTTP = require('../../lib/http'); + +describe('BitcoreHTTP v1 blocks routes', function() { + + // mocks + var nodeMock, app, agent; + beforeEach(function() { + var opts = { + port: 1234 + }; + nodeMock = new EventEmitter(); + app = new BitcoreHTTP(nodeMock, opts).app; + agent = request(app); + }); + describe('/blocks', function() { + it('works with default parameters', function(cb) { + agent.get('/v1/blocks/') + .expect(200) + .expect({ + 'message': 'This is a mocked response' + }, cb); + }); + }); + describe('/blocks/:blockHash', function() { + it('fails with invalid blockHash', function(cb) { + agent.get('/v1/blocks/abad1dea') + .expect(422) + .expect('blockHash parameter must be a 64 digit hex', cb); + }); + it('works with valid blockHash', function(cb) { + agent.get('/v1/blocks/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f') + .expect(200) + .expect('{"header":{"version":1,"prevHash":"0000000000000000000000000000000000000000000000000000000000000000","merkleRoot":"3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a","time":1231006505,"bits":486604799,"nonce":2083236893},"transactions":[{"version":1,"inputs":[{"prevTxId":"0000000000000000000000000000000000000000000000000000000000000000","outputIndex":4294967295,"sequenceNumber":4294967295,"script":"4 0xffff001d 1 0x04 69 0x5468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73"}],"outputs":[{"satoshis":5000000000,"script":"65 0x04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG"}],"nLockTime":0}]}', cb); + }); + }); + +});