Merge pull request #24 from maraoz/tdd/api
add tests for REST API with mocked services
This commit is contained in:
commit
d704a6d143
102
api/controllers/blocks.js
Normal file
102
api/controllers/blocks.js
Normal file
@ -0,0 +1,102 @@
|
||||
'use strict';
|
||||
|
||||
var bitcore = require('bitcore');
|
||||
var _ = bitcore.deps._;
|
||||
var $ = bitcore.util.preconditions;
|
||||
var Block = bitcore.Block;
|
||||
|
||||
var BitcoreNode = require('../../');
|
||||
|
||||
var Blocks = {};
|
||||
|
||||
var node;
|
||||
Blocks.setNode = function(aNode) {
|
||||
node = aNode;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* params
|
||||
*/
|
||||
|
||||
/*
|
||||
* Finds a block by its hash
|
||||
*/
|
||||
Blocks.blockHashParam = function(req, res, next, blockHash) {
|
||||
node.getBlock(blockHash)
|
||||
.then(function(block) {
|
||||
req.block = block;
|
||||
})
|
||||
.then(next)
|
||||
.catch(BitcoreNode.errors.Blocks.NotFound, function() {
|
||||
res.status(404).send('Block with id ' + blockHash + ' not found');
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Finds a block by its height
|
||||
*/
|
||||
Blocks.heightParam = function(req, res, next, height) {
|
||||
height = parseInt(height);
|
||||
node.getBlock(height)
|
||||
.then(function(block) {
|
||||
req.block = block;
|
||||
})
|
||||
.then(next)
|
||||
.catch(BitcoreNode.errors.Blocks.NotFound, function() {
|
||||
res.status(404).send('Block with height ' + height + ' not found');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* controllers
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns a list of blocks given certain query options.
|
||||
*
|
||||
* from: block height as lower limit (default: 0)
|
||||
* to: ditto, but for the upper limit, non inclusive (default: 1000000)
|
||||
* page: for paginating results (default: 0)
|
||||
* offset: skip the first offset blocks (default: 0)
|
||||
* limit: max amount of blocks returned (default: 10)
|
||||
*
|
||||
*/
|
||||
Blocks.list = function(req, res) {
|
||||
var from = parseInt(req.query.from || 0);
|
||||
var to = parseInt(req.query.to || 1e6);
|
||||
var offset = parseInt(req.query.offset || 0);
|
||||
var limit = parseInt(req.query.limit || 10);
|
||||
|
||||
if (to < from) {
|
||||
res.status(422);
|
||||
res.send('/v1/blocks/ "to" must be >= to "from"');
|
||||
return;
|
||||
}
|
||||
|
||||
node.listBlocks(from, to, offset, limit)
|
||||
.then(function(blocks) {
|
||||
res.send(blocks);
|
||||
});
|
||||
};
|
||||
|
||||
Blocks.getLatest = function(req, res) {
|
||||
node.getLatestBlock()
|
||||
.then(function(block) {
|
||||
req.block = block;
|
||||
Blocks.get(req, res);
|
||||
});
|
||||
};
|
||||
|
||||
Blocks.get = function(req, res) {
|
||||
$.checkState(req.block instanceof Block);
|
||||
res.send(req.block.toObject());
|
||||
};
|
||||
|
||||
Blocks.getBlockError = function(req, res) {
|
||||
res.status(422);
|
||||
res.send('/v1/blocks/ parameter must be a 64 digit hex or block height integer');
|
||||
};
|
||||
|
||||
module.exports = Blocks;
|
||||
16
api/controllers/node.js
Normal file
16
api/controllers/node.js
Normal file
@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
var NodeStatus = {};
|
||||
var node;
|
||||
NodeStatus.setNode = function(aNode) {
|
||||
node = aNode;
|
||||
};
|
||||
|
||||
NodeStatus.getStatus = function(req, res) {
|
||||
node.getStatus()
|
||||
.then(function(status) {
|
||||
res.send(status);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = NodeStatus;
|
||||
88
api/controllers/transactions.js
Normal file
88
api/controllers/transactions.js
Normal file
@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
var Promise = require('bluebird');
|
||||
|
||||
var bitcore = require('bitcore');
|
||||
var _ = bitcore.deps._;
|
||||
var $ = bitcore.util.preconditions;
|
||||
var Transaction = bitcore.Transaction;
|
||||
|
||||
var BitcoreNode = require('../../');
|
||||
|
||||
var Transactions = {};
|
||||
|
||||
var node;
|
||||
Transactions.setNode = function(aNode) {
|
||||
node = aNode;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* params
|
||||
*/
|
||||
|
||||
/*
|
||||
* Finds a transaction by its hash
|
||||
*/
|
||||
Transactions.txHashParam = function(req, res, next, txHash) {
|
||||
node.getTransaction(txHash)
|
||||
.then(function(tx) {
|
||||
req.tx = tx;
|
||||
})
|
||||
.then(next)
|
||||
.catch(BitcoreNode.errors.Transactions.NotFound, function() {
|
||||
res.status(404).send('Transaction with id ' + txHash + ' not found');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* controllers
|
||||
*/
|
||||
|
||||
/*
|
||||
* get transaction by its hash
|
||||
*/
|
||||
Transactions.get = function(req, res) {
|
||||
$.checkState(req.tx instanceof Transaction);
|
||||
res.send(req.tx.toObject());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* send a transaction to the bitcoin network
|
||||
*/
|
||||
Transactions.send = function(req, res) {
|
||||
var raw = req.body.raw;
|
||||
if (_.isUndefined(raw)) {
|
||||
Transaction._sendError(res);
|
||||
return;
|
||||
}
|
||||
var tx;
|
||||
try {
|
||||
tx = new Transaction(raw);
|
||||
} catch (e) {
|
||||
Transaction._sendError(res);
|
||||
return;
|
||||
}
|
||||
node.broadcast(tx)
|
||||
.then(function() {
|
||||
res.send('Transaction broadcasted successfully');
|
||||
})
|
||||
.catch(BitcoreNode.errors.Transactions.CantBroadcast, function(err) {
|
||||
res.status(422).send(err.message);
|
||||
});
|
||||
};
|
||||
|
||||
Transaction._sendError = function(res) {
|
||||
res.status(422);
|
||||
res.send('/v1/transactions/send parameter must be a raw transaction hex');
|
||||
};
|
||||
|
||||
|
||||
Transactions.getTxError = function(req, res) {
|
||||
res.status(422);
|
||||
res.send('/v1/transactions/ parameter must be a 64 digit hex');
|
||||
};
|
||||
|
||||
module.exports = Transactions;
|
||||
@ -1,8 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('config');
|
||||
var BitcoreHTTP = require('./lib/http');
|
||||
|
||||
var http = BitcoreHTTP.create(config.get('BitcoreHTTP'));
|
||||
http.start();
|
||||
if (require.main === module) {
|
||||
var config = require('config');
|
||||
var http = BitcoreHTTP.create(config.get('BitcoreHTTP'));
|
||||
http.start();
|
||||
}
|
||||
|
||||
module.exports = BitcoreHTTP;
|
||||
|
||||
@ -1,31 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var NodeStatus = require('../controllers/node');
|
||||
var Blocks = require('../controllers/blocks');
|
||||
var Transactions = require('../controllers/transactions');
|
||||
|
||||
|
||||
function initRouter(node) {
|
||||
var router = express.Router();
|
||||
|
||||
[NodeStatus, Blocks, Transactions].forEach(function(controller) {
|
||||
controller.setNode(node);
|
||||
});
|
||||
|
||||
function mockResponse(req, res) {
|
||||
res.send({'message': 'This is a mocked response'});
|
||||
res.send({
|
||||
'message': 'This is a mocked response'
|
||||
});
|
||||
}
|
||||
|
||||
// parameter middleware
|
||||
router.param('blockHash', Blocks.blockHashParam);
|
||||
router.param('height', Blocks.heightParam);
|
||||
router.param('txHash', Transactions.txHashParam);
|
||||
|
||||
// Node routes
|
||||
router.get('/node', mockResponse);
|
||||
router.get('/node', NodeStatus.getStatus);
|
||||
|
||||
// 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/transactions/:txIndex', mockResponse);
|
||||
router.get('/blocks', Blocks.list);
|
||||
router.get('/blocks/latest', Blocks.getLatest);
|
||||
router.get('/blocks/:blockHash([A-Fa-f0-9]{64})', Blocks.get);
|
||||
router.get('/blocks/:height([0-9]+)', Blocks.get);
|
||||
|
||||
// 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.get('/transactions/:txHash([A-Fa-f0-9]{64})', Transactions.get);
|
||||
router.post('/transactions/send', Transactions.send);
|
||||
|
||||
// Input routes
|
||||
router.get('/transactions/:txHash/inputs', mockResponse);
|
||||
@ -42,6 +53,10 @@ function initRouter(node) {
|
||||
// TODO: check if this is really restful
|
||||
router.get('/addresses/:addresses/utxos', mockResponse);
|
||||
|
||||
// error routes
|
||||
router.get('/blocks/*', Blocks.getBlockError);
|
||||
router.get('/transactions/*', Transactions.getTxError);
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
|
||||
15
api/test/data/blocks.js
Normal file
15
api/test/data/blocks.js
Normal file
@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
var bitcore = require('bitcore');
|
||||
var Block = bitcore.Block;
|
||||
|
||||
var mockBlocks = {};
|
||||
var blockHexs = require('./blocks.json');
|
||||
blockHexs.map(function(hex) {
|
||||
var block = new Block(new Buffer(hex, 'hex'));
|
||||
return block;
|
||||
}).forEach(function(block) {
|
||||
mockBlocks[block.id] = block;
|
||||
});
|
||||
|
||||
module.exports = mockBlocks;
|
||||
12
api/test/data/blocks.json
Normal file
12
api/test/data/blocks.json
Normal file
File diff suppressed because one or more lines are too long
17
api/test/data/transactions.js
Normal file
17
api/test/data/transactions.js
Normal file
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
var bitcore = require('bitcore');
|
||||
var Block = bitcore.Block;
|
||||
|
||||
var mockTransactions = {};
|
||||
var blockHexs = require('./blocks.json');
|
||||
blockHexs.map(function(hex) {
|
||||
var block = new Block(new Buffer(hex, 'hex'));
|
||||
return block;
|
||||
}).forEach(function(block) {
|
||||
block.transactions.forEach(function(tx) {
|
||||
mockTransactions[tx.id] = tx;
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = mockTransactions;
|
||||
@ -10,6 +10,9 @@ var BitcoreHTTP = require('../lib/http');
|
||||
describe('BitcoreHTTP', function() {
|
||||
|
||||
// mocks
|
||||
var opts = {
|
||||
port: 1234
|
||||
};
|
||||
var nodeMock;
|
||||
beforeEach(function() {
|
||||
nodeMock = new EventEmitter();
|
||||
@ -25,7 +28,7 @@ describe('BitcoreHTTP', function() {
|
||||
});
|
||||
});
|
||||
it('starts', function() {
|
||||
var http = new BitcoreHTTP(nodeMock);
|
||||
var http = new BitcoreHTTP(nodeMock, opts);
|
||||
http.start.bind(http).should.not.throw();
|
||||
});
|
||||
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
147
api/test/v1/blocks.js
Normal file
147
api/test/v1/blocks.js
Normal file
@ -0,0 +1,147 @@
|
||||
'use strict';
|
||||
|
||||
var chai = require('chai');
|
||||
var should = chai.should();
|
||||
var request = require('supertest');
|
||||
|
||||
var EventEmitter = require('eventemitter2').EventEmitter2;
|
||||
var Promise = require('bluebird');
|
||||
Promise.longStackTraces();
|
||||
var bitcore = require('bitcore');
|
||||
var _ = bitcore.deps._;
|
||||
|
||||
var BitcoreHTTP = require('../../lib/http');
|
||||
var BitcoreNode = require('../../../');
|
||||
var mockBlocks = require('../data/blocks');
|
||||
|
||||
Object.values = function(obj) {
|
||||
var vals = [];
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
vals.push(obj[key]);
|
||||
}
|
||||
}
|
||||
return vals;
|
||||
};
|
||||
|
||||
describe('BitcoreHTTP v1 blocks routes', function() {
|
||||
|
||||
// mocks
|
||||
var b1 = mockBlocks[Object.keys(mockBlocks)[0]];
|
||||
var firstBlock = mockBlocks[Object.keys(mockBlocks).splice(0, 1)[0]];
|
||||
var secondBlock = mockBlocks[Object.keys(mockBlocks).splice(1, 1)[0]];
|
||||
var lastBlock = mockBlocks[Object.keys(mockBlocks).splice(-1)[0]];
|
||||
var blockForHash = function(hash) {
|
||||
return mockBlocks[hash];
|
||||
};
|
||||
var last3 = Object.keys(mockBlocks).splice(-3).map(blockForHash);
|
||||
var some2 = Object.keys(mockBlocks).splice(2,2).map(blockForHash);
|
||||
var nodeMock, app, agent;
|
||||
var blockList = Object.values(mockBlocks);
|
||||
beforeEach(function() {
|
||||
nodeMock = new EventEmitter();
|
||||
nodeMock.getBlock = function(blockHash) {
|
||||
var block;
|
||||
if (typeof blockHash === 'number') {
|
||||
var height = blockHash;
|
||||
block = mockBlocks[Object.keys(mockBlocks)[height - 100000]];
|
||||
} else {
|
||||
block = mockBlocks[blockHash];
|
||||
}
|
||||
if (_.isUndefined(block)) {
|
||||
return Promise.reject(new BitcoreNode.errors.Blocks.NotFound(blockHash));
|
||||
}
|
||||
return Promise.resolve(block);
|
||||
|
||||
};
|
||||
nodeMock.getLatestBlock = function() {
|
||||
return Promise.resolve(lastBlock);
|
||||
};
|
||||
nodeMock.listBlocks = function(from, to, offset, limit) {
|
||||
var start = from - 1e5;
|
||||
var end = to - 1e5;
|
||||
var section = blockList.slice(start, end);
|
||||
return Promise.resolve(section.slice(offset, offset + limit));
|
||||
};
|
||||
app = new BitcoreHTTP(nodeMock).app;
|
||||
agent = request(app);
|
||||
});
|
||||
|
||||
describe('/blocks', function() {
|
||||
it('works with default parameters', function(cb) {
|
||||
agent.get('/v1/blocks/')
|
||||
.expect(200)
|
||||
.expect(JSON.stringify(blockList), cb);
|
||||
});
|
||||
it('fails with to<from', function(cb) {
|
||||
agent.get('/v1/blocks/?from=100000&to=99999')
|
||||
.expect(422)
|
||||
.expect('/v1/blocks/ "to" must be >= to "from"', cb);
|
||||
});
|
||||
it('works with to/from parameters', function(cb) {
|
||||
agent.get('/v1/blocks/?from=100000&to=100001')
|
||||
.expect(200)
|
||||
.expect(JSON.stringify([firstBlock]), cb);
|
||||
});
|
||||
it('works with limit/offset parameters', function(cb) {
|
||||
agent.get('/v1/blocks/?limit=1&offset=1')
|
||||
.expect(200)
|
||||
.expect(JSON.stringify([secondBlock]), cb);
|
||||
});
|
||||
it('works with all parameters', function(cb) {
|
||||
agent.get('/v1/blocks/?from=100005&to=100020&limit=3&offset=2')
|
||||
.expect(200)
|
||||
.expect(JSON.stringify(last3), cb);
|
||||
});
|
||||
it('works with all parameters 2', function(cb) {
|
||||
agent.get('/v1/blocks/?from=100000&to=100005&limit=2&offset=2')
|
||||
.expect(200)
|
||||
.expect(JSON.stringify(some2), cb);
|
||||
});
|
||||
});
|
||||
describe('/blocks/latest', function() {
|
||||
it('returns latest block', function(cb) {
|
||||
agent.get('/v1/blocks/latest')
|
||||
.expect(200)
|
||||
.expect(lastBlock.toJSON(), cb);
|
||||
});
|
||||
});
|
||||
describe('/blocks/:blockHash', function() {
|
||||
it('fails with invalid blockHash', function(cb) {
|
||||
agent.get('/v1/blocks/abad1dea')
|
||||
.expect(422)
|
||||
.expect('/v1/blocks/ parameter must be a 64 digit hex or block height integer', cb);
|
||||
});
|
||||
it('returns 404 with non existent block', function(cb) {
|
||||
agent.get('/v1/blocks/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b600000000')
|
||||
.expect(404)
|
||||
.expect('Block with id 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b600000000 not found', cb);
|
||||
});
|
||||
Object.keys(mockBlocks).forEach(function(hash) {
|
||||
var block = mockBlocks[hash];
|
||||
it('works with valid blockHash ...' + hash.substring(hash.length - 8), function(cb) {
|
||||
agent.get('/v1/blocks/' + hash)
|
||||
.expect(200)
|
||||
.expect(block.toJSON(), cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('/blocks/:height', function() {
|
||||
it('fails with invalid height', function(cb) {
|
||||
agent.get('/v1/blocks/-15')
|
||||
.expect(422)
|
||||
.expect('/v1/blocks/ parameter must be a 64 digit hex or block height integer', cb);
|
||||
});
|
||||
it('returns 404 with non existent block', function(cb) {
|
||||
agent.get('/v1/blocks/876543')
|
||||
.expect(404)
|
||||
.expect('Block with height 876543 not found', cb);
|
||||
});
|
||||
it('works with valid height', function(cb) {
|
||||
agent.get('/v1/blocks/100000')
|
||||
.expect(200)
|
||||
.expect(b1.toJSON(), cb);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
39
api/test/v1/node.js
Normal file
39
api/test/v1/node.js
Normal file
@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
var chai = require('chai');
|
||||
var should = chai.should();
|
||||
var request = require('supertest');
|
||||
|
||||
var EventEmitter = require('eventemitter2').EventEmitter2;
|
||||
var Promise = require('bluebird');
|
||||
Promise.longStackTraces();
|
||||
|
||||
var BitcoreHTTP = require('../../lib/http');
|
||||
|
||||
describe('BitcoreHTTP v1 node routes', function() {
|
||||
|
||||
// mocks
|
||||
var nodeMock, app, agent;
|
||||
beforeEach(function() {
|
||||
nodeMock = new EventEmitter();
|
||||
nodeMock.status = {
|
||||
sync: 0.75,
|
||||
peer_count: 8,
|
||||
version: 'test'
|
||||
};
|
||||
nodeMock.getStatus = function() {
|
||||
return Promise.resolve(nodeMock.status);
|
||||
};
|
||||
app = new BitcoreHTTP(nodeMock).app;
|
||||
agent = request(app);
|
||||
});
|
||||
|
||||
describe('/node', function() {
|
||||
it('works', function(cb) {
|
||||
agent.get('/v1/node/')
|
||||
.expect(200)
|
||||
.expect(nodeMock.status, cb);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
112
api/test/v1/transactions.js
Normal file
112
api/test/v1/transactions.js
Normal file
@ -0,0 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
var chai = require('chai');
|
||||
var should = chai.should();
|
||||
var request = require('supertest');
|
||||
|
||||
var bitcore = require('bitcore');
|
||||
var _ = bitcore.deps._;
|
||||
var Transaction = bitcore.Transaction;
|
||||
var EventEmitter = require('eventemitter2').EventEmitter2;
|
||||
var Promise = require('bluebird');
|
||||
Promise.longStackTraces();
|
||||
|
||||
var BitcoreHTTP = require('../../lib/http');
|
||||
var BitcoreNode = require('../../../');
|
||||
var mockTransactions = require('../data/transactions');
|
||||
|
||||
describe('BitcoreHTTP v1 transactions routes', function() {
|
||||
|
||||
// mocks
|
||||
var mockValidTx = new Transaction();
|
||||
var t1 = mockTransactions[Object.keys(mockTransactions)[0]];
|
||||
var nodeMock, app, agent;
|
||||
beforeEach(function() {
|
||||
nodeMock = new EventEmitter();
|
||||
nodeMock.getTransaction = function(txHash) {
|
||||
var tx = mockTransactions[txHash];
|
||||
if (_.isUndefined(tx)) {
|
||||
return Promise.reject(new BitcoreNode.errors.Transactions.NotFound(txHash));
|
||||
}
|
||||
return Promise.resolve(tx);
|
||||
};
|
||||
nodeMock.broadcast = function(tx) {
|
||||
if (mockTransactions[tx.id]) {
|
||||
return Promise.reject(new BitcoreNode.errors.Transactions.CantBroadcast(tx.id));
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
app = new BitcoreHTTP(nodeMock).app;
|
||||
agent = request(app);
|
||||
});
|
||||
|
||||
describe('/transactions', function() {
|
||||
it('works with default parameters', function(cb) {
|
||||
agent.get('/v1/transactions/')
|
||||
.expect(200)
|
||||
.expect({
|
||||
'message': 'This is a mocked response'
|
||||
}, cb);
|
||||
});
|
||||
});
|
||||
describe('/transactions/:txHash', function() {
|
||||
it('fails with invalid txHash', function(cb) {
|
||||
agent.get('/v1/transactions/abad1dea')
|
||||
.expect(422)
|
||||
.expect('/v1/transactions/ parameter must be a 64 digit hex', cb);
|
||||
});
|
||||
it('returns 404 with non existent transaction', function(cb) {
|
||||
agent.get('/v1/transactions/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b600000000')
|
||||
.expect(404)
|
||||
.expect('Transaction with id 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b600000000 not found', cb);
|
||||
});
|
||||
Object.keys(mockTransactions).forEach(function(hash) {
|
||||
it('works with valid txHash ...' + hash.substring(hash.length - 8), function(cb) {
|
||||
agent.get('/v1/transactions/' + hash)
|
||||
.expect(200)
|
||||
.expect(mockTransactions[hash].toJSON(), cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('/transactions/send', function() {
|
||||
it('fails with invalid data type', function(cb) {
|
||||
agent.post('/v1/transactions/send')
|
||||
.send('some random data')
|
||||
.expect(422)
|
||||
.expect('/v1/transactions/send parameter must be a raw transaction hex', cb);
|
||||
});
|
||||
it('fails with invalid data format', function(cb) {
|
||||
agent.post('/v1/transactions/send')
|
||||
.send({
|
||||
1: 2
|
||||
})
|
||||
.expect(422)
|
||||
.expect('/v1/transactions/send parameter must be a raw transaction hex', cb);
|
||||
});
|
||||
it('fails with valid data format, invalid raw tx', function(cb) {
|
||||
agent.post('/v1/transactions/send')
|
||||
.send({
|
||||
raw: '00abad1d3a'
|
||||
})
|
||||
.expect(422)
|
||||
.expect('/v1/transactions/send parameter must be a raw transaction hex', cb);
|
||||
});
|
||||
it('works with valid tx', function(cb) {
|
||||
agent.post('/v1/transactions/send')
|
||||
.send({
|
||||
raw: mockValidTx.uncheckedSerialize()
|
||||
})
|
||||
.expect(200)
|
||||
.expect('Transaction broadcasted successfully', cb);
|
||||
});
|
||||
it('fails with invalid tx', function(cb) {
|
||||
agent.post('/v1/transactions/send')
|
||||
.send({
|
||||
raw: t1.uncheckedSerialize()
|
||||
})
|
||||
.expect(422)
|
||||
.expect('Unable to broadcast transaction 8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87', cb);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
7
index.js
7
index.js
@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('config');
|
||||
|
||||
var BitcoreNode = require('./lib/node.js');
|
||||
var BitcoreNode = require('./lib/node');
|
||||
|
||||
if (require.main === module) {
|
||||
var config = require('config');
|
||||
var node = BitcoreNode.create(config.get('BitcoreNode'));
|
||||
node.start();
|
||||
node.on('error', function(err) {
|
||||
@ -16,4 +16,7 @@ if (require.main === module) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
BitcoreNode.errors = require('./lib/errors');
|
||||
|
||||
module.exports = BitcoreNode;
|
||||
|
||||
26
lib/errors.js
Normal file
26
lib/errors.js
Normal file
@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
var spec = {
|
||||
name: 'BitcoreNode',
|
||||
message: 'Internal Error on BitcoreNode',
|
||||
errors: [{
|
||||
name: 'Transactions',
|
||||
message: 'Internal Transactions error on BitcoreNode',
|
||||
errors: [{
|
||||
name: 'NotFound',
|
||||
message: 'Transaction {0} not found'
|
||||
}, {
|
||||
name: 'CantBroadcast',
|
||||
message: 'Unable to broadcast transaction {0}'
|
||||
}]
|
||||
}, {
|
||||
name: 'Blocks',
|
||||
message: 'Internal Blocks error on BitcoreNode',
|
||||
errors: [{
|
||||
name: 'NotFound',
|
||||
message: 'Block {0} not found'
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
module.exports = require('bitcore').errors.extend(spec);
|
||||
Loading…
Reference in New Issue
Block a user