socky-server 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.textile +95 -0
- data/README.md +30 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/bin/socky +5 -0
- data/lib/em-websocket_hacks.rb +15 -0
- data/lib/socky.rb +75 -0
- data/lib/socky/connection.rb +137 -0
- data/lib/socky/connection/authentication.rb +99 -0
- data/lib/socky/connection/finders.rb +67 -0
- data/lib/socky/message.rb +85 -0
- data/lib/socky/misc.rb +74 -0
- data/lib/socky/net_request.rb +27 -0
- data/lib/socky/options.rb +39 -0
- data/lib/socky/options/config.rb +79 -0
- data/lib/socky/options/parser.rb +93 -0
- data/lib/socky/runner.rb +95 -0
- data/spec/em-websocket_spec.rb +36 -0
- data/spec/files/default.yml +18 -0
- data/spec/files/invalid.yml +1 -0
- data/spec/socky/connection/authentication_spec.rb +183 -0
- data/spec/socky/connection/finders_spec.rb +188 -0
- data/spec/socky/connection_spec.rb +151 -0
- data/spec/socky/message_spec.rb +102 -0
- data/spec/socky/misc_spec.rb +74 -0
- data/spec/socky/net_request_spec.rb +42 -0
- data/spec/socky/options/config_spec.rb +72 -0
- data/spec/socky/options/parser_spec.rb +76 -0
- data/spec/socky/options_spec.rb +60 -0
- data/spec/socky/runner_spec.rb +88 -0
- data/spec/socky_spec.rb +89 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/stallion.rb +96 -0
- metadata +198 -0
data/lib/socky/runner.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
module Socky
|
2
|
+
# default runner class - creates server and runs it
|
3
|
+
class Runner
|
4
|
+
include Socky::Misc
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# create new eventmachine server
|
8
|
+
def run(argv = ARGV)
|
9
|
+
server = self.new(argv)
|
10
|
+
|
11
|
+
if options[:kill]
|
12
|
+
server.kill_pid
|
13
|
+
elsif options[:daemonize]
|
14
|
+
server.daemonize
|
15
|
+
else
|
16
|
+
server.start
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# set server-wide options from args
|
22
|
+
def initialize(argv = ARGV)
|
23
|
+
Options.prepare(argv)
|
24
|
+
end
|
25
|
+
|
26
|
+
# start eventmachine server
|
27
|
+
# require options to be parsed earlier
|
28
|
+
def start
|
29
|
+
EventMachine.epoll
|
30
|
+
|
31
|
+
EventMachine.run do
|
32
|
+
|
33
|
+
trap("TERM") { stop }
|
34
|
+
trap("INT") { stop }
|
35
|
+
|
36
|
+
EventMachine::start_server("0.0.0.0", options[:port], EventMachine::WebSocket::Connection,
|
37
|
+
:debug => options[:deep_debug], :secure => options[:secure], :tls_options => options[:tls_options]) do |ws|
|
38
|
+
|
39
|
+
connection = Socky::Connection.new(ws)
|
40
|
+
ws.onopen { connection.subscribe }
|
41
|
+
ws.onmessage { |msg| connection.process_message(msg) }
|
42
|
+
ws.onclose { connection.unsubscribe }
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
info ["Server started"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# stop eventmachine server
|
51
|
+
def stop
|
52
|
+
info ["Server stopping"]
|
53
|
+
EventMachine.stop
|
54
|
+
end
|
55
|
+
|
56
|
+
# run server in daemon mode
|
57
|
+
def daemonize
|
58
|
+
fork do
|
59
|
+
Process.setsid
|
60
|
+
exit if fork
|
61
|
+
store_pid(Process.pid)
|
62
|
+
# Dir.chdir "/" # Mucks up logs
|
63
|
+
File.umask 0000
|
64
|
+
STDIN.reopen "/dev/null"
|
65
|
+
STDOUT.reopen "/dev/null", "a"
|
66
|
+
STDERR.reopen STDOUT
|
67
|
+
start
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# kill daemonized server according to pid file in pid_path
|
72
|
+
def kill_pid
|
73
|
+
begin
|
74
|
+
pid = IO.read(pid_path).chomp.to_i
|
75
|
+
FileUtils.rm pid_path
|
76
|
+
Process.kill(9, pid)
|
77
|
+
puts "killed PID: #{pid}"
|
78
|
+
rescue => e
|
79
|
+
puts e
|
80
|
+
end
|
81
|
+
exit
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def store_pid(pid)
|
87
|
+
FileUtils.mkdir_p(File.dirname(pid_path))
|
88
|
+
File.open(pid_path, 'w'){|f| f.write("#{pid}\n")}
|
89
|
+
rescue => e
|
90
|
+
puts e
|
91
|
+
exit
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::WebSocket::Connection do
|
4
|
+
|
5
|
+
it "should not receive debug message if :debug option is false" do
|
6
|
+
EM.run do
|
7
|
+
Socky.logger.should_not_receive(:debug)
|
8
|
+
EM.add_timer(0.1) do
|
9
|
+
http = EventMachine::HttpRequest.new('ws://127.0.0.1:9999/').get(:timeout => 0)
|
10
|
+
http.errback { http.close_connection }
|
11
|
+
http.callback { http.close_connection }
|
12
|
+
end
|
13
|
+
|
14
|
+
EM::WebSocket.start(:host => "127.0.0.1", :port => 9999, :debug => false) do |ws|
|
15
|
+
ws.onclose { EM.stop }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should use Socky.logger.debug instead of pp when instance call #debug" do
|
21
|
+
EM.run do
|
22
|
+
Socky.logger.should_receive(:debug).with("Socket initialize")
|
23
|
+
Socky.logger.should_receive(:debug).with(anything()).at_least(:once)
|
24
|
+
EM.add_timer(0.1) do
|
25
|
+
http = EventMachine::HttpRequest.new('ws://127.0.0.1:9999/').get(:timeout => 0)
|
26
|
+
http.errback { http.close_connection }
|
27
|
+
http.callback { http.close_connection }
|
28
|
+
end
|
29
|
+
|
30
|
+
EM::WebSocket.start(:host => "127.0.0.1", :port => 9999, :debug => true) do |ws|
|
31
|
+
ws.onclose { EM.stop }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
:port: 8080
|
2
|
+
:debug: false
|
3
|
+
|
4
|
+
# :subscribe_url: http://localhost:3000/socky/subscribe
|
5
|
+
# :unsubscribe_url: http://localhost:3000/socky/unsubscribe
|
6
|
+
|
7
|
+
:secret: my_secret_key
|
8
|
+
|
9
|
+
:secure: false
|
10
|
+
|
11
|
+
# :timeout: 3
|
12
|
+
|
13
|
+
# :log_path: /var/log/socky.log
|
14
|
+
# :pid_path: /var/run/socky.pid
|
15
|
+
|
16
|
+
# :tls_options:
|
17
|
+
# :private_key_file: /private/key
|
18
|
+
# :cert_chain_file: /ssl/certificate
|
@@ -0,0 +1 @@
|
|
1
|
+
invalid data
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Socky::Connection::Authentication do
|
4
|
+
include Socky::Connection::Authentication
|
5
|
+
|
6
|
+
context "instance" do
|
7
|
+
context "#subscribe_request" do
|
8
|
+
before(:each) do
|
9
|
+
stub!(:admin).and_return(false)
|
10
|
+
stub!(:send_data)
|
11
|
+
end
|
12
|
+
it "should not call #send_subscribe_request if already authenticated" do
|
13
|
+
stub!(:authenticated?).and_return(true)
|
14
|
+
should_not_receive(:send_subscribe_request)
|
15
|
+
subscribe_request
|
16
|
+
end
|
17
|
+
it "should call #send_subscribe_request if unauthenticated" do
|
18
|
+
stub!(:authenticated?).and_return(false)
|
19
|
+
should_receive(:send_subscribe_request)
|
20
|
+
subscribe_request
|
21
|
+
end
|
22
|
+
it "should add self to connection list if #send_subscribe_request block is true" do
|
23
|
+
EM.run do
|
24
|
+
stub!(:authenticated?).and_return(false)
|
25
|
+
stub!(:send_subscribe_request).and_yield(true)
|
26
|
+
should_receive(:add_to_pool)
|
27
|
+
subscribe_request
|
28
|
+
EM.stop
|
29
|
+
end
|
30
|
+
end
|
31
|
+
it "should be authenticated by url if #send_subscribe_request block is true" do
|
32
|
+
EM.run do
|
33
|
+
stub!(:authenticated?).and_return(false)
|
34
|
+
stub!(:send_subscribe_request).and_yield(true)
|
35
|
+
stub!(:add_to_pool)
|
36
|
+
subscribe_request
|
37
|
+
authenticated_by_url?.should be_true
|
38
|
+
EM.stop
|
39
|
+
end
|
40
|
+
end
|
41
|
+
it "should disconnect if #send_subscribe_request block is false" do
|
42
|
+
EM.run do
|
43
|
+
stub!(:send_subscribe_request).and_yield(false)
|
44
|
+
should_receive(:disconnect)
|
45
|
+
subscribe_request
|
46
|
+
EM.add_timer(0.1) do
|
47
|
+
EM.stop
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
context "#unsubscribe_request" do
|
53
|
+
it "should remove self from connection list if authenticated" do
|
54
|
+
stub!(:admin).and_return(false)
|
55
|
+
stub!(:authenticated?).and_return(true)
|
56
|
+
should_receive(:remove_from_pool)
|
57
|
+
unsubscribe_request
|
58
|
+
end
|
59
|
+
it "should send unsubscribe request if authenticated but not admin" do
|
60
|
+
stub!(:admin).and_return(false)
|
61
|
+
stub!(:authenticated?).and_return(true)
|
62
|
+
stub!(:remove_from_pool)
|
63
|
+
should_receive(:send_unsubscribe_request)
|
64
|
+
unsubscribe_request
|
65
|
+
end
|
66
|
+
it "should not send unsubscribe request if authenticated and admin" do
|
67
|
+
stub!(:admin).and_return(true)
|
68
|
+
stub!(:authenticated?).and_return(true)
|
69
|
+
stub!(:remove_from_pool)
|
70
|
+
should_not_receive(:send_unsubscribe_request)
|
71
|
+
unsubscribe_request
|
72
|
+
end
|
73
|
+
it "should not send unsubscribe request if unauthenticated" do
|
74
|
+
stub!(:authenticated?).and_return(false)
|
75
|
+
should_not_receive(:send_unsubscribe_request)
|
76
|
+
unsubscribe_request
|
77
|
+
end
|
78
|
+
end
|
79
|
+
context "#authenticated?" do
|
80
|
+
it "should authenticate as admin if admin" do
|
81
|
+
stub!(:admin).and_return(true)
|
82
|
+
should_receive(:authenticate_as_admin)
|
83
|
+
authenticated?
|
84
|
+
end
|
85
|
+
it "should authenticate as user if not admin" do
|
86
|
+
stub!(:admin).and_return(false)
|
87
|
+
should_receive(:authenticate_as_user)
|
88
|
+
authenticated?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
context "#authenticate_as_admin" do
|
92
|
+
it "should return true if client secret is equal server secret" do
|
93
|
+
stub!(:secret).and_return("test")
|
94
|
+
Socky.stub!(:options).and_return({:secret => "test"})
|
95
|
+
authenticate_as_admin.should be_true
|
96
|
+
end
|
97
|
+
it "should return false if client secret is not equal server secret" do
|
98
|
+
stub!(:secret).and_return("abstract")
|
99
|
+
Socky.stub!(:options).and_return({:secret => "test"})
|
100
|
+
authenticate_as_admin.should be_false
|
101
|
+
end
|
102
|
+
it "should return true if server secret is nil" do
|
103
|
+
stub!(:secret).and_return("abstract")
|
104
|
+
Socky.stub!(:options).and_return({:secret => nil})
|
105
|
+
authenticate_as_admin.should be_true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
it "#authenticate_as_user should call #authenticated_by_url?" do
|
109
|
+
should_receive(:authenticated_by_url?)
|
110
|
+
authenticate_as_user
|
111
|
+
end
|
112
|
+
it "#authenticated_by_url? should return current status" do
|
113
|
+
instance_variable_set('@authenticated_by_url',true)
|
114
|
+
authenticated_by_url?.should be_true
|
115
|
+
instance_variable_set('@authenticated_by_url',false)
|
116
|
+
authenticated_by_url?.should be_false
|
117
|
+
end
|
118
|
+
context "#send_subscribe_request" do
|
119
|
+
it "should build params for request if socky option subscribe_url is not nil" do
|
120
|
+
Socky.stub!(:options).and_return({:subscribe_url => "any"})
|
121
|
+
should_receive(:params_for_request)
|
122
|
+
send_subscribe_request
|
123
|
+
end
|
124
|
+
it "should call Socky::NetRequest#post if socky option subscribe_url is not nil" do
|
125
|
+
Socky.stub!(:options).and_return({:subscribe_url => "any"})
|
126
|
+
stub!(:params_for_request)
|
127
|
+
Socky::NetRequest.should_receive(:post)
|
128
|
+
send_subscribe_request
|
129
|
+
end
|
130
|
+
it "should not call Socky::NetRequest#post if socky option subscribe_url is nil" do
|
131
|
+
Socky.stub!(:options).and_return({:subscribe_url => nil})
|
132
|
+
Socky::NetRequest.should_not_receive(:post)
|
133
|
+
send_subscribe_request{}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
context "#send_unsubscribe_request" do
|
137
|
+
it "should build params for request if socky option unsubscribe_url is not nil" do
|
138
|
+
Socky.stub!(:options).and_return({:unsubscribe_url => "any"})
|
139
|
+
should_receive(:params_for_request)
|
140
|
+
send_unsubscribe_request{}
|
141
|
+
end
|
142
|
+
it "should call Socky::NetRequest#post if socky option unsubscribe_url is not nil" do
|
143
|
+
Socky.stub!(:options).and_return({:unsubscribe_url => "any"})
|
144
|
+
stub!(:params_for_request)
|
145
|
+
Socky::NetRequest.should_receive(:post)
|
146
|
+
send_unsubscribe_request{}
|
147
|
+
end
|
148
|
+
it "should not call Socky::NetRequest#post if socky option unsubscribe_url is nil" do
|
149
|
+
Socky.stub!(:options).and_return({:unsubscribe_url => nil})
|
150
|
+
Socky::NetRequest.should_not_receive(:post)
|
151
|
+
send_unsubscribe_request{}
|
152
|
+
end
|
153
|
+
end
|
154
|
+
context "#params_for_request" do
|
155
|
+
before(:each) do
|
156
|
+
stub!(:client)
|
157
|
+
stub!(:secret)
|
158
|
+
stub!(:channels).and_return([])
|
159
|
+
end
|
160
|
+
it "should return empty hash if none of (client,secret,channels) are set" do
|
161
|
+
params_for_request.should eql({})
|
162
|
+
end
|
163
|
+
it "should return client as client_id if set" do
|
164
|
+
stub!(:client).and_return("some client")
|
165
|
+
params_for_request.should eql({:client_id => "some client"})
|
166
|
+
end
|
167
|
+
it "should return secret as client_secret if set" do
|
168
|
+
stub!(:secret).and_return("some secret")
|
169
|
+
params_for_request.should eql({:client_secret => "some secret"})
|
170
|
+
end
|
171
|
+
it "should return channels if not empty" do
|
172
|
+
stub!(:channels).and_return(["some channel"])
|
173
|
+
params_for_request.should eql({:channels => ["some channel"]})
|
174
|
+
end
|
175
|
+
it "should return client, secret and channels as hash if all are set" do
|
176
|
+
stub!(:client).and_return("some client")
|
177
|
+
stub!(:secret).and_return("some secret")
|
178
|
+
stub!(:channels).and_return(["some channel"])
|
179
|
+
params_for_request.should eql({:client_id => "some client", :client_secret => "some secret", :channels => ["some channel"]})
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Socky::Connection::Finders do
|
4
|
+
include Socky::Connection::Finders
|
5
|
+
include Socky::Misc
|
6
|
+
|
7
|
+
context "class" do
|
8
|
+
before(:each) do
|
9
|
+
@connection1 = mock(:connection1, :client => "client1", :channels => [nil])
|
10
|
+
@connection2 = mock(:connection2, :client => "client1", :channels => ["1", "3", "5"])
|
11
|
+
@connection3 = mock(:connection3, :client => "client2", :channels => ["2", "5"])
|
12
|
+
@connection4 = mock(:connection4, :client => "client3", :channels => ["3", "5"])
|
13
|
+
@connections = [@connection1,@connection2,@connection3,@connection4]
|
14
|
+
@connections.collect { |connection| Socky::Connection.connections << connection }
|
15
|
+
end
|
16
|
+
after(:each) do
|
17
|
+
Socky::Connection.connections.clear
|
18
|
+
end
|
19
|
+
|
20
|
+
it "#find_all should return all connections" do
|
21
|
+
find_all.should eql(@connections)
|
22
|
+
end
|
23
|
+
context "#find" do
|
24
|
+
it "should return all connections if no options specified" do
|
25
|
+
find.should eql(@connections)
|
26
|
+
end
|
27
|
+
context "on :to" do
|
28
|
+
context "if :clients option is specified" do
|
29
|
+
it "should return all connections if :clients is nil" do
|
30
|
+
find(:to => {:clients => nil}).should eql(@connections)
|
31
|
+
end
|
32
|
+
it "should return none connections if :clients is empty" do
|
33
|
+
find(:to => {:clients => []}).should eql([])
|
34
|
+
end
|
35
|
+
it "should return only connections from specified client" do
|
36
|
+
find(:to => {:clients => "client1"}).should eql([@connection1,@connection2])
|
37
|
+
end
|
38
|
+
it "should return only connections from specified clients if array provided" do
|
39
|
+
find(:to => {:clients => ["client1","client2"]}).should eql([@connection1,@connection2,@connection3])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
context "if :channels option is specified" do
|
43
|
+
it "should return all connections if :channels is nil" do
|
44
|
+
find(:to => {:channels => nil}).should eql(@connections)
|
45
|
+
end
|
46
|
+
it "should return none connections if :channels is empty" do
|
47
|
+
find(:to => {:channels => []}).should eql([])
|
48
|
+
end
|
49
|
+
it "should return all connections that include specified channel" do
|
50
|
+
find(:to => {:channels => "3"}).should eql([@connection2,@connection4])
|
51
|
+
end
|
52
|
+
it "should return all connections that include at last one of specified channels" do
|
53
|
+
find(:to => {:channels => ["2","3"]}).should eql([@connection2,@connection3,@connection4])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
context "if both :clients and :channels options are provided" do
|
57
|
+
context "but :channels are nil" do
|
58
|
+
it "should return only connections from specified client" do
|
59
|
+
find(:to => {:channels => nil,:clients => "client1"}).should eql([@connection1,@connection2])
|
60
|
+
end
|
61
|
+
it "should return only connections from specified clients if array provided" do
|
62
|
+
find(:to => {:channels => nil,:clients => ["client1","client2"]}).should eql([@connection1,@connection2,@connection3])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
context "but :channels are empty" do
|
66
|
+
it "should return none connections" do
|
67
|
+
find(:to => {:channels => [],:clients => "client1"}).should eql([])
|
68
|
+
end
|
69
|
+
it "should return none connections if array provided" do
|
70
|
+
find(:to => {:channels => [],:clients => ["client1","client2"]}).should eql([])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
context "but :clients are nil" do
|
74
|
+
it "should return all connections that include specified channel" do
|
75
|
+
find(:to => {:clients => nil,:channels => "3"}).should eql([@connection2,@connection4])
|
76
|
+
end
|
77
|
+
it "should return all connections that include at last one of specified channels" do
|
78
|
+
find(:to => {:clients => nil,:channels => ["2","3"]}).should eql([@connection2,@connection3,@connection4])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
context "but :clients are empty" do
|
82
|
+
it "should return none connections" do
|
83
|
+
find(:to => {:clients => [],:channels => "3"}).should eql([])
|
84
|
+
end
|
85
|
+
it "should return none connections if array provided" do
|
86
|
+
find(:to => {:clients => [],:channels => ["2","3"]}).should eql([])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
it "should return only connections from specified client that include specified channel" do
|
90
|
+
find(:to => {:clients => "client1",:channels => "3"}).should eql([@connection2])
|
91
|
+
find(:to => {:clients => "client1",:channels => "2"}).should eql([])
|
92
|
+
end
|
93
|
+
it "should return only connections from specified client that include one of specified channels" do
|
94
|
+
find(:to => {:clients => "client1",:channels => ["2","3"]}).should eql([@connection2])
|
95
|
+
end
|
96
|
+
it "should return only connections from specified clients that include specified channel" do
|
97
|
+
find(:to => {:clients => ["client1","client2"],:channels => "2"}).should eql([@connection3])
|
98
|
+
end
|
99
|
+
it "should return only connections from specified clients that include at last one of specified channels" do
|
100
|
+
find(:to => {:clients => ["client1","client2"],:channels => ["2","1"]}).should eql([@connection2,@connection3])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "on :except" do
|
106
|
+
context "if :clients option is specified" do
|
107
|
+
it "should return all connections if :clients is nil" do
|
108
|
+
find(:except => {:clients => nil}).should eql(@connections)
|
109
|
+
end
|
110
|
+
it "should return all connections if :clients is empty" do
|
111
|
+
find(:except => {:clients => []}).should eql(@connections)
|
112
|
+
end
|
113
|
+
it "should return all connections except of specified client" do
|
114
|
+
find(:except => {:clients => "client1"}).should eql([@connection3,@connection4])
|
115
|
+
end
|
116
|
+
it "should return all connections except of specified clients if array provided" do
|
117
|
+
find(:except => {:clients => ["client1","client2"]}).should eql([@connection4])
|
118
|
+
end
|
119
|
+
end
|
120
|
+
context "if :channels option is specified" do
|
121
|
+
it "should return all connections if :channels is nil" do
|
122
|
+
find(:except => {:channels => nil}).should eql(@connections)
|
123
|
+
end
|
124
|
+
it "should return all connections if :channels is empty" do
|
125
|
+
find(:except => {:channels => []}).should eql(@connections)
|
126
|
+
end
|
127
|
+
it "should return all connections except of that include all specified channels" do
|
128
|
+
find(:except => {:channels => ["2","5"]}).should eql([@connection1,@connection2,@connection4])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
context "if both :clients and :channels options are provided" do
|
132
|
+
context "but :channels are nil" do
|
133
|
+
it "should return all connections except of specified client" do
|
134
|
+
find(:except => {:channels => nil,:clients => "client1"}).should eql([@connection3,@connection4])
|
135
|
+
end
|
136
|
+
it "should return all connections except of specified clients if array provided" do
|
137
|
+
find(:except => {:channels => nil,:clients => ["client1","client2"]}).should eql([@connection4])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
context "but :channels are empty" do
|
141
|
+
it "should return all connections except of specified client" do
|
142
|
+
find(:except => {:channels => [],:clients => "client1"}).should eql([@connection3,@connection4])
|
143
|
+
end
|
144
|
+
it "should return all connections except of provided clients if array provided" do
|
145
|
+
find(:except => {:channels => [],:clients => ["client1","client2"]}).should eql([@connection4])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
context "but :clients are nil" do
|
149
|
+
it "should return all connections except of that include all of specified channels" do
|
150
|
+
find(:except => {:clients => nil,:channels => ["2","5"]}).should eql([@connection1,@connection2,@connection4])
|
151
|
+
end
|
152
|
+
end
|
153
|
+
context "but :clients are empty" do
|
154
|
+
it "should return all connections except of that include all of specified channels " do
|
155
|
+
find(:except => {:clients => [],:channels => ["2","5"]}).should eql([@connection1,@connection2,@connection4])
|
156
|
+
end
|
157
|
+
end
|
158
|
+
it "should return all connections except of specified client or all specified channels" do
|
159
|
+
find(:except => {:clients => "client2",:channels => "3"}).should eql([@connection1,@connection2,@connection4])
|
160
|
+
find(:except => {:clients => "client2",:channels => ["3","5"]}).should eql([@connection1,@connection2])
|
161
|
+
end
|
162
|
+
it "should return only connections from specified clients that include specified channel" do
|
163
|
+
find(:except => {:clients => ["client1","client2"],:channels => "3"}).should eql([@connection4])
|
164
|
+
find(:except => {:clients => ["client1","client2"],:channels => ["3","5"]}).should eql([])
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "on :to and :except" do
|
170
|
+
context "should value 'except' more that 'to'" do
|
171
|
+
it "on :client" do
|
172
|
+
find(:to => {:clients => "client1"},:except => {:clients => "client1"}).should eql([])
|
173
|
+
end
|
174
|
+
it "on :channels" do
|
175
|
+
find(:to => {:channels => "5"},:except => {:channels => "5"}).should eql([])
|
176
|
+
end
|
177
|
+
it "on :client allow and :channels except" do
|
178
|
+
find(:to => {:clients => "client2"},:except => {:channels => ["2","5"]}).should eql([])
|
179
|
+
end
|
180
|
+
it "on :channels allow and :clients except" do
|
181
|
+
find(:to => {:channels => ["5"]},:except => {:clients => "client2"}).should eql([@connection2,@connection4])
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|