1 | _ = require 'lodash'
|
2 | moment = require 'moment'
|
3 | UUID = require 'uuid'
|
4 | request = require 'request'
|
5 | Server = require '../../src/server'
|
6 | Redis = require 'ioredis'
|
7 | RedisNS = require '@octoblu/redis-ns'
|
8 | { JobManagerResponder } = require 'meshblu-core-job-manager'
|
9 |
|
10 | describe 'POST /messages', ->
|
11 | beforeEach (done) ->
|
12 | @responseQueueId = UUID.v4()
|
13 | @requestQueueName = "request:queue:#{@responseQueueId}"
|
14 | @responseQueueName = "response:queue:#{@responseQueueId}"
|
15 | @namespace = 'test:meshblu-http'
|
16 | @jobLogQueue = 'test:meshblu:job-log'
|
17 | @redisUri = 'redis://localhost'
|
18 | @port = 0xd00d
|
19 | @sut = new Server {
|
20 | @port
|
21 | disableLogging: true
|
22 | jobTimeoutSeconds: 1
|
23 | @namespace
|
24 | @jobLogQueue
|
25 | jobLogRedisUri: @redisUri
|
26 | jobLogSampleRate: 1
|
27 | redisUri: @redisUri
|
28 | cacheRedisUri: @redisUri
|
29 | @requestQueueName
|
30 | @responseQueueName
|
31 | }
|
32 |
|
33 | @sut.run done
|
34 |
|
35 | afterEach ->
|
36 | @sut.stop()
|
37 |
|
38 | beforeEach (done) ->
|
39 | @redis = new RedisNS @namespace, new Redis @redisUri, dropBufferSupport: true
|
40 | @redis.on 'ready', done
|
41 |
|
42 | afterEach (done) ->
|
43 | @redis.del @requestQueueName, @responseQueueName, done
|
44 | return
|
45 |
|
46 | beforeEach (done) ->
|
47 | @workerFunc = (@request, callback=_.noop) =>
|
48 | @jobManagerDo @request, callback
|
49 |
|
50 | @jobManager = new JobManagerResponder {
|
51 | @redisUri
|
52 | @namespace
|
53 | @workerFunc
|
54 | maxConnections: 1
|
55 | queueTimeoutSeconds: 1
|
56 | jobTimeoutSeconds: 1
|
57 | jobLogSampleRate: 1
|
58 | requestQueueName: @requestQueueName
|
59 | responseQueueName: @responseQueueName
|
60 | }
|
61 | @jobManager.start done
|
62 |
|
63 | beforeEach ->
|
64 | @jobManager.do = (@jobManagerDo) =>
|
65 |
|
66 | afterEach ->
|
67 | @jobManager.stop()
|
68 |
|
69 | beforeEach (done) ->
|
70 | @jobLogClient = new Redis 'localhost', dropBufferSupport: true
|
71 | @jobLogClient.on 'ready', =>
|
72 | @jobLogClient.del @jobLogQueue, done
|
73 | return
|
74 |
|
75 | context 'when the request is successful', ->
|
76 | beforeEach ->
|
77 | @jobManager.do (@jobRequest, callback) =>
|
78 | response =
|
79 | metadata:
|
80 | code: 201
|
81 | metrics: @jobRequest.metadata.metrics
|
82 | jobLogs: @jobRequest.metadata.jobLogs
|
83 | responseId: @jobRequest.metadata.responseId
|
84 |
|
85 | callback null, response
|
86 |
|
87 | beforeEach (done) ->
|
88 | options =
|
89 | auth:
|
90 | username: 'irritable-captian'
|
91 | password: 'poop-deck'
|
92 | json:
|
93 | devices: ['*']
|
94 |
|
95 | request.post "http://localhost:#{@port}/messages", options, (error, @response) =>
|
96 | done error
|
97 |
|
98 | it 'should return a 201', ->
|
99 | expect(@response.statusCode).to.equal 201
|
100 |
|
101 | it 'should submit the correct job type', ->
|
102 | expect(@jobRequest.metadata.jobType).to.equal 'SendMessage'
|
103 |
|
104 | it 'should set the correct auth data', ->
|
105 | expect(@jobRequest.metadata.auth).to.deep.equal uuid: 'irritable-captian', token: 'poop-deck'
|
106 |
|
107 | it 'should send the correct message', ->
|
108 | message = JSON.parse @jobRequest.rawData
|
109 | expect(message).to.deep.equal devices: ['*']
|
110 |
|
111 | it 'should log the message', (done) ->
|
112 | @jobLogClient.llen @jobLogQueue, (error, count) =>
|
113 | return done error if error?
|
114 | expect(count).to.equal 1
|
115 | done()
|
116 | return
|
117 |
|
118 | it 'should log the attempt and success of the message', (done) ->
|
119 | @jobLogClient.lindex @jobLogQueue, 0, (error, jobStr) =>
|
120 | return done error if error?
|
121 | todaySuffix = moment.utc().format('YYYY-MM-DD')
|
122 | index = "metric:meshblu-core-protocol-adapter-http:sampled-#{todaySuffix}"
|
123 | expect(JSON.parse jobStr).to.containSubset {
|
124 | "index": index
|
125 | "type": "meshblu-core-protocol-adapter-http:request"
|
126 | "body": {
|
127 | "request": {
|
128 | "metadata": {
|
129 | "auth": {
|
130 | "uuid": "irritable-captian"
|
131 | }
|
132 | "fromUuid": "irritable-captian"
|
133 | "jobType": "SendMessage"
|
134 | "toUuid": "irritable-captian"
|
135 | }
|
136 | }
|
137 | "response": {
|
138 | "metadata": {
|
139 | "code": 201
|
140 | "success": true
|
141 | }
|
142 | }
|
143 | }
|
144 | }
|
145 | done()
|
146 | return
|
147 |
|
148 | context 'when the request is unsuccessful', ->
|
149 | beforeEach ->
|
150 | @jobManager.do (@jobRequest, callback) =>
|
151 | response =
|
152 | metadata:
|
153 | code: 506
|
154 | responseId: @jobRequest.metadata.responseId
|
155 |
|
156 | callback null, response
|
157 |
|
158 | beforeEach (done) ->
|
159 | options =
|
160 | auth:
|
161 | username: 'irritable-captian'
|
162 | password: 'poop-deck'
|
163 | json:
|
164 | devices: ['*']
|
165 |
|
166 | request.post "http://localhost:#{@port}/messages", options, (error, @response) =>
|
167 | done error
|
168 |
|
169 | it 'should return a 506', ->
|
170 | expect(@response.statusCode).to.equal 506
|
171 |
|
172 | it 'should submit the correct job type', ->
|
173 | expect(@jobRequest.metadata.jobType).to.equal 'SendMessage'
|
174 |
|
175 | it 'should set the correct auth data', ->
|
176 | expect(@jobRequest.metadata.auth).to.deep.equal uuid: 'irritable-captian', token: 'poop-deck'
|
177 |
|
178 | it 'should send the correct message', ->
|
179 | message = JSON.parse @jobRequest.rawData
|
180 | expect(message).to.deep.equal devices: ['*']
|
181 |
|
182 | it 'should log the message', (done) ->
|
183 | @jobLogClient.llen @jobLogQueue, (error, count) =>
|
184 | return done error if error?
|
185 | expect(count).to.equal 2
|
186 | done()
|
187 | return
|
188 |
|
189 | it 'should log the attempt and success of the message', (done) ->
|
190 | @jobLogClient.lindex @jobLogQueue, 0, (error, jobStr) =>
|
191 | return done error if error?
|
192 | todaySuffix = moment.utc().format('YYYY-MM-DD')
|
193 | index = "metric:meshblu-core-protocol-adapter-http:failed-#{todaySuffix}"
|
194 | expect(JSON.parse jobStr).to.containSubset {
|
195 | "index": index
|
196 | "type": "meshblu-core-protocol-adapter-http:request"
|
197 | "body": {
|
198 | "request": {
|
199 | "metadata": {
|
200 | "auth": {
|
201 | "uuid": "irritable-captian"
|
202 | }
|
203 | "fromUuid": "irritable-captian"
|
204 | "jobType": "SendMessage"
|
205 | "toUuid": "irritable-captian"
|
206 | }
|
207 | }
|
208 | "response": {
|
209 | "metadata": {
|
210 | "code": 506
|
211 | "success": false
|
212 | }
|
213 | }
|
214 | }
|
215 | }
|
216 | done()
|
217 | return
|