openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
866 lines (781 loc) • 33.5 kB
text/coffeescript
should = require "should"
request = require "supertest"
Transaction = require("../../lib/model/transactions").Transaction
Channel = require("../../lib/model/channels").Channel
User = require('../../lib/model/users').User
server = require "../../lib/server"
testUtils = require "../testUtils"
auth = require("../testUtils").auth
FakeServer = require "../fakeTcpServer"
config = require '../../lib/config/config'
apiConf = config.get 'api'
Event = require("../../lib/model/events").Event
AutoRetry = require('../../lib/model/autoRetry').AutoRetry
application = config.get 'application'
os = require "os"
domain = os.hostname() + '.' + application.name
describe "API Integration Tests", ->
beforeEach (done) -> Transaction.remove {}, -> done()
afterEach (done)-> Transaction.remove {}, -> done()
describe "Transactions REST Api testing", ->
transactionId = null
requ =
path: "/api/test"
headers:
"header-title": "header1-value"
"another-header": "another-header-value"
querystring: "param1=value1¶m2=value2"
body: "<HTTP body request>"
method: "POST"
timestamp: "2014-06-09T11:17:25.929Z"
respo =
status: "200"
headers:
header: "value"
header2: "value2"
body: "<HTTP response>"
timestamp: "2014-06-09T11:17:25.929Z"
transactionData =
_id: "111111111111111111111111"
status: "Processing"
clientID: "999999999999999999999999"
channelID: "888888888888888888888888"
request: requ
response: respo
routes:
[
name: "dummy-route"
request: requ
response: respo
]
orchestrations:
[
name: "dummy-orchestration"
request: requ
response: respo
]
properties:
"prop1": "prop1-value1"
"prop2": "prop-value1"
authDetails = {}
channel = new Channel
name: "TestChannel1"
urlPattern: "test/sample"
allow: [ "PoC", "Test1", "Test2" ]
routes: [
name: "test route"
host: "localhost"
port: 9876
primary: true
]
txViewAcl: [ "group1" ]
txViewFullAcl: []
channel2 = new Channel
name: "TestChannel2"
urlPattern: "test2/sample"
allow: [ "PoC", "Test1", "Test2" ]
routes: [
name: "test route"
host: "localhost"
port: 9876
primary: true
]
txViewAcl: [ "not-for-non-root" ]
txViewFullAcl: []
autoRetryEnabled: true
autoRetryPeriodMinutes: 60
autoRetryMaxAttempts: 5
before (done) ->
auth.setupTestUsers (err) ->
channel.save (err) ->
channel2.save (err) ->
server.start apiPort: 8080, ->
done()
after (done) ->
auth.cleanupTestUsers (err) ->
Channel.remove (err) ->
server.stop ->
done()
beforeEach (done) ->
authDetails = auth.getAuthDetails()
Event.ensureIndexes done
afterEach (done) ->
Event.remove {}, done
describe "*addTransaction()", ->
it "should add a transaction and return status 201 - transaction created", (done) ->
transactionData.channelID = channel._id
request("https://localhost:8080")
.post("/transactions")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(transactionData)
.expect(201)
.end (err, res) ->
if err
done err
else
Transaction.findOne { clientID: "999999999999999999999999" }, (error, newTransaction) ->
should.not.exist (error)
(newTransaction != null).should.be.true
newTransaction.status.should.equal "Processing"
newTransaction.clientID.toString().should.equal "999999999999999999999999"
newTransaction.channelID.toString().should.equal channel._id.toString()
newTransaction.request.path.should.equal "/api/test"
newTransaction.request.headers['header-title'].should.equal "header1-value"
newTransaction.request.headers['another-header'].should.equal "another-header-value"
newTransaction.request.querystring.should.equal "param1=value1¶m2=value2"
newTransaction.request.body.should.equal "<HTTP body request>"
newTransaction.request.method.should.equal "POST"
done()
it "should only allow admin users to add transactions", (done) ->
request("https://localhost:8080")
.post("/transactions")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(transactionData)
.expect(403)
.end (err, res) ->
if err
done err
else
done()
it "should generate events after adding a transaction", (done) ->
transactionData.channelID = channel._id
request("https://localhost:8080")
.post("/transactions")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(transactionData)
.expect(201)
.end (err, res) ->
return done err if err
validateEvents = ->
Event.find {}, (err, events) ->
return done err if err
# expect 8: start+end for primary route, secondary route and orchestration
events.length.should.be.exactly 6
for ev in events
ev.channelID.toString().should.be.exactly channel._id.toString()
evs = (events.map (event) -> "#{event.type}-#{event.name}-#{event.event}")
evs.should.containEql "primary-test route-start"
evs.should.containEql "primary-test route-end"
evs.should.containEql "route-dummy-route-start"
evs.should.containEql "route-dummy-route-end"
evs.should.containEql "orchestration-dummy-orchestration-start"
evs.should.containEql "orchestration-dummy-orchestration-end"
done()
setTimeout validateEvents, 100 * global.testTimeoutFactor
describe "*updateTransaction()", ->
s = {}
beforeEach (done) ->
s = new FakeServer()
s.start done
afterEach ->
s.stop()
it "should call /updateTransaction ", (done) ->
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
transactionId = result._id
reqUp = new Object()
reqUp.path = "/api/test/updated"
reqUp.headers =
"Content-Type": "text/javascript"
"Access-Control": "authentication-required"
reqUp.querystring = 'updated=value'
reqUp.body = "<HTTP body update>"
reqUp.method = "PUT"
updates =
request: reqUp
status: "Completed"
clientID: "777777777777777777777777"
$push: {
routes : {
"name": "async",
"orchestrations": [
{
"name": "test",
"request": {
"method": "POST",
"body": "data",
"timestamp": 1425897647329
},
"response": {
"status": 201,
"body": "OK",
"timestamp": 1425897688016
}
}
]
}
}
request("https://localhost:8080")
.put("/transactions/#{transactionId}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(updates)
.expect(200)
.end (err, res) ->
if err
done err
else
Transaction.findOne { "_id": transactionId }, (error, updatedTrans) ->
should.not.exist(error)
(updatedTrans != null).should.be.true
updatedTrans.status.should.equal "Completed"
updatedTrans.clientID.toString().should.equal "777777777777777777777777"
updatedTrans.request.path.should.equal "/api/test/updated"
updatedTrans.request.headers['Content-Type'].should.equal "text/javascript"
updatedTrans.request.headers['Access-Control'].should.equal "authentication-required"
updatedTrans.request.querystring.should.equal "updated=value"
updatedTrans.request.body.should.equal "<HTTP body update>"
updatedTrans.request.method.should.equal "PUT"
updatedTrans.routes[1].name.should.equal "async"
updatedTrans.routes[1].orchestrations[0].name.should.equal "test"
s.expectMessage domain + '.channels.888888888888888888888888.async.orchestrations.test:1|c', ->
s.expectMessage domain + '.channels.888888888888888888888888.async.orchestrations.test.statusCodes.201:1|c', done
done()
it "should only allow admin user to update a transaction", (done) ->
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
transactionId = result._id
updates = {}
request("https://localhost:8080")
.put("/transactions/#{transactionId}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(updates)
.expect(403)
.end (err, res) ->
if err
done err
else
done()
it "should generate events on update", (done) ->
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
transactionId = result._id
reqUp = new Object()
reqUp.path = "/api/test/updated"
reqUp.headers =
"Content-Type": "text/javascript"
"Access-Control": "authentication-required"
reqUp.querystring = 'updated=value'
reqUp.body = "<HTTP body update>"
reqUp.method = "PUT"
updates =
status: "Failed"
"orchestrations": [
{
"name": "test",
"request": {
"method": "POST",
"body": "data",
"timestamp": 1425897647329
},
"response": {
"status": 500,
"body": "OK",
"timestamp": 1425897688016
}
}
]
request("https://localhost:8080")
.put("/transactions/#{transactionId}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(updates)
.expect(200)
.end (err, res) ->
return done err if err
validateEvents = ->
Event.find {}, (err, events) ->
return done err if err
# events should only be generated for the updated fields
events.length.should.be.exactly 2
for ev in events
ev.channelID.toString().should.be.exactly channel._id.toString()
evs = (events.map (event) -> "#{event.type}-#{event.name}-#{event.event}")
evs.should.containEql "orchestration-test-start"
evs.should.containEql "orchestration-test-end"
done()
setTimeout validateEvents, 100 * global.testTimeoutFactor
it 'should queue a transaction for auto retry', (done) ->
transactionData.channelID = channel2._id
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
transactionId = result._id
updates =
status: "Failed"
error:
message: "Error message"
stack: "stack\nstack\nstack"
request("https://localhost:8080")
.put("/transactions/#{transactionId}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(updates)
.expect(200)
.end (err, res) ->
return done err if err
Transaction.findById transactionId, (err, tx) ->
tx.autoRetry.should.be.true()
AutoRetry.findOne transactionID: transactionId, (err, queueItem) ->
queueItem.should.be.ok()
queueItem.channelID.toString().should.be.exactly channel2._id.toString()
done()
it 'should not queue a transaction for auto retry when max retries have been reached', (done) ->
transactionData.autoRetryAttempt = 5
transactionData.channelID = channel2._id
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
transactionId = result._id
updates =
status: "Failed"
error:
message: "Error message"
stack: "stack\nstack\nstack"
request("https://localhost:8080")
.put("/transactions/#{transactionId}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(updates)
.expect(200)
.end (err, res) ->
return done err if err
Transaction.findById transactionId, (err, tx) ->
tx.autoRetry.should.be.false()
done()
describe "*getTransactions()", ->
it "should call getTransactions ", (done) ->
Transaction.count {}, (err, countBefore) ->
tx = new Transaction transactionData
tx.save (error, result) ->
should.not.exist (error)
request("https://localhost:8080")
.get("/transactions?filterPage=0&filterLimit=10&filters={}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body.length.should.equal countBefore + 1
done()
it "should call getTransactions with filter parameters ", (done) ->
obj =
filterPage: 0
filterLimit: 10
filters:
'status': 'Processing'
'request.timestamp': '{"$gte": "2014-06-09T00:00:00.000Z", "$lte": "2014-06-10T00:00:00.000Z" }'
'request.path': '/api/test'
'response.status': '2xx'
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
Transaction.count {}, (err, countBefore) ->
tx = new Transaction transactionData
tx.save (error, result) ->
should.not.exist (error)
request("https://localhost:8080")
.get("/transactions?"+params)
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body.length.should.equal countBefore + 1
done()
it "should call getTransactions with filter parameters (Different filters)", (done) ->
obj =
filterPage: 0
filterLimit: 10
filters:
'status': 'Processing'
'routes.request.path': '/api/test'
'routes.response.status': '2xx'
'orchestrations.request.path': '/api/test'
'orchestrations.response.status': '2xx'
'properties':
'prop1': 'prop1-value1'
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
Transaction.count {}, (err, countBefore) ->
tx = new Transaction transactionData
tx.save (error, result) ->
should.not.exist (error)
request("https://localhost:8080")
.get("/transactions?"+params)
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body.length.should.equal countBefore + 1
done()
it "should call getTransactions with filter parameters (Different filters - return no results)", (done) ->
obj =
filterPage: 0
filterLimit: 10
filters:
'status': 'Processing'
'routes.request.path': '/api/test'
'routes.response.status': '2xx'
'orchestrations.request.path': '/api/test'
'orchestrations.response.status': '2xx'
'properties':
'prop3': 'prop3-value3'
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
Transaction.count {}, (err, countBefore) ->
tx = new Transaction transactionData
tx.save (error, result) ->
should.not.exist (error)
request("https://localhost:8080")
.get("/transactions?"+params)
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
# prop3 does not exist so no records should be returned
res.body.length.should.equal 0
done()
it "should only return the transactions that a user can view", (done) ->
tx = new Transaction transactionData
tx.channelID = channel._id
tx.save (err) ->
return done err if err
tx2 = new Transaction transactionData
tx2._id = "111111111111111111111112"
tx2.channelID = channel2._id
tx2.save (err) ->
return done err if err
request("https://localhost:8080")
.get("/transactions")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
# should NOT retrieve tx2
res.body.should.have.length(1)
res.body[0]._id.should.be.equal "111111111111111111111111"
done()
it "should return the transactions for a channel that a user has permission to view", (done) ->
tx = new Transaction transactionData
tx.channelID = channel._id
tx.save (err) ->
return done err if err
tx2 = new Transaction transactionData
tx2._id = "111111111111111111111112"
tx2.channelID = channel2._id
tx2.save (err) ->
return done err if err
request("https://localhost:8080")
.get("/transactions?channelID=#{channel._id}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
# should NOT retrieve tx2
res.body.should.have.length(1)
res.body[0]._id.should.be.equal "111111111111111111111111"
done()
it "should return 403 for a channel that a user does NOT have permission to view", (done) ->
tx = new Transaction transactionData
tx.channelID = channel._id
tx.save (err) ->
return done err if err
tx2 = new Transaction transactionData
tx2._id = "111111111111111111111112"
tx2.channelID = channel2._id
tx2.save (err) ->
return done err if err
request("https://localhost:8080")
.get("/transactions?channelID=#{tx2.channelID}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(403)
.end (err, res) -> done()
it "should truncate transaction details if filterRepresentation is fulltruncate ", (done) ->
Transaction.count {}, (err, countBefore) ->
tx = new Transaction transactionData
tx.save (error, result) ->
should.not.exist (error)
request("https://localhost:8080")
.get("/transactions?filterRepresentation=fulltruncate")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body.length.should.equal countBefore + 1
res.body[countBefore].request.body.should.equal "<HTTP body#{apiConf.truncateAppend}"
res.body[countBefore].response.body.should.equal "<HTTP resp#{apiConf.truncateAppend}"
res.body[countBefore].routes[0].request.body.should.equal "<HTTP body#{apiConf.truncateAppend}"
res.body[countBefore].routes[0].response.body.should.equal "<HTTP resp#{apiConf.truncateAppend}"
res.body[countBefore].orchestrations[0].request.body.should.equal "<HTTP body#{apiConf.truncateAppend}"
res.body[countBefore].orchestrations[0].response.body.should.equal "<HTTP resp#{apiConf.truncateAppend}"
done()
describe "*getTransactionById (transactionId)", ->
it "should fetch a transaction by ID - admin user", (done) ->
tx = new Transaction transactionData
tx.save (err, result)->
should.not.exist(err)
transactionId = result._id
request("https://localhost:8080")
.get("/transactions/#{transactionId}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
(res != null).should.be.true
res.body.status.should.equal "Processing"
res.body.clientID.toString().should.eql "999999999999999999999999"
res.body.request.path.should.equal "/api/test"
res.body.request.headers['header-title'].should.equal "header1-value"
res.body.request.headers['another-header'].should.equal "another-header-value"
res.body.request.querystring.should.equal "param1=value1¶m2=value2"
res.body.request.body.should.equal "<HTTP body request>"
res.body.request.method.should.equal "POST"
done()
it "should NOT return a transaction that a user is not allowed to view", (done) ->
tx = new Transaction transactionData
tx.channelID = channel2._id
tx.save (err, result)->
should.not.exist(err)
transactionId = result._id
request("https://localhost:8080")
.get("/transactions/#{transactionId}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(403)
.end (err, res) ->
if err
done err
else
done()
it "should return a transaction that a user is allowed to view", (done) ->
tx = new Transaction transactionData
tx.channelID = channel._id
tx.save (err, tx) ->
if err
return done err
should.not.exist(err)
transactionId = tx._id
request("https://localhost:8080")
.get("/transactions/#{transactionId}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
(res != null).should.be.true
res.body.status.should.equal "Processing"
res.body.clientID.toString().should.eql "999999999999999999999999"
res.body.request.path.should.equal "/api/test"
res.body.request.headers['header-title'].should.equal "header1-value"
res.body.request.headers['another-header'].should.equal "another-header-value"
res.body.request.querystring.should.equal "param1=value1¶m2=value2"
should.not.exist(res.body.request.body)
res.body.request.method.should.equal "POST"
done()
it "should truncate a large body if filterRepresentation is 'fulltruncate'", (done) ->
# transactionData body lengths > config.truncateSize
tx = new Transaction transactionData
tx.save (err, result)->
should.not.exist(err)
transactionId = result._id
request("https://localhost:8080")
.get("/transactions/#{transactionId}?filterRepresentation=fulltruncate")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body.request.body.should.equal "<HTTP body#{apiConf.truncateAppend}"
res.body.response.body.should.equal "<HTTP resp#{apiConf.truncateAppend}"
res.body.routes[0].request.body.should.equal "<HTTP body#{apiConf.truncateAppend}"
res.body.routes[0].response.body.should.equal "<HTTP resp#{apiConf.truncateAppend}"
res.body.orchestrations[0].request.body.should.equal "<HTTP body#{apiConf.truncateAppend}"
res.body.orchestrations[0].response.body.should.equal "<HTTP resp#{apiConf.truncateAppend}"
done()
describe "*findTransactionByClientId (clientId)", ->
it "should call findTransactionByClientId", (done) ->
clientId = "555555555555555555555555"
transactionData.clientID = clientId
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
request("https://localhost:8080")
.get("/transactions/clients/#{clientId}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body[0].clientID.should.equal clientId
done()
it "should NOT return transactions that a user is not allowed to view", (done) ->
clientId = "444444444444444444444444"
transactionData.clientID = clientId
transactionData.channelID = "888888888888888888888888"
tx = new Transaction transactionData
tx.save (err, result)->
should.not.exist(err)
transactionId = result._id
request("https://localhost:8080")
.get("/transactions/clients/#{clientId}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body.should.have.length(0);
done()
it "should return transactions that a user is allowed to view", (done) ->
clientId = "333333333333333333333333"
transactionData.clientID = clientId
tx = new Transaction transactionData
tx.channelID = channel._id
tx.save (err, tx) ->
if err
return done err
should.not.exist(err)
transactionId = tx._id
request("https://localhost:8080")
.get("/transactions/clients/#{clientId}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
res.body[0].clientID.should.equal clientId
done()
describe "*removeTransaction (transactionId)", ->
it "should call removeTransaction", (done) ->
transactionData.clientID = "222222222222222222222222"
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
transactionId = result._id
request("https://localhost:8080")
.del("/transactions/#{transactionId}")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(200)
.end (err, res) ->
if err
done err
else
Transaction.findOne { "_id": transactionId }, (err, transDoc) ->
should.not.exist(err)
(transDoc == null).should.be.true
done()
it "should only allow admin users to remove transactions", (done) ->
transactionData.clientID = "222222222222222222222222"
tx = new Transaction transactionData
tx.save (err, result) ->
should.not.exist(err)
transactionId = result._id
request("https://localhost:8080")
.del("/transactions/#{transactionId}")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.expect(403)
.end (err, res) ->
if err
done err
else
done()