Added 100% unit tests for Fulcrum endpoints

This commit is contained in:
Chris Troutner
2021-07-14 15:23:26 -07:00
parent 322a10cd74
commit e68200ed9c
4 changed files with 306 additions and 3 deletions
+3 -3
View File
@@ -17,13 +17,13 @@ class FulcrumRPC {
this.adapters = localConfig.adapters
if (!this.adapters) {
throw new Error(
'Instance of Adapters library required when instantiating User JSON RPC Controller.'
'Instance of Adapters library required when instantiating Fulcrum JSON RPC Controller.'
)
}
this.useCases = localConfig.useCases
if (!this.useCases) {
throw new Error(
'Instance of Use Cases library required when instantiating User JSON RPC Controller.'
'Instance of Use Cases library required when instantiating Fulcrum JSON RPC Controller.'
)
}
@@ -41,7 +41,7 @@ class FulcrumRPC {
async fulcrumRouter (rpcData) {
let endpoint = 'unknown'
try {
console.log('fulcrumRouter rpcData: ', rpcData)
// console.log('fulcrumRouter rpcData: ', rpcData)
endpoint = rpcData.payload.params.endpoint
let user
@@ -0,0 +1,248 @@
/*
Unit tests for the json-rpc/auth/index.js file.
*/
// Public npm libraries
const jsonrpc = require('jsonrpc-lite')
const sinon = require('sinon')
const assert = require('chai').assert
const { v4: uid } = require('uuid')
// Set the environment variable to signal this is a test.
process.env.SVC_ENV = 'test'
// Local libraries
const FulcrumRPC = require('../../../../src/controllers/json-rpc/fulcrum')
const RateLimit = require('../../../../src/controllers/json-rpc/rate-limit')
const adapters = require('../../mocks/adapters')
const UseCasesMock = require('../../mocks/use-cases')
describe('#FulcrumRPC', () => {
let uut
let sandbox
beforeEach(() => {
sandbox = sinon.createSandbox()
const useCases = new UseCasesMock()
uut = new FulcrumRPC({ adapters, useCases })
uut.rateLimit = new RateLimit({ max: 100 })
})
afterEach(() => sandbox.restore())
describe('#constructor', () => {
it('should throw an error if adapters are not passed in', () => {
try {
uut = new FulcrumRPC()
assert.fail('Unexpected code path')
} catch (err) {
assert.include(
err.message,
'Instance of Adapters library required when instantiating Fulcrum JSON RPC Controller.'
)
}
})
it('should throw an error if useCases are not passed in', () => {
try {
uut = new FulcrumRPC({ adapters })
assert.fail('Unexpected code path')
} catch (err) {
assert.include(
err.message,
'Instance of Use Cases library required when instantiating Fulcrum JSON RPC Controller.'
)
}
})
})
describe('#fulcrumRouter', () => {
it('should route to the transactions method', async () => {
// Mock dependencies
sandbox.stub(uut, 'transactions').resolves(true)
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'fulcrum', {
endpoint: 'transactions'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
rpcData.from = 'Origin request'
const result = await uut.fulcrumRouter(rpcData)
assert.equal(result, true)
})
it('should return 500 status on routing issue', async () => {
// Mock dependencies
sandbox.stub(uut, 'transactions').rejects(new Error('test error'))
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'fulcrum', {
endpoint: 'transactions'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
rpcData.from = 'Origin request'
const result = await uut.fulcrumRouter(rpcData)
assert.equal(result.success, false)
assert.equal(result.status, 500)
assert.equal(result.message, 'test error')
assert.equal(result.endpoint, 'transactions')
})
})
describe('#transactions', () => {
it('should return data from bchjs', async () => {
// Mock dependencies
sandbox
.stub(uut.bchjs.Electrumx, 'transactions')
.resolves({ success: true })
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'fulcrum', {
endpoint: 'transactions',
addresses: 'testAddr'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transactions(rpcData)
// console.log('response: ', response)
assert.equal(response.success, true)
assert.equal(response.status, 200)
})
it('should return an error for invalid address', async () => {
// Force an error
sandbox
.stub(uut.bchjs.Electrumx, 'transactions')
.rejects(new Error('Invalid address'))
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'fulcrum', {
endpoint: 'transactions',
addresses: 'testAddr'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transactions(rpcData)
console.log('response: ', response)
assert.equal(response.success, false)
assert.equal(response.status, 422)
assert.equal(response.message, 'Invalid address')
assert.equal(response.endpoint, 'transactions')
})
})
// describe('#authUser', () => {
// it('should return a JWT token if user successfully authenticates', async () => {
// // Generate the parsed data that the main router would pass to this
// // endpoint.
// const id = uid()
// const authCall = jsonrpc.request(id, 'auth', {
// endpoint: 'authUser',
// login: 'test543@test.com',
// password: 'password'
// })
// const jsonStr = JSON.stringify(authCall, null, 2)
// const rpcData = jsonrpc.parse(jsonStr)
//
// const response = await uut.authUser(rpcData)
// // console.log('response: ', response)
//
// assert.equal(response.endpoint, 'authUser')
// assert.property(response, 'userId')
// // assert.equal(response.userType, 'user')
// assert.property(response, 'userName')
// assert.property(response, 'userEmail')
// assert.property(response, 'apiToken')
// assert.equal(response.status, 200)
// assert.equal(response.success, true)
// assert.property(response, 'message')
// })
//
// it('should return an error for invalid credentials', async () => {
// // Generate the parsed data that the main router would pass to this
// // endpoint.
// const id = uid()
// const authCall = jsonrpc.request(id, 'auth', {
// endpoint: 'authUser',
// login: 'test543@test.com',
// password: 'badpassword'
// })
// const jsonStr = JSON.stringify(authCall, null, 2)
// const rpcData = jsonrpc.parse(jsonStr)
//
// // Force an error.
// sandbox
// .stub(uut.userLib, 'authUser')
// .rejects(new Error('Login credential do not match'))
//
// const response = await uut.authUser(rpcData)
// // console.log('response: ', response)
//
// assert.equal(response.success, false)
// assert.equal(response.status, 422)
// assert.equal(response.message, 'Login credential do not match')
// assert.equal(response.endpoint, 'authUser')
// })
//
// it('should throw an error if login is not provided', async () => {
// // Generate the parsed data that the main router would pass to this
// // endpoint.
// const id = uid()
// const authCall = jsonrpc.request(id, 'auth', {
// endpoint: 'authUser'
// })
// const jsonStr = JSON.stringify(authCall, null, 2)
// const rpcData = jsonrpc.parse(jsonStr)
//
// const response = await uut.authUser(rpcData)
// // console.log('response: ', response)
//
// assert.equal(response.success, false)
// assert.equal(response.status, 422)
// assert.equal(response.message, 'login must be specified')
// assert.equal(response.endpoint, 'authUser')
// })
//
// it('should throw an error if password is not provided', async () => {
// // Generate the parsed data that the main router would pass to this
// // endpoint.
// const id = uid()
// const authCall = jsonrpc.request(id, 'auth', {
// endpoint: 'authUser',
// login: 'test543@test.com'
// })
// const jsonStr = JSON.stringify(authCall, null, 2)
// const rpcData = jsonrpc.parse(jsonStr)
//
// const response = await uut.authUser(rpcData)
// // console.log('response: ', response)
//
// assert.equal(response.success, false)
// assert.equal(response.status, 422)
// assert.equal(response.message, 'password must be specified')
// assert.equal(response.endpoint, 'authUser')
// })
// })
})
@@ -179,5 +179,33 @@ describe('#JSON RPC', () => {
assert.equal(obj.result.method, 'about')
assert.equal(obj.id, id)
})
it('should route to fulcrum handler', async () => {
const id = uid()
const userCall = jsonrpc.request(id, 'fulcrum', {
endpoint: 'transactions'
})
const jsonStr = JSON.stringify(userCall, null, 2)
// Mock the controller.
sandbox.stub(uut.fulcrumController, 'fulcrumRouter').resolves('true')
// Force ipfs-coord communication.
uut.ipfsCoord.ipfs = {
orbitdb: {
sendToDb: () => {}
}
}
const result = await uut.router(jsonStr, 'peerA')
// console.log(result)
const obj = JSON.parse(result.retStr)
// console.log('obj: ', obj)
assert.equal(obj.result.value, 'true')
assert.equal(obj.result.method, 'fulcrum')
assert.equal(obj.id, id)
})
})
})
@@ -96,4 +96,31 @@ describe('#Fulcrum-REST-Router', () => {
}
})
})
describe('#handleError', () => {
it('should pass an error message', () => {
try {
const err = {
status: 422,
message: 'Unprocessable Entity'
}
uut.handleError(ctx, err)
} catch (err) {
assert.include(err.message, 'Unprocessable Entity')
}
})
it('should still throw error if there is no message', () => {
try {
const err = {
status: 404
}
uut.handleError(ctx, err)
} catch (err) {
assert.include(err.message, 'Not Found')
}
})
})
})