@trivechain/trivechaind-rpc
Version:
Trivechain Client Library to connect to Trivechain Core (trivechaind) via RPC
566 lines (512 loc) • 14.3 kB
JavaScript
var chai = require('chai')
var RpcClient = require('../')
var util = require('util')
var EventEmitter = require('events').EventEmitter
var sinon = require('sinon')
var should = chai.should()
var http = require('http')
var https = require('https')
var async = require('async')
// eslint-disable-next-line
if(!setImmediate) setImmediate = setTimeout;
describe('RpcClient', function () {
it('should initialize the main object', function () {
should.exist(RpcClient)
})
it('should be able to create instance', function () {
var s = new RpcClient()
should.exist(s)
})
it('default to rejectUnauthorized as true', function () {
var s = new RpcClient()
should.exist(s)
s.rejectUnauthorized.should.equal(true)
})
it('should be able to define a custom logger', function () {
var customLogger = {
info: function () {},
warn: function () {},
err: function () {},
debug: function () {},
}
RpcClient.config.log = customLogger
var s = new RpcClient()
s.log.should.equal(customLogger)
RpcClient.config.log = false
})
it('should be able to define the logger to normal', function () {
RpcClient.config.logger = 'normal'
var s = new RpcClient()
s.log.should.equal(RpcClient.loggers.normal)
})
it('should be able to define the logger to none', function () {
RpcClient.config.logger = 'none'
var s = new RpcClient()
s.log.should.equal(RpcClient.loggers.none)
})
function FakeResponse() {
EventEmitter.call(this)
}
util.inherits(FakeResponse, EventEmitter)
function FakeRequest() {
EventEmitter.call(this)
return this
}
util.inherits(FakeRequest, EventEmitter)
FakeRequest.prototype.setHeader = function () {}
FakeRequest.prototype.write = function (data) {
this.data = data
}
FakeRequest.prototype.end = function () {}
it('should use https', function () {
var client = new RpcClient({
user: 'user',
pass: 'pass',
port: 8332,
})
client.protocol.should.equal(https)
})
it('should use http', function () {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
protocol: 'http',
})
client.protocol.should.equal(http)
})
it('should call a method and receive response', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
var req = new FakeRequest()
setImmediate(function () {
res.emit('data', '{}')
res.emit('end')
})
callback(res)
return req
})
client.setTxFee(0.01, function (error, parsedBuf) {
requestStub.restore()
should.not.exist(error)
should.exist(parsedBuf)
done()
})
})
it('accept many values for bool', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: false,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
var req = new FakeRequest()
setImmediate(function () {
res.emit('data', req.data)
res.emit('end')
})
callback(res)
return req
})
async.eachSeries(
[true, 'true', 1, '1', 'True'],
function (i, next) {
client.importAddress(
'n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X',
'',
i,
function (error, parsedBuf) {
should.not.exist(error)
should.exist(parsedBuf)
parsedBuf.params[2].should.equal(true)
next()
}
)
},
function (err) {
requestStub.restore()
done()
console.log(err)
}
)
})
it('should process object arguments', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: false,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
var req = new FakeRequest()
setImmediate(function () {
res.emit('data', req.data)
res.emit('end')
})
callback(res)
return req
})
var obj = { n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X: 1 }
async.eachSeries(
[obj, JSON.stringify(obj)],
function (i, next) {
client.sendMany('account', i, function (error, parsedBuf) {
should.not.exist(error)
should.exist(parsedBuf)
parsedBuf.params[1].should.have.property(
'n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X',
1
)
next()
})
},
function (err) {
requestStub.restore()
done()
console.log(err)
}
)
})
it('should batch calls for a method and receive a response', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: false,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
setImmediate(function () {
res.emit('data', '[{}, {}, {}]')
res.emit('end')
})
callback(res)
return new FakeRequest()
})
client.batchedCalls = []
client.listReceivedByAccount(1, true)
client.listReceivedByAccount(2, true)
client.listReceivedByAccount(3, true)
client.batchedCalls.length.should.equal(3)
client.batch(
function () {
// batch started
},
function (error, result) {
// batch ended
requestStub.restore()
should.not.exist(error)
should.exist(result)
result.length.should.equal(3)
done()
}
)
})
it('should handle connection rejected 401 unauthorized', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
res.statusCode = 401
setImmediate(function () {
res.emit('end')
})
callback(res)
return new FakeRequest()
})
client.getBalance('n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X', 6, function (
error,
parsedBuf
) {
requestStub.restore()
should.exist(error)
error.message.should.equal(
'Trivechain JSON-RPC: Connection Rejected: 401 Unnauthorized'
)
done()
})
})
it('should handle connection rejected 401 forbidden', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
res.statusCode = 403
setImmediate(function () {
res.emit('end')
})
callback(res)
return new FakeRequest()
})
client.getDifficulty(function (error, parsedBuf) {
requestStub.restore()
should.exist(error)
error.message.should.equal(
'Trivechain JSON-RPC: Connection Rejected: 403 Forbidden'
)
done()
})
})
it('should handle 500 work limit exceeded error', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
res.statusCode = 500
setImmediate(function () {
res.emit('data', 'Work queue depth exceeded')
res.emit('end')
})
callback(res)
return new FakeRequest()
})
client.getDifficulty(function (error, parsedBuf) {
requestStub.restore()
should.exist(error)
error.message.should.equal(
'Trivechain JSON-RPC: Work queue depth exceeded'
)
done()
})
})
it('should handle EPIPE error case 1', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var req = new FakeRequest()
setImmediate(function () {
req.emit('error', new Error('write EPIPE'))
})
var res = new FakeResponse()
setImmediate(function () {
res.emit('data', '{}')
res.emit('end')
})
callback(res)
return req
})
client.getDifficulty(function (error, parsedBuf) {
requestStub.restore()
should.exist(error)
error.message.should.equal(
'Trivechain JSON-RPC: Request Error: write EPIPE'
)
done()
})
})
it('should handle EPIPE error case 2', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
setImmediate(function () {
res.emit('data', '{}')
res.emit('end')
})
var req = new FakeRequest()
setImmediate(function () {
req.emit('error', new Error('write EPIPE'))
})
callback(res)
req.on('error', function (err) {
requestStub.restore()
done()
console.log(err)
})
return req
})
client.getDifficulty(function (error, parsedBuf) {
console.log(error)
})
})
it('should handle ECONNREFUSED error', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
var req = new FakeRequest()
setImmediate(function () {
req.emit('error', new Error('connect ECONNREFUSED'))
})
callback(res)
return req
})
client.getDifficulty(function (error, parsedBuf) {
requestStub.restore()
should.exist(error)
error.message.should.equal(
'Trivechain JSON-RPC: Request Error: connect ECONNREFUSED'
)
done()
})
})
it('should callback with error if invalid json', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
setImmediate(function () {
res.emit('data', 'not a json string')
res.emit('end')
})
var req = new FakeRequest()
callback(res)
return req
})
client.getDifficulty(function (error, parsedBuf) {
requestStub.restore()
should.exist(error)
error.message.should.equal(
'Trivechain JSON-RPC: Error Parsing JSON: Unexpected token o in JSON at position 1'
)
done()
})
})
it('should callback with error if blank response', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
var res = new FakeResponse()
setImmediate(function () {
res.emit('data', '')
res.emit('end')
})
var req = new FakeRequest()
callback(res)
return req
})
client.getDifficulty(function (error, parsedBuf) {
requestStub.restore()
should.exist(error)
error.message.should.equal(
'Trivechain JSON-RPC: Error Parsing JSON: Unexpected end of JSON input'
)
done()
})
})
it('should add additional http options', function (done) {
var client = new RpcClient({
user: 'user',
pass: 'pass',
host: 'localhost',
port: 8332,
rejectUnauthorized: true,
disableAgent: true,
})
client.httpOptions = {
port: 20001,
}
var calledPort = false
var requestStub = sinon
.stub(client.protocol, 'request')
.callsFake(function (options, callback) {
calledPort = options.port
var res = new FakeResponse()
setImmediate(function () {
res.emit('data', '{}')
res.emit('end')
})
var req = new FakeRequest()
callback(res)
return req
})
client.getDifficulty(function (error, parsedBuf) {
should.not.exist(error)
should.exist(parsedBuf)
calledPort.should.equal(20001)
requestStub.restore()
done()
})
})
})