faye 0.7.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of faye might be problematic. Click here for more details.
- data/History.txt +15 -3
- data/README.rdoc +2 -6
- data/lib/faye-browser-min.js +1 -1
- data/lib/faye.rb +25 -36
- data/lib/faye/adapters/rack_adapter.rb +43 -22
- data/lib/faye/engines/connection.rb +7 -10
- data/lib/faye/engines/memory.rb +28 -28
- data/lib/faye/engines/proxy.rb +109 -0
- data/lib/faye/mixins/logging.rb +1 -8
- data/lib/faye/mixins/timeouts.rb +1 -1
- data/lib/faye/protocol/channel.rb +3 -3
- data/lib/faye/protocol/client.rb +50 -45
- data/lib/faye/protocol/extensible.rb +11 -18
- data/lib/faye/protocol/server.rb +53 -38
- data/lib/faye/transport/http.rb +49 -27
- data/lib/faye/transport/transport.rb +3 -1
- data/lib/faye/transport/web_socket.rb +6 -10
- data/lib/faye/util/namespace.rb +2 -2
- data/spec/browser.html +3 -1
- data/spec/encoding_helper.rb +7 -0
- data/spec/javascript/client_spec.js +0 -5
- data/spec/javascript/engine/memory_spec.js +7 -0
- data/spec/javascript/engine_spec.js +22 -57
- data/spec/javascript/server/handshake_spec.js +10 -6
- data/spec/javascript/server/integration_spec.js +11 -10
- data/spec/javascript/server/publish_spec.js +85 -0
- data/spec/javascript/server_spec.js +5 -51
- data/spec/node.js +6 -6
- data/spec/ruby/client_spec.rb +1 -1
- data/spec/ruby/engine/memory_spec.rb +7 -0
- data/spec/ruby/{engine_spec.rb → engine_examples.rb} +28 -34
- data/spec/ruby/rack_adapter_spec.rb +1 -1
- data/spec/ruby/server/handshake_spec.rb +10 -6
- data/spec/ruby/server/publish_spec.rb +81 -0
- data/spec/ruby/server_spec.rb +6 -44
- data/spec/spec_helper.rb +5 -18
- data/spec/testswarm +1 -5
- metadata +105 -180
- data/lib/faye/engines/base.rb +0 -66
- data/lib/faye/engines/redis.rb +0 -225
- data/lib/faye/thin_extensions.rb +0 -75
- data/lib/faye/util/web_socket.rb +0 -89
- data/lib/faye/util/web_socket/api.rb +0 -103
- data/lib/faye/util/web_socket/client.rb +0 -82
- data/lib/faye/util/web_socket/draft75_parser.rb +0 -53
- data/lib/faye/util/web_socket/draft76_parser.rb +0 -53
- data/lib/faye/util/web_socket/protocol8_parser.rb +0 -324
- data/spec/javascript/web_socket/client_spec.js +0 -121
- data/spec/javascript/web_socket/draft75parser_spec.js +0 -39
- data/spec/javascript/web_socket/protocol8parser_spec.js +0 -153
- data/spec/redis.conf +0 -42
- data/spec/ruby/web_socket/client_spec.rb +0 -126
- data/spec/ruby/web_socket/draft75_parser_spec.rb +0 -41
- data/spec/ruby/web_socket/protocol8_parser_spec.rb +0 -145
data/lib/faye/transport/http.rb
CHANGED
@@ -8,45 +8,67 @@ module Faye
|
|
8
8
|
def request(message, timeout)
|
9
9
|
retry_block = retry_block(message, timeout)
|
10
10
|
|
11
|
-
|
12
|
-
cookies = @
|
11
|
+
content = Faye.to_json(message)
|
12
|
+
cookies = @cookies.get_cookies(@endpoint)
|
13
|
+
params = build_params(URI.parse(@endpoint), content, cookies)
|
14
|
+
request = create_request(params)
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
request.callback do
|
17
|
+
handle_response(request.response, retry_block)
|
18
|
+
store_cookies([*request.response_header['SET_COOKIE']].compact)
|
19
|
+
end
|
20
|
+
request.errback do
|
21
|
+
retry_block.call
|
22
|
+
trigger(:down)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def build_params(uri, content, cookies)
|
29
|
+
{
|
16
30
|
:head => {
|
17
|
-
'Content-Length' => content.
|
31
|
+
'Content-Length' => content.bytesize,
|
18
32
|
'Content-Type' => 'application/json',
|
19
33
|
'Cookie' => cookies * '; ',
|
20
|
-
'Host' =>
|
21
|
-
},
|
34
|
+
'Host' => uri.host
|
35
|
+
}.merge(@headers),
|
36
|
+
|
22
37
|
:body => content,
|
23
38
|
:timeout => -1 # for em-http-request < 1.0
|
24
39
|
}
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_request(params)
|
43
|
+
version = EventMachine::HttpRequest::VERSION.split('.')[0].to_i
|
44
|
+
client = if version >= 1
|
45
|
+
options = { # for em-http-request >= 1.0
|
46
|
+
:inactivity_timeout => 0 # connection inactivity (post-setup) timeout (0 = disable timeout)
|
47
|
+
}
|
48
|
+
EventMachine::HttpRequest.new(@endpoint, options)
|
49
|
+
else
|
50
|
+
EventMachine::HttpRequest.new(@endpoint)
|
51
|
+
end
|
52
|
+
|
53
|
+
client.post(params)
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_response(response, retry_block)
|
57
|
+
message = Yajl::Parser.parse(response) rescue nil
|
58
|
+
if message
|
59
|
+
receive(message)
|
60
|
+
trigger(:up)
|
30
61
|
else
|
31
|
-
request = EventMachine::HttpRequest.new(@endpoint).post(params)
|
32
|
-
end
|
33
|
-
request.callback do
|
34
|
-
begin
|
35
|
-
cookies = [*request.response_header['SET_COOKIE']]
|
36
|
-
cookies.each do |cookie|
|
37
|
-
@client.cookies.set_cookie(@endpoint, cookie)
|
38
|
-
end
|
39
|
-
receive(JSON.parse(request.response))
|
40
|
-
trigger(:up)
|
41
|
-
rescue
|
42
|
-
retry_block.call
|
43
|
-
end
|
44
|
-
end
|
45
|
-
request.errback do
|
46
62
|
retry_block.call
|
47
63
|
trigger(:down)
|
48
64
|
end
|
49
65
|
end
|
66
|
+
|
67
|
+
def store_cookies(cookies)
|
68
|
+
cookies.each do |cookie|
|
69
|
+
@cookies.set_cookie(@endpoint, cookie)
|
70
|
+
end
|
71
|
+
end
|
50
72
|
end
|
51
73
|
|
52
74
|
Transport.register 'long-polling', Transport::Http
|
@@ -5,6 +5,8 @@ module Faye
|
|
5
5
|
include Publisher
|
6
6
|
include Timeouts
|
7
7
|
|
8
|
+
attr_accessor :cookies, :headers
|
9
|
+
|
8
10
|
def initialize(client, endpoint)
|
9
11
|
debug('Created new ? transport for ?', connection_type, endpoint)
|
10
12
|
@client = client
|
@@ -60,7 +62,7 @@ module Faye
|
|
60
62
|
|
61
63
|
def retry_block(message, timeout)
|
62
64
|
lambda do
|
63
|
-
EventMachine.add_timer(
|
65
|
+
EventMachine.add_timer(@client.retry) { request(message, timeout) }
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
@@ -37,10 +37,9 @@ module Faye
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def request(messages, timeout = nil)
|
40
|
-
@timeout = timeout || @timeout
|
41
40
|
@messages ||= {}
|
42
41
|
messages.each { |message| @messages[message['id']] = message }
|
43
|
-
with_socket { |socket| socket.send(
|
42
|
+
with_socket { |socket| socket.send(Faye.to_json(messages)) }
|
44
43
|
end
|
45
44
|
|
46
45
|
def with_socket(&resume)
|
@@ -71,7 +70,7 @@ module Faye
|
|
71
70
|
end
|
72
71
|
|
73
72
|
@socket.onmessage = lambda do |event|
|
74
|
-
messages = [
|
73
|
+
messages = [Yajl::Parser.parse(event.data)].flatten
|
75
74
|
messages.each { |message| @messages.delete(message['id']) }
|
76
75
|
receive(messages)
|
77
76
|
end
|
@@ -82,13 +81,10 @@ module Faye
|
|
82
81
|
@state = UNCONNECTED
|
83
82
|
@socket = nil
|
84
83
|
|
85
|
-
if was_connected
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
@timeout = @timeout * 2
|
90
|
-
trigger(:down)
|
91
|
-
end
|
84
|
+
next resend if was_connected
|
85
|
+
|
86
|
+
EventMachine.add_timer(@client.retry) { connect }
|
87
|
+
trigger(:down)
|
92
88
|
end
|
93
89
|
end
|
94
90
|
|
data/lib/faye/util/namespace.rb
CHANGED
data/spec/browser.html
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
5
5
|
<title>Faye test suite</title>
|
6
|
-
<script type="text/javascript" src="../
|
6
|
+
<script type="text/javascript" src="../node_modules/jsclass/min/loader.js"></script>
|
7
7
|
</head>
|
8
8
|
<body>
|
9
9
|
<script type="text/javascript">
|
@@ -16,6 +16,8 @@
|
|
16
16
|
heartbeat: function() {}
|
17
17
|
}
|
18
18
|
|
19
|
+
JS.cacheBust = true
|
20
|
+
|
19
21
|
JS.Packages(function() { with(this) {
|
20
22
|
file('../build/faye-browser-min.js').provides('Faye')
|
21
23
|
autoload(/.*Spec/, {from: './javascript'})
|
@@ -583,11 +583,6 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
|
|
583
583
|
client.publish("/messages/foo", {hello: "world"})
|
584
584
|
}})
|
585
585
|
|
586
|
-
it("throws an error when publishing to an invalid channel", function() { with(this) {
|
587
|
-
expect(transport, "send").given(objectIncluding({channel: "/messages/*"}), 60).exactly(0)
|
588
|
-
assertThrows(Error, function() { client.publish("/messages/*", {hello: "world"}) })
|
589
|
-
}})
|
590
|
-
|
591
586
|
describe("on publish failure", function() { with(this) {
|
592
587
|
before(function() { with(this) {
|
593
588
|
stubResponse({channel: "/messages/foo",
|
@@ -12,11 +12,11 @@ JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
|
12
12
|
connect: function(name, engine, resume) {
|
13
13
|
var clientId = this._clients[name]
|
14
14
|
var inboxes = this._inboxes
|
15
|
-
engine.connect(clientId, {}, function(
|
16
|
-
|
17
|
-
delete
|
18
|
-
inboxes[name].push(
|
19
|
-
}
|
15
|
+
engine.connect(clientId, {}, function(messages) {
|
16
|
+
for (var i = 0, n = messages.length; i < n; i++) {
|
17
|
+
delete messages[i].id
|
18
|
+
inboxes[name].push(messages[i])
|
19
|
+
}
|
20
20
|
})
|
21
21
|
setTimeout(resume, 10)
|
22
22
|
},
|
@@ -32,7 +32,7 @@ JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
|
32
32
|
|
33
33
|
check_num_clients: function(n, resume) {
|
34
34
|
var ids = new JS.Set()
|
35
|
-
|
35
|
+
for (var key in this._clients) ids.add(this._clients[key])
|
36
36
|
this.assertEqual(n, ids.count())
|
37
37
|
resume()
|
38
38
|
},
|
@@ -55,10 +55,10 @@ JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
|
55
55
|
|
56
56
|
publish: function(messages, resume) {
|
57
57
|
messages = [].concat(messages)
|
58
|
-
|
59
|
-
message = Faye.extend({id: Faye.random()},
|
58
|
+
for (var i = 0, n = messages.length; i < n; i++) {
|
59
|
+
var message = Faye.extend({id: Faye.random()}, messages[i])
|
60
60
|
this.engine.publish(message)
|
61
|
-
}
|
61
|
+
}
|
62
62
|
setTimeout(resume, 20)
|
63
63
|
},
|
64
64
|
|
@@ -108,29 +108,18 @@ JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
|
108
108
|
check_different_messages: function(a, b, resume) {
|
109
109
|
this.assertNotSame(this._inboxes[a][0], this._inboxes[b][0])
|
110
110
|
resume()
|
111
|
-
},
|
112
|
-
|
113
|
-
clean_redis_db: function(resume) {
|
114
|
-
this.engine.disconnect()
|
115
|
-
var redis = require('redis').createClient(6379, 'localhost', {no_ready_check: true})
|
116
|
-
redis.auth(this.engineOpts.password)
|
117
|
-
redis.flushall(function() {
|
118
|
-
redis.end()
|
119
|
-
resume()
|
120
|
-
})
|
121
111
|
}
|
122
112
|
})
|
123
113
|
|
124
114
|
JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this) {
|
125
|
-
include(JS.Test.Helpers)
|
126
|
-
|
127
|
-
define("create_engine", function() { with(this) {
|
128
|
-
var opts = Faye.extend(options(), engineOpts)
|
129
|
-
return new engineKlass(opts)
|
130
|
-
}})
|
131
|
-
|
132
115
|
sharedExamplesFor("faye engine", function() { with(this) {
|
116
|
+
include(JS.Test.Helpers)
|
133
117
|
include(EngineSteps)
|
118
|
+
|
119
|
+
define("create_engine", function() { with(this) {
|
120
|
+
var opts = Faye.extend(options(), engineOpts)
|
121
|
+
return new Faye.Engine.Proxy(opts)
|
122
|
+
}})
|
134
123
|
|
135
124
|
define("options", function() { return {timeout: 1} })
|
136
125
|
|
@@ -390,7 +379,14 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
390
379
|
}})
|
391
380
|
|
392
381
|
sharedBehavior("distributed engine", function() { with(this) {
|
382
|
+
include(JS.Test.Helpers)
|
393
383
|
include(EngineSteps)
|
384
|
+
|
385
|
+
define("create_engine", function() { with(this) {
|
386
|
+
var opts = Faye.extend(options(), engineOpts)
|
387
|
+
return new Faye.Engine.Proxy(opts)
|
388
|
+
}})
|
389
|
+
|
394
390
|
define("options", function() { return {timeout: 1} })
|
395
391
|
|
396
392
|
before(function() { with(this) {
|
@@ -418,35 +414,4 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
418
414
|
}})
|
419
415
|
}})
|
420
416
|
}})
|
421
|
-
|
422
|
-
describe("Faye.Engine.Memory", function() { with(this) {
|
423
|
-
before(function() {
|
424
|
-
this.engineKlass = Faye.Engine.Memory
|
425
|
-
this.engineOpts = {}
|
426
|
-
})
|
427
|
-
|
428
|
-
itShouldBehaveLike("faye engine")
|
429
|
-
}})
|
430
|
-
|
431
|
-
describe("Faye.Engine.Redis", function() { with(this) {
|
432
|
-
before(function() {
|
433
|
-
this.engineKlass = Faye.Engine.Redis
|
434
|
-
this.engineOpts = {password: "foobared", namespace: new Date().getTime().toString()}
|
435
|
-
})
|
436
|
-
after(function() { this.clean_redis_db() })
|
437
|
-
|
438
|
-
itShouldBehaveLike("faye engine")
|
439
|
-
|
440
|
-
describe("distribution", function() { with(this) {
|
441
|
-
itShouldBehaveLike("distributed engine")
|
442
|
-
}})
|
443
|
-
|
444
|
-
describe("using a Unix socket", function() { with(this) {
|
445
|
-
before(function() { with(this) {
|
446
|
-
this.engineOpts.socket = "/tmp/redis.sock"
|
447
|
-
}})
|
448
|
-
|
449
|
-
itShouldBehaveLike("faye engine")
|
450
|
-
}})
|
451
|
-
}})
|
452
417
|
}})
|
@@ -3,6 +3,10 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
3
3
|
this.engine = {}
|
4
4
|
stub(Faye.Engine, "get").returns(engine)
|
5
5
|
this.server = new Faye.Server()
|
6
|
+
|
7
|
+
this.connectionTypes = ["long-polling", "cross-origin-long-polling",
|
8
|
+
"callback-polling","websocket",
|
9
|
+
"eventsource","in-process"]
|
6
10
|
}})
|
7
11
|
|
8
12
|
describe("#handshake", function() { with(this) {
|
@@ -25,7 +29,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
25
29
|
channel: "/meta/handshake",
|
26
30
|
successful: true,
|
27
31
|
version: "1.0",
|
28
|
-
supportedConnectionTypes:
|
32
|
+
supportedConnectionTypes: connectionTypes,
|
29
33
|
clientId: "clientid"
|
30
34
|
}, response)
|
31
35
|
})
|
@@ -41,7 +45,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
41
45
|
channel: "/meta/handshake",
|
42
46
|
successful: true,
|
43
47
|
version: "1.0",
|
44
|
-
supportedConnectionTypes:
|
48
|
+
supportedConnectionTypes: connectionTypes,
|
45
49
|
clientId: "clientid",
|
46
50
|
id: "foo"
|
47
51
|
}, response)
|
@@ -65,7 +69,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
65
69
|
successful: false,
|
66
70
|
error: "402:version:Missing required parameter",
|
67
71
|
version: "1.0",
|
68
|
-
supportedConnectionTypes:
|
72
|
+
supportedConnectionTypes: connectionTypes
|
69
73
|
}, response)
|
70
74
|
})
|
71
75
|
}})
|
@@ -86,7 +90,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
86
90
|
successful: false,
|
87
91
|
error: "402:supportedConnectionTypes:Missing required parameter",
|
88
92
|
version: "1.0",
|
89
|
-
supportedConnectionTypes:
|
93
|
+
supportedConnectionTypes: connectionTypes
|
90
94
|
}, response)
|
91
95
|
})
|
92
96
|
}})
|
@@ -109,7 +113,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
109
113
|
successful: false,
|
110
114
|
error: "301:iframe,flash:Connection types not supported",
|
111
115
|
version: "1.0",
|
112
|
-
supportedConnectionTypes:
|
116
|
+
supportedConnectionTypes: connectionTypes
|
113
117
|
}, response)
|
114
118
|
})
|
115
119
|
}})
|
@@ -132,7 +136,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
132
136
|
successful: false,
|
133
137
|
error: "invalid",
|
134
138
|
version: "1.0",
|
135
|
-
supportedConnectionTypes:
|
139
|
+
supportedConnectionTypes: connectionTypes
|
136
140
|
}, response)
|
137
141
|
})
|
138
142
|
}})
|
@@ -28,16 +28,17 @@ JS.ENV.IntegrationSteps = JS.Test.asyncSteps({
|
|
28
28
|
var n = channels.length
|
29
29
|
if (n === 0) return this._clients[name].connect(callback)
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
31
|
+
for (var i = 0; i < n; i++)
|
32
|
+
(function(channel) {
|
33
|
+
var subscription = this._clients[name].subscribe(channel, function(message) {
|
34
|
+
this._inboxes[name][channel] = this._inboxes[name][channel] || []
|
35
|
+
this._inboxes[name][channel].push(message)
|
36
|
+
}, this)
|
37
|
+
subscription.callback(function() {
|
38
|
+
n -= 1
|
39
|
+
if (n === 0) callback()
|
40
|
+
})
|
41
|
+
}).call(this, channels[i]);
|
41
42
|
},
|
42
43
|
|
43
44
|
publish: function(name, channel, message, callback) {
|
@@ -0,0 +1,85 @@
|
|
1
|
+
JS.ENV.Server.PublishSpec = JS.Test.describe("Server publish", function() { with(this) {
|
2
|
+
before(function() { with(this) {
|
3
|
+
this.engine = {}
|
4
|
+
stub(Faye.Engine, "get").returns(engine)
|
5
|
+
this.server = new Faye.Server()
|
6
|
+
|
7
|
+
this.message = {channel: "/some/channel", data: "publish"}
|
8
|
+
}})
|
9
|
+
|
10
|
+
describe("publishing a message", function() { with(this) {
|
11
|
+
it("tells the engine to publish the message", function() { with(this) {
|
12
|
+
expect(engine, "publish").given(message)
|
13
|
+
server.process(message, false, function() {})
|
14
|
+
}})
|
15
|
+
|
16
|
+
it("returns a successful response", function() { with(this) {
|
17
|
+
stub(engine, "publish")
|
18
|
+
server.process(message, false, function(response) {
|
19
|
+
assertEqual([
|
20
|
+
{ channel: "/some/channel",
|
21
|
+
successful: true
|
22
|
+
}
|
23
|
+
], response)
|
24
|
+
})
|
25
|
+
}})
|
26
|
+
|
27
|
+
describe("with an invalid channel", function() { with(this) {
|
28
|
+
before(function() { with(this) {
|
29
|
+
message.channel = "channel"
|
30
|
+
}})
|
31
|
+
|
32
|
+
it("does not tell the engine to publish the message", function() { with(this) {
|
33
|
+
expect(engine, "publish").exactly(0)
|
34
|
+
server.process(message, false, function() {})
|
35
|
+
}})
|
36
|
+
|
37
|
+
it("returns an unsuccessful response", function() { with(this) {
|
38
|
+
stub(engine, "publish")
|
39
|
+
server.process(message, false, function(response) {
|
40
|
+
assertEqual([
|
41
|
+
{ channel: "channel",
|
42
|
+
successful: false,
|
43
|
+
error: "405:channel:Invalid channel"
|
44
|
+
}
|
45
|
+
], response)
|
46
|
+
})
|
47
|
+
}})
|
48
|
+
}})
|
49
|
+
|
50
|
+
describe("with an error", function() { with(this) {
|
51
|
+
before(function() { with(this) {
|
52
|
+
message.error = "invalid"
|
53
|
+
}})
|
54
|
+
|
55
|
+
it("does not tell the engine to publish the message", function() { with(this) {
|
56
|
+
expect(engine, "publish").exactly(0)
|
57
|
+
server.process(message, false, function() {})
|
58
|
+
}})
|
59
|
+
|
60
|
+
it("returns an unsuccessful response", function() { with(this) {
|
61
|
+
stub(engine, "publish")
|
62
|
+
server.process(message, false, function(response) {
|
63
|
+
assertEqual([
|
64
|
+
{ channel: "/some/channel",
|
65
|
+
successful: false,
|
66
|
+
error: "invalid"
|
67
|
+
}
|
68
|
+
], response)
|
69
|
+
})
|
70
|
+
}})
|
71
|
+
}})
|
72
|
+
|
73
|
+
describe("to an invalid channel", function() { with(this) {
|
74
|
+
before(function() { with(this) {
|
75
|
+
message.channel = "/invalid/*"
|
76
|
+
}})
|
77
|
+
|
78
|
+
it("does not tell the engine to publish the message", function() { with(this) {
|
79
|
+
expect(engine, "publish").exactly(0)
|
80
|
+
server.process(message, false, function() {})
|
81
|
+
}})
|
82
|
+
}})
|
83
|
+
}})
|
84
|
+
}})
|
85
|
+
|