openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
663 lines (578 loc) • 24.2 kB
text/coffeescript
should = require "should"
request = require "supertest"
server = require "../../lib/server"
Task = require("../../lib/model/tasks").Task
Transaction = require("../../lib/model/transactions").Transaction
AutoRetry = require("../../lib/model/autoRetry").AutoRetry
Channel = require("../../lib/model/channels").Channel
testUtils = require "../testUtils"
auth = require("../testUtils").auth
config = require("../../lib/config/config")
MongoClient = require("mongodb").MongoClient
ObjectId = require('mongoose').Types.ObjectId
describe "API Integration Tests", ->
describe 'Tasks REST Api testing', ->
task1 = new Task
_id: "aaa908908bbb98cc1d0809ee"
status: "Completed"
remainingTransactions: 0
totalTransactions: 4
transactions: [ {tid: "11111", tstatus: "Completed"},
{tid: "22222", tstatus: "Completed"},
{tid: "33333", tstatus: "Failed"},
{tid: "44444", tstatus: "Completed"} ]
created: "2014-06-18T12:00:00.929Z"
completed: "12014-06-18T12:01:00.929Z"
user: "root@openhim.org"
task2 = new Task
_id: "aaa777777bbb66cc5d4444ee"
status: "Queued"
remainingTransactions: 3
totalTransactions: 3
transactions: [ {tid: "55555", tstatus: "Queued"},
{tid: "66666", tstatus: "Queued"},
{tid: "77777", tstatus: "Queued"} ]
created: "2014-06-18T12:00:00.929Z"
user: "root@openhim.org"
task3 = new Task
_id: "bbb777777bbb66cc5d4444ee"
status: "Paused"
remainingTransactions: 11
totalTransactions: 23
transactions: [ {tid: "11111", tstatus: "Completed", rerunID: "111111111111", rerunStatus: "Successful"},
{tid: "22222", tstatus: "Completed", rerunID: "22222222222", rerunStatus: "Successful"},
{tid: "33333", tstatus: "Completed", rerunID: "33333333333", rerunStatus: "Successful"},
{tid: "fakeIDShouldFail", tstatus: "Failed", error: "Failed due to incorrect format of ID"},
{tid: "55555", tstatus: "Completed", rerunID: "55555555555", rerunStatus: "Failed"},
{tid: "66666", tstatus: "Completed", rerunID: "66666666666", rerunStatus: "Completed"},
{tid: "77777", tstatus: "Completed", rerunID: "77777777777", rerunStatus: "Successful"},
{tid: "88888", tstatus: "Completed", rerunID: "88888888888", rerunStatus: "Failed"},
{tid: "fakeIDShouldFail2", tstatus: "Failed", error: "Failed due to incorrect format of ID"},
{tid: "10101", tstatus: "Completed", rerunID: "10101010101", rerunStatus: "Failed"},
{tid: "11011", tstatus: "Completed", rerunID: "11011011011", rerunStatus: "Failed"},
{tid: "12121", tstatus: "Processing"},
{tid: "13131", tstatus: "Queued"},
{tid: "14141", tstatus: "Queued"},
{tid: "15151", tstatus: "Queued"},
{tid: "16161", tstatus: "Queued"},
{tid: "17171", tstatus: "Queued"},
{tid: "18181", tstatus: "Queued"},
{tid: "19191", tstatus: "Queued"},
{tid: "20202", tstatus: "Queued"},
{tid: "21212", tstatus: "Queued"},
{tid: "22022", tstatus: "Queued"},
{tid: "23232", tstatus: "Queued"} ]
created: "2014-06-18T12:00:00.929Z"
user: "root@openhim.org"
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"
transaction1 = new Transaction
_id: "888888888888888888888888"
status: "Successful"
clientID: "000000000000000000000000"
channelID: "aaaa11111111111111111111"
request: requ
transaction2 = new Transaction
_id: "999999999999999999999999"
status: "Successful"
clientID: "000000000000000000000000"
channelID: "aaaa11111111111111111111"
request: requ
transaction3 = new Transaction
_id: "101010101010101010101010"
status: "Successful"
clientID: "000000000000000000000000"
channelID: "aaaa11111111111111111111"
request: requ
transaction4 = new Transaction
_id: "112233445566778899101122"
status: "Successful"
clientID: "000000000000000000000000"
channelID: "bbbb22222222222222222222"
request: requ
transaction5 = new Transaction
_id: "101010101010101010105555"
status: "Successful"
clientID: "000000000000000000000000"
channelID: "cccc33333333333333333333"
request: requ
transaction6 = new Transaction
_id: "101010101010101010106666"
status: "Successful"
clientID: "000000000000000000000000"
channelID: "dddd44444444444444444444"
request: requ
channel = new Channel
_id: "aaaa11111111111111111111"
name: "TestChannel1"
urlPattern: "test/sample"
allow: [ "PoC", "Test1", "Test2" ]
routes: [
name: "test route"
host: "localhost"
port: 9876
primary: true
]
txViewAcl: [ "group1" ]
txRerunAcl: [ "group2" ]
channel2 = new Channel
_id: "bbbb22222222222222222222"
name: "TestChannel2"
urlPattern: "test/sample2"
allow: [ "PoC", "Test1", "Test2" ]
routes: [
name: "test route"
host: "localhost"
port: 9876
primary: true
]
txViewAcl: [ "group1" ]
txRerunAcl: [ "group222222222" ]
channel3 = new Channel
_id: "cccc33333333333333333333"
name: "TestChannel3"
urlPattern: "test/sample3"
allow: [ "PoC", "Test1", "Test2" ]
routes: [
name: "test route"
host: "localhost"
port: 9876
primary: true
]
txViewAcl: [ "group1" ]
txRerunAcl: [ "group222222222" ]
status: 'disabled'
channel4 = new Channel
_id: "dddd44444444444444444444"
name: "TestChannel4"
urlPattern: "test/sample4"
allow: [ "PoC", "Test1", "Test2" ]
routes: [
name: "test route"
host: "localhost"
port: 9876
primary: true
]
txViewAcl: [ "group1" ]
txRerunAcl: [ "group222222222" ]
status: 'deleted'
authDetails = {}
before (done) ->
Task.remove {}, ->
task1.save -> task2.save -> task3.save (err) ->
transaction1.save -> transaction2.save -> transaction3.save ->
transaction4.save -> transaction5.save -> transaction6.save ->
channel.save -> channel2.save -> channel3.save -> channel4.save ->
auth.setupTestUsers ->
server.start apiPort: 8080, ->
done()
after (done) ->
server.stop ->
auth.cleanupTestUsers ->
Task.remove {}, ->
Transaction.remove {}, ->
Channel.remove {}, ->
MongoClient.connect config.mongo.url, (err, db) ->
mongoCollection = db?.collection "jobs"
mongoCollection.drop()
done()
beforeEach ->
authDetails = auth.getAuthDetails()
describe '*getTasks()', ->
it 'should fetch all tasks', (done) ->
obj =
filterPage: 0
filterLimit: 10
filters: {}
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
request("https://localhost:8080")
.get("/tasks?"+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.be.eql(3)
done()
it 'should fetch all tasks that are currently Paused', (done) ->
obj =
filterPage: 0
filterLimit: 10
filters:
status: 'Paused'
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
request("https://localhost:8080")
.get("/tasks?"+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.be.eql(1)
done()
describe '*addTask()', ->
it 'should add a new task', (done) ->
newTask =
tids: [ "888888888888888888888888", "999999999999999999999999", "101010101010101010101010" ]
request("https://localhost:8080")
.post("/tasks")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(newTask)
.expect(201)
.end (err, res) ->
if err
done err
else
Task.findOne { $and: [ transactions: { $elemMatch: { tid: "888888888888888888888888" } }, { transactions: $elemMatch: { tid: "999999999999999999999999" } }, { transactions: $elemMatch: { tid: "101010101010101010101010" } } ] }, (err, task) ->
task.should.have.property "status", "Queued"
task.transactions.should.have.length 3
task.should.have.property "remainingTransactions", 3
done()
it 'should add a new task (non Admin user)', (done) ->
newTask =
tids: [ "888888888888888888888888", "999999999999999999999999", "101010101010101010101010" ]
request("https://localhost:8080")
.post("/tasks")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(newTask)
.expect(201)
.end (err, res) ->
if err
done err
else
Task.findOne { $and: [ transactions: { $elemMatch: { tid: "888888888888888888888888" } }, { transactions: $elemMatch: { tid: "999999999999999999999999" } }, { transactions: $elemMatch: { tid: "101010101010101010101010" } } ] }, (err, task) ->
task.should.have.property "status", "Queued"
task.transactions.should.have.length 3
task.should.have.property "remainingTransactions", 3
done()
it 'should NOT add a new task (non Admin user - No permission for one transaction)', (done) ->
newTask =
tids: [ "112233445566778899101122", "888888888888888888888888", "999999999999999999999999", "101010101010101010101010" ]
request("https://localhost:8080")
.post("/tasks")
.set("auth-username", testUtils.nonRootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(newTask)
.expect(403)
.end (err, res) ->
if err
done err
else
done()
it 'should NOT add a new task if there are transactions linked to disabled channels', (done) ->
newTask =
tids: [ "888888888888888888888888", "999999999999999999999999", "101010101010101010101010", "101010101010101010105555" ]
request("https://localhost:8080")
.post("/tasks")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(newTask)
.expect(400)
.end (err, res) ->
if err
done err
else
done()
it 'should NOT add a new task if there are transactions linked to deleted channels (flagged)', (done) ->
newTask =
tids: [ "888888888888888888888888", "999999999999999999999999", "101010101010101010101010", "101010101010101010106666" ]
request("https://localhost:8080")
.post("/tasks")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(newTask)
.expect(400)
.end (err, res) ->
if err
done err
else
done()
it 'should add a new task with status Paused if the request contains paused=true', (done) ->
newTask =
tids: [ "222288888888888888888888", "333399999999999999999999", "444410101010101010101010" ]
paused: true
request("https://localhost:8080")
.post("/tasks")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(newTask)
.expect(201)
.end (err, res) ->
if err
done err
else
Task.findOne { $and: [ transactions: { $elemMatch: { tid: "222288888888888888888888" } }, { transactions: $elemMatch: { tid: "333399999999999999999999" } }, { transactions: $elemMatch: { tid: "444410101010101010101010" } } ] }, (err, task) ->
task.should.have.property "status", "Paused"
task.transactions.should.have.length 3
task.should.have.property "remainingTransactions", 3
done()
it 'should clear the transactions in a new task out of the auto retry queue', (done) ->
newTask =
tids: [ "888888888888888888888888", "999999999999999999999999" ]
AutoRetry.remove {}, (err) ->
return done err if err
retry1 = new AutoRetry
transactionID: ObjectId '888888888888888888888888'
channelID: ObjectId '222222222222222222222222'
requestTimestamp: new Date()
retry2 = new AutoRetry
transactionID: ObjectId '999999999999999999999999'
channelID: ObjectId '222222222222222222222222'
requestTimestamp: new Date()
retry3 = new AutoRetry
transactionID: ObjectId '111119999999999999999999'
channelID: ObjectId '222222222222222222222222'
requestTimestamp: new Date()
retry1.save -> retry2.save -> retry3.save ->
request("https://localhost:8080")
.post("/tasks")
.set("auth-username", testUtils.rootUser.email)
.set("auth-ts", authDetails.authTS)
.set("auth-salt", authDetails.authSalt)
.set("auth-token", authDetails.authToken)
.send(newTask)
.expect(201)
.end (err, res) ->
if err
done err
else
setTimeout ( ->
AutoRetry.find {}, (err, results) ->
results.length.should.be.exactly 1
# retry3 not in task
results[0].transactionID.toString().should.be.equal retry3.transactionID.toString()
done()
), 100 * global.testTimeoutFactor
describe '*getTask(taskId)', ->
it 'should fetch a specific task by ID', (done) ->
obj =
filterPage: 0
filterLimit: 10
filters: {}
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
request("https://localhost:8080")
.get("/tasks/aaa908908bbb98cc1d0809ee?"+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.should.have.property "_id", "aaa908908bbb98cc1d0809ee"
res.body.should.have.property "status", "Completed"
res.body.transactions.should.have.length 4
done()
it 'should fetch a specific task by ID with limit of first 10 records', (done) ->
obj =
filterPage: 0
filterLimit: 10
filters: {}
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
request("https://localhost:8080")
.get("/tasks/bbb777777bbb66cc5d4444ee?"+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.should.have.property "_id", "bbb777777bbb66cc5d4444ee"
res.body.should.have.property "status", "Paused"
res.body.transactions.should.have.length 10
res.body.transactions[0].should.have.property "rerunStatus", "Successful"
res.body.transactions[2].should.have.property "rerunStatus", "Successful"
res.body.transactions[3].should.have.property "error", "Failed due to incorrect format of ID"
res.body.transactions[7].should.have.property "rerunStatus", "Failed"
res.body.transactions[8].should.have.property "error", "Failed due to incorrect format of ID"
res.body.transactions[9].should.have.property "rerunStatus", "Failed"
done()
it 'should fetch a specific task by ID with filters ( tstatus: "Completed" )', (done) ->
obj =
filterPage: 0
filterLimit: 10
filters:
tstatus: 'Completed'
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
request("https://localhost:8080")
.get("/tasks/bbb777777bbb66cc5d4444ee?"+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.should.have.property "_id", "bbb777777bbb66cc5d4444ee"
res.body.should.have.property "status", "Paused"
res.body.transactions.should.have.length 9
res.body.transactions[0].should.have.property "rerunStatus", "Successful"
res.body.transactions[1].should.have.property "rerunStatus", "Successful"
res.body.transactions[2].should.have.property "rerunStatus", "Successful"
res.body.transactions[3].should.have.property "rerunStatus", "Failed"
res.body.transactions[4].should.have.property "rerunStatus", "Completed"
res.body.transactions[5].should.have.property "rerunStatus", "Successful"
res.body.transactions[6].should.have.property "rerunStatus", "Failed"
res.body.transactions[7].should.have.property "rerunStatus", "Failed"
res.body.transactions[8].should.have.property "rerunStatus", "Failed"
done()
it 'should fetch a specific task by ID with filters ( tstatus: "Completed", rerunStatus: "Successful" )', (done) ->
obj =
filterPage: 0
filterLimit: 10
filters:
tstatus: 'Completed'
rerunStatus: 'Successful'
params = ""
for k, v of obj
v = JSON.stringify v
if params.length > 0
params += "&"
params += "#{k}=#{v}"
params = encodeURI params
request("https://localhost:8080")
.get("/tasks/bbb777777bbb66cc5d4444ee?"+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.should.have.property "_id", "bbb777777bbb66cc5d4444ee"
res.body.should.have.property "status", "Paused"
res.body.transactions.should.have.length 4
done()
describe '*updateTask(taskId)', ->
it 'should update a specific task by ID', (done) ->
updates =
status: "Completed"
completed: "2014-06-18T13:30:00.929Z"
request("https://localhost:8080")
.put("/tasks/aaa777777bbb66cc5d4444ee")
.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
Task.findOne { _id: "aaa777777bbb66cc5d4444ee" }, (err, task) ->
task.should.have.property "status", "Completed"
task.transactions.should.have.length 3
done()
it 'should not allow a non admin user to update a task', (done) ->
updates = {}
request("https://localhost:8080")
.put("/tasks/890aaS0b93ccccc30dddddd0")
.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()
describe '*removeTask(taskId)', ->
it 'should remove a specific task by ID', (done) ->
request("https://localhost:8080")
.del("/tasks/aaa777777bbb66cc5d4444ee")
.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
Task.find { _id: "aaa777777bbb66cc5d4444ee" }, (err, task) ->
task.should.have.length 0
done()
it 'should not only allow a non admin user to remove a task', (done) ->
request("https://localhost:8080")
.del("/tasks/890aaS0b93ccccc30dddddd0")
.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()