forked from russellhaering/node-stomp-broker
/
client.test.js
299 lines (228 loc) · 9.34 KB
/
client.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
var util = require('util'),
Events = require('events').EventEmitter,
nodeunit = require('nodeunit'),
testCase = require('nodeunit').testCase;
var StompClient = require('../lib/client').StompClient;
var connectionObserver;
// surpress logs for the test
util.log = function() {};
// net mockage
var net = require('net');
net.createConnection = function() {
return connectionObserver;
};
var StompFrame = require('../lib/frame').StompFrame;
// Override StompFrame send function to allow inspection of frame data inside a test
var oldSend;
var sendHook = function() {};
module.exports = testCase({
setUp: function(callback) {
// Mock net object so we never try to send any real data
connectionObserver = new Events();
this.stompClient = new StompClient('127.0.0.1', 2098, 'user', 'pass', '1.0');
oldSend = StompFrame.prototype.send;
StompFrame.prototype.send = function(stream) {
var self = this;
process.nextTick(function () {
sendHook(self);
});
};
callback();
},
tearDown: function(callback) {
delete this.stompClient;
sendHook = function() {};
StompFrame.prototype.send = oldSend;
callback();
},
'check default properties are correctly set on a basic StompClient': function(test) {
var stompClient = new StompClient();
test.equal(stompClient.user, '');
test.equal(stompClient.pass, '');
test.equal(stompClient.address, '127.0.0.1');
test.equal(stompClient.port, 2098);
test.equal(stompClient.version, '1.0');
test.done();
},
'check outbound CONNECT frame correctly follows protocol specification': function(test) {
var self = this;
test.expect(4);
sendHook = function(stompFrame) {
test.equal(stompFrame.command, 'CONNECT');
test.deepEqual(stompFrame.headers, {
login: 'user',
passcode: 'pass'
});
test.equal(stompFrame.body, '');
test.equal(stompFrame.contentLength, -1);
test.done();
};
//start the test
this.stompClient.connect();
connectionObserver.emit('connect');
},
'check inbound CONNECTED frame parses correctly': function(test) {
var self = this;
var testId = '1234';
test.expect(2);
sendHook = function() {
self.stompClient.stream.emit('data', 'CONNECTED\nsession:' + testId + '\n\n\0');
};
this.stompClient._stompFrameEmitter.on('CONNECTED', function (stompFrame) {
test.equal(stompFrame.command, 'CONNECTED');
test.equal(testId, stompFrame.headers.session);
test.done();
});
//start the test
this.stompClient.connect(function() {});
connectionObserver.emit('connect');
},
'check outbound SUBSCRIBE frame correctly follows protocol specification': function(test) {
var self = this;
var testId = '1234';
var destination = '/queue/someQueue';
test.expect(3);
//mock that we received a CONNECTED from the stomp server in our send hook
sendHook = function(stompFrame) {
self.stompClient.stream.emit('data', 'CONNECTED\nsession:' + testId + '\n\n\0');
};
// Once connected - subscribe to a fake queue
this.stompClient._stompFrameEmitter.on('CONNECTED', function (stompFrame) {
//override the sendHook so we can test the latest stompframe to be sent
sendHook = function(stompFrame) {
test.equal(stompFrame.command, 'SUBSCRIBE');
test.equal(stompFrame.headers.destination, destination);
test.equal(stompFrame.headers.id, 'blah');
test.done();
};
self.stompClient.subscribe(destination, function(){
// this callback never gets called unless the client recieves some data down the subscription
// the point of this test is to ensure the SUBSCRIBE frame is correctly structured
// note the use of additional id header (optional in spec) below :)
}, { id: 'blah' });
});
this.stompClient.connect(function() {});
connectionObserver.emit('connect');
},
'check the SUBSCRIBE callback fires when we receive data down the destination queue': function(test) {
var self = this;
var testId = '1234';
var destination = '/queue/someQueue';
var messageId = 1;
var messageToBeSent = 'oh herrow!';
test.expect(5);
//mock that we received a CONNECTED from the stomp server in our send hook
sendHook = function(stompFrame) {
self.stompClient.stream.emit('data', 'CONNECTED\nsession:' + testId + '\n\n\0');
};
this.stompClient.connect(function() {
// Mock inbound MESSAGE frame
sendHook = function (stompFrame) {
self.stompClient.stream.emit('data', 'MESSAGE\ndestination:' + destination + '\nmessage-id:' + messageId + '\n\n' + messageToBeSent + '\0');
};
// Subscribe to a queue, and upon receipt of message (wired above) test that body/headers correctly propogate to callback
self.stompClient.subscribe(destination, function (body, headers) {
test.equal(body, messageToBeSent, 'Received message matches the sent one');
test.equal(headers['message-id'], messageId);
test.equal(headers.destination, destination);
test.equal(self.stompClient.subscriptions[destination].length, 1, 'ensure callback was added to subscription stack');
// Unsubscribe and ensure queue is cleared of the subscription (and related callback)
self.stompClient.unsubscribe(destination, {}, function () {
test.equal(typeof self.stompClient.subscriptions[destination], 'undefined', 'ensure queue is cleared of the subscription');
test.done();
});
});
});
connectionObserver.emit('connect');
},
'check outbound UNSUBSCRIBE frame correctly follows protocol specification': function (test) {
var self = this;
var testId = '1234';
var destination = '/queue/someQueue';
test.expect(3);
//mock that we received a CONNECTED from the stomp server in our send hook
sendHook = function(stompFrame) {
self.stompClient.stream.emit('data', 'CONNECTED\nsession:' + testId + '\n\n\0');
};
// Once connected - unsubscribe to a fake queue
this.stompClient._stompFrameEmitter.on('CONNECTED', function (stompFrame) {
//override the sendHook so we can test the latest stompframe to be sent
sendHook = function(stompFrame) {
test.equal(stompFrame.command, 'UNSUBSCRIBE');
test.equal(stompFrame.headers.destination, destination);
test.equal(stompFrame.headers.id, 'specialid');
test.done();
};
self.stompClient.unsubscribe(destination, { id: 'specialid' }, function() {});
});
this.stompClient.connect(function(){});
connectionObserver.emit('connect');
},
'check outbound SEND frame correctly follows protocol specification': function (test) {
var self = this;
var testId = '1234';
var destination = '/queue/someQueue';
var messageToBeSent = 'oh herrow!';
test.expect(3);
//mock that we received a CONNECTED from the stomp server in our send hook
sendHook = function (stompFrame) {
self.stompClient.stream.emit('data', 'CONNECTED\nsession:' + testId + '\n\n\0');
};
this.stompClient.connect(function() {
sendHook = function(stompFrame) {
test.equal(stompFrame.command, 'SEND');
test.deepEqual(stompFrame.headers, { destination: destination });
test.equal(stompFrame.body, messageToBeSent);
test.done();
};
self.stompClient.publish(destination, messageToBeSent);
});
connectionObserver.emit('connect');
},
'check parseError event fires when malformed frame is received': function(test) {
var self = this;
test.expect(1);
//mock that we received a CONNECTED from the stomp server in our send hook
sendHook = function (stompFrame) {
self.stompClient.stream.emit('data', 'CONNECTED\n\n\n\0');
};
this.stompClient._stompFrameEmitter.on('parseError', function (err) {
test.equal(err.message, 'Header "session" is required, and missing from frame: {"command":"CONNECTED","headers":{},"body":"\\n"}');
test.done();
});
this.stompClient.connect(function() {});
connectionObserver.emit('connect');
},
'check disconnect method correctly sends DISCONNECT frame, disconnects TCP stream, and fires callback': function (test) {
var self = this;
test.expect(7);
self.stompClient.on('disconnect', function() {
test.ok(true, 'disconnect event fired');
});
//mock that we received a CONNECTED from the stomp server in our send hook
sendHook = function (stompFrame) {
self.stompClient.stream.emit('data', 'CONNECTED\nsession:blah\n\n\0');
};
self.stompClient.connect(function() {
// Assert next outbound STOMP frame is a DISCONNECT
sendHook = function (stompFrame) {
test.equal(stompFrame.command, 'DISCONNECT');
test.deepEqual(stompFrame.headers, {});
test.equal(stompFrame.body, '');
};
self.stompClient.stream.on('end', function() {
test.ok(true, 'tcp stream end event is fired');
});
// Set disconnection callback to ensure it is called appropriately
self.stompClient.disconnect(function () {
test.ok(true, 'disconnect callback executed');
test.done();
});
});
// Mock the TCP end call
connectionObserver.end = function() {
test.ok(true, 'TCP end call made');
};
connectionObserver.emit('connect');
}
});