adhearsion 2.4.0 → 2.5.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/CHANGELOG.md +29 -0
- data/Gemfile +0 -2
- data/Guardfile +2 -2
- data/README.markdown +3 -6
- data/Rakefile +1 -1
- data/adhearsion.gemspec +7 -2
- data/features/cli_create.feature +85 -7
- data/features/plugin_generator.feature +4 -0
- data/features/step_definitions/app_generator_steps.rb +8 -1
- data/lib/adhearsion.rb +6 -3
- data/lib/adhearsion/call.rb +101 -30
- data/lib/adhearsion/call_controller.rb +40 -12
- data/lib/adhearsion/call_controller/dial.rb +119 -36
- data/lib/adhearsion/call_controller/input.rb +11 -5
- data/lib/adhearsion/call_controller/output.rb +47 -33
- data/lib/adhearsion/call_controller/output/async_player.rb +3 -2
- data/lib/adhearsion/call_controller/output/formatter.rb +7 -2
- data/lib/adhearsion/call_controller/output/player.rb +2 -2
- data/lib/adhearsion/call_controller/record.rb +16 -13
- data/lib/adhearsion/call_controller/utility.rb +3 -3
- data/lib/adhearsion/calls.rb +21 -8
- data/lib/adhearsion/cli_commands/ahn_command.rb +1 -0
- data/lib/adhearsion/configuration.rb +2 -2
- data/lib/adhearsion/console.rb +3 -2
- data/lib/adhearsion/generators.rb +7 -9
- data/lib/adhearsion/generators/app/app_generator.rb +12 -2
- data/lib/adhearsion/generators/app/templates/Gemfile.erb +7 -9
- data/lib/adhearsion/generators/app/templates/README.md +0 -19
- data/lib/adhearsion/generators/app/templates/adhearsion.erb +37 -0
- data/lib/adhearsion/generators/app/templates/config/environment.rb +6 -1
- data/lib/adhearsion/generators/app/templates/events.erb +18 -0
- data/lib/adhearsion/generators/app/templates/routes.erb +19 -0
- data/lib/adhearsion/generators/app/templates/{lib/simon_game.rb → simon_game.rb} +0 -0
- data/lib/adhearsion/generators/app/templates/{spec/call_controllers/simon_game_spec.rb → simon_game_spec.rb} +0 -0
- data/lib/adhearsion/generators/controller/controller_generator.rb +2 -2
- data/lib/adhearsion/generators/controller/templates/lib/{controller.rb → controller.rb.erb} +0 -0
- data/lib/adhearsion/generators/controller/templates/spec/{controller_spec.rb → controller_spec.rb.erb} +0 -0
- data/lib/adhearsion/generators/plugin/plugin_generator.rb +16 -15
- data/lib/adhearsion/generators/plugin/templates/gitignore +17 -0
- data/lib/adhearsion/generators/plugin/templates/spec/plugin-template/controller_methods_spec.rb.tt +1 -1
- data/lib/adhearsion/initializer.rb +14 -2
- data/lib/adhearsion/logging.rb +1 -0
- data/lib/adhearsion/outbound_call.rb +3 -7
- data/lib/adhearsion/punchblock_plugin/initializer.rb +3 -2
- data/lib/adhearsion/router/openended_route.rb +1 -1
- data/lib/adhearsion/router/route.rb +4 -3
- data/lib/adhearsion/version.rb +1 -1
- data/spec/adhearsion/call_controller/dial_spec.rb +811 -79
- data/spec/adhearsion/call_controller/output/formatter_spec.rb +13 -1
- data/spec/adhearsion/call_controller/output_spec.rb +35 -1
- data/spec/adhearsion/call_controller_spec.rb +174 -18
- data/spec/adhearsion/call_spec.rb +423 -39
- data/spec/adhearsion/calls_spec.rb +19 -3
- data/spec/adhearsion/outbound_call_spec.rb +88 -45
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +3 -3
- data/spec/adhearsion/router/route_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -0
- metadata +92 -77
- data/features/app_generator.feature +0 -49
- data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +0 -71
- data/lib/adhearsion/generators/plugin/templates/.gitignore +0 -9
@@ -24,15 +24,17 @@ module Adhearsion
|
|
24
24
|
end
|
25
25
|
|
26
26
|
describe "#ssml_for_collection" do
|
27
|
-
let(:collection) { ["/foo/bar.wav", 1, Time.now] }
|
27
|
+
let(:collection) { ["/foo/bar.wav", 1, Time.now, '123*'] }
|
28
28
|
let :ssml do
|
29
29
|
file = collection[0]
|
30
30
|
n = collection[1].to_s
|
31
31
|
t = collection[2].to_s
|
32
|
+
c = collection[3].to_s
|
32
33
|
RubySpeech::SSML.draw do
|
33
34
|
audio :src => file
|
34
35
|
say_as(:interpret_as => 'cardinal') { n }
|
35
36
|
say_as(:interpret_as => 'time') { t }
|
37
|
+
say_as(:interpret_as => 'characters') { c }
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
@@ -78,6 +80,16 @@ module Adhearsion
|
|
78
80
|
subject.detect_type(number).should be :numeric
|
79
81
|
end
|
80
82
|
|
83
|
+
it "detects a String of digits" do
|
84
|
+
number = '123'
|
85
|
+
subject.detect_type(number).should be :numeric
|
86
|
+
end
|
87
|
+
|
88
|
+
it "detects a String of characters" do
|
89
|
+
number = '123#'
|
90
|
+
subject.detect_type(number).should be :characters
|
91
|
+
end
|
92
|
+
|
81
93
|
["Foo", "Foo bar", "The answer: foo", "The answer could be foo/bar"].each do |string|
|
82
94
|
it "detects '#{string}' as text" do
|
83
95
|
subject.detect_type(string).should be :text
|
@@ -338,6 +338,13 @@ module Adhearsion
|
|
338
338
|
let(:extra_options) do
|
339
339
|
{ renderer: :native }
|
340
340
|
end
|
341
|
+
|
342
|
+
describe "with a nil argument" do
|
343
|
+
it "is a noop" do
|
344
|
+
subject.play nil
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
341
348
|
describe "with a single string" do
|
342
349
|
let(:audio_file) { "/foo/bar.wav" }
|
343
350
|
let :ssml do
|
@@ -357,15 +364,17 @@ module Adhearsion
|
|
357
364
|
end
|
358
365
|
|
359
366
|
describe "with multiple arguments" do
|
360
|
-
let(:args) { ["/foo/bar.wav", 1, Time.now] }
|
367
|
+
let(:args) { ["/foo/bar.wav", 1, Time.now, "123#"] }
|
361
368
|
let :ssml do
|
362
369
|
file = args[0]
|
363
370
|
n = args[1].to_s
|
364
371
|
t = args[2].to_s
|
372
|
+
c = args[3].to_s
|
365
373
|
RubySpeech::SSML.draw do
|
366
374
|
audio :src => file
|
367
375
|
say_as(:interpret_as => 'cardinal') { n }
|
368
376
|
say_as(:interpret_as => 'time') { t }
|
377
|
+
say_as(:interpret_as => 'characters') { c }
|
369
378
|
end
|
370
379
|
end
|
371
380
|
|
@@ -398,6 +407,12 @@ module Adhearsion
|
|
398
407
|
expect_ssml_output ssml
|
399
408
|
subject.play(args).should be true
|
400
409
|
end
|
410
|
+
|
411
|
+
context "that is empty" do
|
412
|
+
it "is a noop" do
|
413
|
+
subject.play []
|
414
|
+
end
|
415
|
+
end
|
401
416
|
end
|
402
417
|
|
403
418
|
describe "with a number" do
|
@@ -496,6 +511,13 @@ module Adhearsion
|
|
496
511
|
let(:extra_options) do
|
497
512
|
{ renderer: :native }
|
498
513
|
end
|
514
|
+
|
515
|
+
describe "with a nil argument" do
|
516
|
+
it "is a noop" do
|
517
|
+
subject.play! nil
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
499
521
|
describe "with a single string" do
|
500
522
|
let(:audio_file) { "/foo/bar.wav" }
|
501
523
|
let :ssml do
|
@@ -731,6 +753,12 @@ module Adhearsion
|
|
731
753
|
end
|
732
754
|
|
733
755
|
describe "#say" do
|
756
|
+
describe "with a nil argument" do
|
757
|
+
it "is a no-op" do
|
758
|
+
subject.say nil
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
734
762
|
describe "with a RubySpeech document" do
|
735
763
|
it 'plays the correct SSML' do
|
736
764
|
ssml = RubySpeech::SSML.draw { string "Hello world" }
|
@@ -829,6 +857,12 @@ module Adhearsion
|
|
829
857
|
end
|
830
858
|
|
831
859
|
describe "#say!" do
|
860
|
+
describe "with a nil argument" do
|
861
|
+
it "is a noop" do
|
862
|
+
subject.say! nil
|
863
|
+
end
|
864
|
+
end
|
865
|
+
|
832
866
|
describe "with a RubySpeech document" do
|
833
867
|
it 'plays the correct SSML' do
|
834
868
|
ssml = RubySpeech::SSML.draw { string "Hello world" }
|
@@ -28,6 +28,13 @@ module Adhearsion
|
|
28
28
|
its(:logger) { should be call.logger }
|
29
29
|
its(:variables) { should be call.variables }
|
30
30
|
|
31
|
+
describe "#send_message" do
|
32
|
+
it 'should send a message' do
|
33
|
+
call.should_receive(:send_message).with("Hello World!").once
|
34
|
+
subject.send_message "Hello World!"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
31
38
|
context "when the call is dead" do
|
32
39
|
before { call.terminate }
|
33
40
|
|
@@ -49,6 +56,17 @@ module Adhearsion
|
|
49
56
|
subject.execute!
|
50
57
|
end
|
51
58
|
|
59
|
+
context "when trying to execute a command against a dead call" do
|
60
|
+
before do
|
61
|
+
subject.should_receive(:run).once.ordered.and_raise(Call::ExpiredError)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "gracefully terminates " do
|
65
|
+
subject.logger.should_receive(:info).once.with(/Call was hung up/).ordered
|
66
|
+
subject.execute!
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
52
70
|
it "catches standard errors, triggering an exception event" do
|
53
71
|
subject.should_receive(:run).once.ordered.and_raise(StandardError)
|
54
72
|
latch = CountDownLatch.new 1
|
@@ -165,26 +183,28 @@ module Adhearsion
|
|
165
183
|
end
|
166
184
|
|
167
185
|
describe "#pass" do
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
186
|
+
let(:pass_controller) do
|
187
|
+
Class.new CallController do
|
188
|
+
after_call :foobar
|
189
|
+
|
190
|
+
def run
|
191
|
+
before
|
192
|
+
pass SecondController, :foo => 'bar'
|
193
|
+
after
|
194
|
+
end
|
176
195
|
|
177
|
-
|
178
|
-
|
196
|
+
def before
|
197
|
+
end
|
179
198
|
|
180
|
-
|
181
|
-
|
199
|
+
def after
|
200
|
+
end
|
182
201
|
|
183
|
-
|
202
|
+
def foobar
|
203
|
+
end
|
184
204
|
end
|
185
205
|
end
|
186
206
|
|
187
|
-
subject {
|
207
|
+
subject { pass_controller.new call }
|
188
208
|
|
189
209
|
before do
|
190
210
|
call.wrapped_object.stub :write_and_await_response => nil
|
@@ -211,6 +231,142 @@ module Adhearsion
|
|
211
231
|
end
|
212
232
|
end
|
213
233
|
|
234
|
+
describe "#hard_pass" do
|
235
|
+
let(:pass_controller) do
|
236
|
+
Class.new CallController do
|
237
|
+
def run
|
238
|
+
hard_pass SecondController, foo: 'bar'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
subject { pass_controller.new call }
|
244
|
+
|
245
|
+
before do
|
246
|
+
call.wrapped_object.stub(:write_and_await_response).and_return do |command|
|
247
|
+
command.request!
|
248
|
+
command.execute!
|
249
|
+
end
|
250
|
+
call.stub register_controller: nil
|
251
|
+
SecondController.any_instance.should_receive(:md_check).once.with :foo => 'bar'
|
252
|
+
Events.should_receive(:trigger).with(:exception, Exception).never
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should cease execution of the current controller, and instruct the call to execute another" do
|
256
|
+
call.should_receive(:answer).once.ordered
|
257
|
+
|
258
|
+
subject.exec
|
259
|
+
end
|
260
|
+
|
261
|
+
context "when components have been executed on the controller" do
|
262
|
+
let(:pass_controller) do
|
263
|
+
Class.new CallController do
|
264
|
+
attr_accessor :output1, :output2
|
265
|
+
|
266
|
+
def prep_output
|
267
|
+
@output1 = play! 'file://foo.wav'
|
268
|
+
@output2 = play! 'file://bar.wav'
|
269
|
+
end
|
270
|
+
|
271
|
+
def run
|
272
|
+
hard_pass SecondController, foo: 'bar'
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
before { subject.prep_output }
|
278
|
+
|
279
|
+
context "but not yet received a complete event" do
|
280
|
+
it "should terminate the components" do
|
281
|
+
subject.output1.should_receive(:stop!).once
|
282
|
+
subject.output2.should_receive(:stop!).once
|
283
|
+
|
284
|
+
subject.exec
|
285
|
+
end
|
286
|
+
|
287
|
+
context "and some fail to terminate" do
|
288
|
+
before { subject.output1.should_receive(:stop!).and_raise(Punchblock::Component::InvalidActionError) }
|
289
|
+
|
290
|
+
it "should terminate the others" do
|
291
|
+
subject.output2.should_receive(:stop!).once
|
292
|
+
subject.exec
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
context "when some have completed" do
|
298
|
+
before { subject.output1.trigger_event_handler Punchblock::Event::Complete.new }
|
299
|
+
|
300
|
+
it "should not terminate the completed components" do
|
301
|
+
subject.output1.should_receive(:stop!).never
|
302
|
+
subject.output2.should_receive(:stop!).once
|
303
|
+
|
304
|
+
subject.exec
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe '#stop_all_components' do
|
311
|
+
let(:stop_controller) do
|
312
|
+
Class.new CallController do
|
313
|
+
attr_accessor :output1, :output2
|
314
|
+
|
315
|
+
def prep_output
|
316
|
+
@output1 = play! 'file://foo.wav'
|
317
|
+
@output2 = play! 'file://bar.wav'
|
318
|
+
end
|
319
|
+
|
320
|
+
def run
|
321
|
+
stop_all_components
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
subject { stop_controller.new call }
|
327
|
+
|
328
|
+
context "when components have been executed on the controller" do
|
329
|
+
before do
|
330
|
+
call.wrapped_object.stub(:write_and_await_response).and_return do |command|
|
331
|
+
command.request!
|
332
|
+
command.execute!
|
333
|
+
end
|
334
|
+
call.stub register_controller: nil
|
335
|
+
Events.should_receive(:trigger).with(:exception, Exception).never
|
336
|
+
subject.prep_output
|
337
|
+
end
|
338
|
+
|
339
|
+
context "when they have not yet received a complete event" do
|
340
|
+
it "should terminate the components" do
|
341
|
+
subject.output1.should_receive(:stop!).once
|
342
|
+
subject.output2.should_receive(:stop!).once
|
343
|
+
|
344
|
+
subject.exec
|
345
|
+
end
|
346
|
+
|
347
|
+
context "and some fail to terminate" do
|
348
|
+
before { subject.output1.should_receive(:stop!).and_raise(Punchblock::Component::InvalidActionError) }
|
349
|
+
|
350
|
+
it "should terminate the others" do
|
351
|
+
subject.output2.should_receive(:stop!).once
|
352
|
+
subject.exec
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
context "when some have completed" do
|
358
|
+
before { subject.output1.trigger_event_handler Punchblock::Event::Complete.new }
|
359
|
+
|
360
|
+
it "should not terminate the completed components" do
|
361
|
+
subject.output1.should_receive(:stop!).never
|
362
|
+
subject.output2.should_receive(:stop!).once
|
363
|
+
|
364
|
+
subject.exec
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
214
370
|
describe "#write_and_await_response" do
|
215
371
|
let(:message) { Punchblock::Command::Accept.new }
|
216
372
|
|
@@ -249,7 +405,7 @@ module Adhearsion
|
|
249
405
|
describe "#join" do
|
250
406
|
it "delegates to the call, blocking first until it is allowed to execute, and unblocking when an unjoined event is received" do
|
251
407
|
subject.should_receive(:block_until_resumed).once.ordered
|
252
|
-
|
408
|
+
call.wrapped_object.should_receive(:write_and_await_response).once.ordered.with(Punchblock::Command::Join.new(call_uri: 'call1'))
|
253
409
|
latch = CountDownLatch.new 1
|
254
410
|
Thread.new do
|
255
411
|
subject.join 'call1', :foo => :bar
|
@@ -265,7 +421,7 @@ module Adhearsion
|
|
265
421
|
context "with a mixer" do
|
266
422
|
it "delegates to the call, blocking first until it is allowed to execute, and unblocking when an unjoined event is received" do
|
267
423
|
subject.should_receive(:block_until_resumed).once.ordered
|
268
|
-
|
424
|
+
call.wrapped_object.should_receive(:write_and_await_response).once.ordered.with(Punchblock::Command::Join.new(mixer_name: 'foobar'))
|
269
425
|
latch = CountDownLatch.new 1
|
270
426
|
Thread.new do
|
271
427
|
subject.join :mixer_name => 'foobar', :foo => :bar
|
@@ -282,7 +438,7 @@ module Adhearsion
|
|
282
438
|
context "with :async => true" do
|
283
439
|
it "delegates to the call, blocking first until it is allowed to execute, and unblocking when the joined event is received" do
|
284
440
|
subject.should_receive(:block_until_resumed).once.ordered
|
285
|
-
|
441
|
+
call.wrapped_object.should_receive(:write_and_await_response).once.ordered.with(Punchblock::Command::Join.new(call_uri: 'call1'))
|
286
442
|
latch = CountDownLatch.new 1
|
287
443
|
Thread.new do
|
288
444
|
subject.join 'call1', :foo => :bar, :async => true
|
@@ -296,7 +452,7 @@ module Adhearsion
|
|
296
452
|
context "with a mixer" do
|
297
453
|
it "delegates to the call, blocking first until it is allowed to execute, and unblocking when the joined event is received" do
|
298
454
|
subject.should_receive(:block_until_resumed).once.ordered
|
299
|
-
|
455
|
+
call.wrapped_object.should_receive(:write_and_await_response).once.ordered.with(Punchblock::Command::Join.new(mixer_name: 'foobar'))
|
300
456
|
latch = CountDownLatch.new 1
|
301
457
|
Thread.new do
|
302
458
|
subject.join :mixer_name => 'foobar', :foo => :bar, :async => true
|
@@ -37,6 +37,20 @@ module Adhearsion
|
|
37
37
|
Adhearsion.active_calls.clear
|
38
38
|
end
|
39
39
|
|
40
|
+
it "should do recursion detection on inspect" do
|
41
|
+
subject[:foo] = subject
|
42
|
+
Timeout.timeout(0.2) do
|
43
|
+
expect(subject.inspect).to match('...')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should allow timers to be registered from outside" do
|
48
|
+
foo = :bar
|
49
|
+
subject.after(1) { foo = :baz }
|
50
|
+
sleep 1.1
|
51
|
+
foo.should == :baz
|
52
|
+
end
|
53
|
+
|
40
54
|
it { should respond_to :<< }
|
41
55
|
|
42
56
|
its(:end_reason) { should be == nil }
|
@@ -50,6 +64,8 @@ module Adhearsion
|
|
50
64
|
its(:to) { should be == to }
|
51
65
|
its(:from) { should be == from }
|
52
66
|
|
67
|
+
its(:auto_hangup) { should be_true }
|
68
|
+
|
53
69
|
context "when the ID is nil" do
|
54
70
|
let(:call_id) { nil }
|
55
71
|
|
@@ -141,28 +157,52 @@ module Adhearsion
|
|
141
157
|
end
|
142
158
|
end
|
143
159
|
|
144
|
-
|
145
|
-
event
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
160
|
+
context 'registered event handlers' do
|
161
|
+
let(:event) { double 'Event' }
|
162
|
+
let(:response) { double 'Response' }
|
163
|
+
|
164
|
+
it 'are called when messages are delivered' do
|
165
|
+
event.should_receive(:foo?).and_return true
|
166
|
+
response.should_receive(:call).once
|
167
|
+
subject.register_event_handler(:foo?) { response.call }
|
168
|
+
subject << event
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'when a handler raises' do
|
172
|
+
it 'does not cause the call actor to crash' do
|
173
|
+
subject.register_event_handler { raise 'Boom' }
|
174
|
+
subject << event
|
175
|
+
subject.should be_alive
|
176
|
+
end
|
177
|
+
|
178
|
+
it "triggers an exception event" do
|
179
|
+
e = StandardError.new('Boom')
|
180
|
+
Events.should_receive(:trigger).once.with(:exception, [e, subject.logger])
|
181
|
+
subject.register_event_handler { raise e }
|
182
|
+
subject << event
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'executes all handlers for each event' do
|
186
|
+
response.should_receive(:call).once
|
187
|
+
subject.register_event_handler { raise 'Boom' }
|
188
|
+
subject.register_event_handler { response.call }
|
189
|
+
subject << event
|
190
|
+
end
|
191
|
+
end
|
151
192
|
end
|
152
193
|
|
153
194
|
describe "event handlers" do
|
154
|
-
before { pending }
|
155
195
|
let(:response) { double 'Response' }
|
156
196
|
|
157
197
|
describe "for joined events" do
|
158
198
|
context "joined to another call" do
|
159
199
|
let :event do
|
160
|
-
Punchblock::Event::Joined.new call_uri: '
|
200
|
+
Punchblock::Event::Joined.new call_uri: 'footransport:foobar@rayo.net'
|
161
201
|
end
|
162
202
|
|
163
203
|
it "should trigger any on_joined callbacks set for the matching call ID" do
|
164
204
|
response.should_receive(:call).once.with(event)
|
165
|
-
subject.on_joined(:call_uri => '
|
205
|
+
subject.on_joined(:call_uri => 'footransport:foobar@rayo.net') { |event| response.call event }
|
166
206
|
subject << event
|
167
207
|
end
|
168
208
|
|
@@ -175,14 +215,14 @@ module Adhearsion
|
|
175
215
|
it "should trigger any on_joined callbacks set for the matching call" do
|
176
216
|
response.should_receive(:call).once.with(event)
|
177
217
|
call = Call.new
|
178
|
-
call.wrapped_object.stub id: 'foobar', domain: 'rayo.net'
|
218
|
+
call.wrapped_object.stub id: 'foobar', domain: 'rayo.net', transport: 'footransport'
|
179
219
|
subject.on_joined(call) { |event| response.call event }
|
180
220
|
subject << event
|
181
221
|
end
|
182
222
|
|
183
223
|
it "should not trigger on_joined callbacks for other call IDs" do
|
184
224
|
response.should_receive(:call).never
|
185
|
-
subject.on_joined(:
|
225
|
+
subject.on_joined(:call_uri => 'barfoo') { |event| response.call event }
|
186
226
|
subject << event
|
187
227
|
end
|
188
228
|
|
@@ -212,7 +252,7 @@ module Adhearsion
|
|
212
252
|
|
213
253
|
it "should not trigger any on_joined callbacks set for calls" do
|
214
254
|
response.should_receive(:call).never
|
215
|
-
subject.on_joined(:
|
255
|
+
subject.on_joined(:call_uri => 'foobar') { |event| response.call event }
|
216
256
|
subject << event
|
217
257
|
end
|
218
258
|
|
@@ -225,7 +265,7 @@ module Adhearsion
|
|
225
265
|
it "should not trigger any on_joined callbacks set for the matching call" do
|
226
266
|
response.should_receive(:call).never
|
227
267
|
call = Call.new
|
228
|
-
call.stub :id => 'foobar'
|
268
|
+
call.wrapped_object.stub :id => 'foobar'
|
229
269
|
subject.on_joined(call) { |event| response.call event }
|
230
270
|
subject << event
|
231
271
|
end
|
@@ -235,12 +275,12 @@ module Adhearsion
|
|
235
275
|
describe "for unjoined events" do
|
236
276
|
context "unjoined from another call" do
|
237
277
|
let :event do
|
238
|
-
Punchblock::Event::Unjoined.new call_uri: '
|
278
|
+
Punchblock::Event::Unjoined.new call_uri: 'footransport:foobar@rayo.net'
|
239
279
|
end
|
240
280
|
|
241
281
|
it "should trigger any on_unjoined callbacks set for the matching call ID" do
|
242
282
|
response.should_receive(:call).once.with(event)
|
243
|
-
subject.on_unjoined(:call_uri => '
|
283
|
+
subject.on_unjoined(:call_uri => 'footransport:foobar@rayo.net') { |event| response.call event }
|
244
284
|
subject << event
|
245
285
|
end
|
246
286
|
|
@@ -253,14 +293,14 @@ module Adhearsion
|
|
253
293
|
it "should trigger any on_unjoined callbacks set for the matching call" do
|
254
294
|
response.should_receive(:call).once.with(event)
|
255
295
|
call = Call.new
|
256
|
-
call.wrapped_object.stub id: 'foobar', domain: 'rayo.net'
|
296
|
+
call.wrapped_object.stub id: 'foobar', domain: 'rayo.net', transport: 'footransport'
|
257
297
|
subject.on_unjoined(call) { |event| response.call event }
|
258
298
|
subject << event
|
259
299
|
end
|
260
300
|
|
261
301
|
it "should not trigger on_unjoined callbacks for other call IDs" do
|
262
302
|
response.should_receive(:call).never
|
263
|
-
subject.on_unjoined(:
|
303
|
+
subject.on_unjoined(:call_uri => 'barfoo') { |event| response.call event }
|
264
304
|
subject << event
|
265
305
|
end
|
266
306
|
|
@@ -290,7 +330,7 @@ module Adhearsion
|
|
290
330
|
|
291
331
|
it "should not trigger any on_unjoined callbacks set for calls" do
|
292
332
|
response.should_receive(:call).never
|
293
|
-
subject.on_unjoined(:
|
333
|
+
subject.on_unjoined(:call_uri => 'foobar') { |event| response.call event }
|
294
334
|
subject << event
|
295
335
|
end
|
296
336
|
|
@@ -303,7 +343,7 @@ module Adhearsion
|
|
303
343
|
it "should not trigger any on_unjoined callbacks set for the matching call" do
|
304
344
|
response.should_receive(:call).never
|
305
345
|
call = Call.new
|
306
|
-
call.stub :id => 'foobar'
|
346
|
+
call.wrapped_object.stub :id => 'foobar'
|
307
347
|
subject.on_unjoined(call) { |event| response.call event }
|
308
348
|
subject << event
|
309
349
|
end
|
@@ -346,54 +386,121 @@ module Adhearsion
|
|
346
386
|
end
|
347
387
|
|
348
388
|
context "peer registry" do
|
349
|
-
let(:
|
389
|
+
let(:other_call_uri) { 'xmpp:foobar@example.com' }
|
350
390
|
let(:other_call) { Call.new }
|
351
391
|
|
352
|
-
before { other_call.stub :
|
392
|
+
before { other_call.stub uri: other_call_uri }
|
353
393
|
|
354
394
|
let :joined_event do
|
355
|
-
Punchblock::Event::Joined.new call_uri:
|
395
|
+
Punchblock::Event::Joined.new call_uri: other_call_uri
|
356
396
|
end
|
357
397
|
|
358
398
|
let :unjoined_event do
|
359
|
-
Punchblock::Event::Unjoined.new call_uri:
|
399
|
+
Punchblock::Event::Unjoined.new call_uri: other_call_uri
|
360
400
|
end
|
361
401
|
|
362
402
|
context "when we know about the joined call" do
|
363
403
|
before { Adhearsion.active_calls << other_call }
|
404
|
+
after { Adhearsion.active_calls.remove_inactive_call other_call }
|
364
405
|
|
365
406
|
it "should add the peer to its registry" do
|
366
407
|
subject << joined_event
|
367
|
-
subject.peers.should == {'foobar' => other_call}
|
408
|
+
subject.peers.should == {'xmpp:foobar@example.com' => other_call}
|
409
|
+
end
|
410
|
+
|
411
|
+
context "in a handler for the joined event" do
|
412
|
+
it "should have already populated the registry" do
|
413
|
+
peer = nil
|
414
|
+
|
415
|
+
subject.on_joined do |event|
|
416
|
+
peer = subject.peers.keys.first
|
417
|
+
end
|
418
|
+
|
419
|
+
subject << joined_event
|
420
|
+
|
421
|
+
peer.should == other_call_uri
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
context "when being unjoined from a previously joined call" do
|
426
|
+
before { subject << joined_event }
|
427
|
+
|
428
|
+
it "should remove the peer from its registry" do
|
429
|
+
subject.peers.should_not eql({})
|
430
|
+
subject << unjoined_event
|
431
|
+
subject.peers.should eql({})
|
432
|
+
end
|
433
|
+
|
434
|
+
context "in a handler for the unjoined event" do
|
435
|
+
it "should have already been removed the registry" do
|
436
|
+
peer_count = nil
|
437
|
+
|
438
|
+
subject.on_unjoined do |event|
|
439
|
+
peer_count = subject.peers.size
|
440
|
+
end
|
441
|
+
|
442
|
+
subject << unjoined_event
|
443
|
+
|
444
|
+
peer_count.should == 0
|
445
|
+
end
|
446
|
+
end
|
368
447
|
end
|
369
448
|
end
|
370
449
|
|
371
450
|
context "when we don't know about the joined call" do
|
372
451
|
it "should add a nil entry to its registry" do
|
373
452
|
subject << joined_event
|
374
|
-
subject.peers.should == {'foobar' => nil}
|
453
|
+
subject.peers.should == {'xmpp:foobar@example.com' => nil}
|
375
454
|
end
|
376
|
-
end
|
377
455
|
|
378
|
-
|
379
|
-
|
380
|
-
|
456
|
+
context "in a handler for the joined event" do
|
457
|
+
it "should have already populated the registry" do
|
458
|
+
peer = nil
|
381
459
|
|
382
|
-
|
383
|
-
|
460
|
+
subject.on_joined do |event|
|
461
|
+
peer = subject.peers.keys.first
|
462
|
+
end
|
463
|
+
|
464
|
+
subject << joined_event
|
384
465
|
|
385
|
-
|
386
|
-
|
387
|
-
subject << unjoined_event
|
388
|
-
subject.peers.should eql({})
|
466
|
+
peer.should == other_call_uri
|
467
|
+
end
|
389
468
|
end
|
469
|
+
|
470
|
+
context "when being unjoined from a previously joined call" do
|
471
|
+
before { subject << joined_event }
|
472
|
+
|
473
|
+
it "should remove the peer from its registry" do
|
474
|
+
subject.peers.should_not eql({})
|
475
|
+
subject << unjoined_event
|
476
|
+
subject.peers.should eql({})
|
477
|
+
end
|
478
|
+
|
479
|
+
context "in a handler for the unjoined event" do
|
480
|
+
it "should have already been removed the registry" do
|
481
|
+
peer_count = nil
|
482
|
+
|
483
|
+
subject.on_unjoined do |event|
|
484
|
+
peer_count = subject.peers.size
|
485
|
+
end
|
486
|
+
|
487
|
+
subject << unjoined_event
|
488
|
+
|
489
|
+
peer_count.should == 0
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
it "should not return the same registry every call" do
|
496
|
+
subject.peers.should_not be subject.peers
|
390
497
|
end
|
391
498
|
end
|
392
499
|
|
393
500
|
describe "#<<" do
|
394
501
|
describe "with a Punchblock End" do
|
395
502
|
let :end_event do
|
396
|
-
Punchblock::Event::End.new :reason => :hangup
|
503
|
+
Punchblock::Event::End.new :reason => :hangup, :platform_code => 'arbitrary_code'
|
397
504
|
end
|
398
505
|
|
399
506
|
it "should mark the call as ended" do
|
@@ -406,6 +513,11 @@ module Adhearsion
|
|
406
513
|
subject.end_reason.should be == :hangup
|
407
514
|
end
|
408
515
|
|
516
|
+
it "should set the end code" do
|
517
|
+
subject << end_event
|
518
|
+
subject.end_code.should be == 'arbitrary_code'
|
519
|
+
end
|
520
|
+
|
409
521
|
it "should set the end time" do
|
410
522
|
finish_time = Time.local(2008, 9, 1, 12, 1, 3)
|
411
523
|
Timecop.freeze finish_time
|
@@ -654,6 +766,20 @@ module Adhearsion
|
|
654
766
|
end
|
655
767
|
end
|
656
768
|
|
769
|
+
describe "#send_message" do
|
770
|
+
it "should send a message through the Punchblock connection using the call ID and domain" do
|
771
|
+
subject.wrapped_object.should_receive(:client).once.and_return mock_client
|
772
|
+
mock_client.should_receive(:send_message).once.with(subject.id, subject.domain, "Hello World!", {})
|
773
|
+
subject.send_message "Hello World!"
|
774
|
+
end
|
775
|
+
|
776
|
+
it "should send a message with the given subject" do
|
777
|
+
subject.wrapped_object.should_receive(:client).once.and_return mock_client
|
778
|
+
mock_client.should_receive(:send_message).once.with(subject.id, subject.domain, nil, :subject => "Important Message")
|
779
|
+
subject.send_message nil, :subject => "Important Message"
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
657
783
|
describe "basic control commands" do
|
658
784
|
def expect_message_waiting_for_response(message = nil, fail = false, &block)
|
659
785
|
expectation = subject.wrapped_object.should_receive(:write_and_await_response, &block).once
|
@@ -810,26 +936,156 @@ module Adhearsion
|
|
810
936
|
subject.join target, :media => :bridge, :direction => :recv
|
811
937
|
end
|
812
938
|
end
|
939
|
+
|
940
|
+
it "should return the command" do
|
941
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
942
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
943
|
+
result[:command].should be_a Punchblock::Command::Join
|
944
|
+
result[:command].call_uri.should eql(uri)
|
945
|
+
result[:command].media.should eql(:bridge)
|
946
|
+
result[:command].direction.should eql(:recv)
|
947
|
+
end
|
948
|
+
|
949
|
+
it "should return something that can be blocked on until the join is complete" do
|
950
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
951
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
952
|
+
|
953
|
+
result[:joined_condition].wait(0.5).should be_false
|
954
|
+
|
955
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
956
|
+
result[:joined_condition].wait(0.5).should be_true
|
957
|
+
end
|
958
|
+
|
959
|
+
it "should return something that can be blocked on until the entities are unjoined" do
|
960
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
961
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
962
|
+
|
963
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
964
|
+
|
965
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
966
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
967
|
+
|
968
|
+
subject << Punchblock::Event::Unjoined.new(call_uri: uri)
|
969
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
970
|
+
end
|
971
|
+
|
972
|
+
it "should unblock all conditions on call end if no joined/unjoined events are received" do
|
973
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
974
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
975
|
+
|
976
|
+
result[:joined_condition].wait(0.5).should be_false
|
977
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
978
|
+
|
979
|
+
subject << Punchblock::Event::End.new
|
980
|
+
result[:joined_condition].wait(0.5).should be_true
|
981
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
982
|
+
end
|
983
|
+
|
984
|
+
it "should not error on call end when joined/unjoined events are received correctly" do
|
985
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
986
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
987
|
+
|
988
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
989
|
+
subject << Punchblock::Event::Unjoined.new(call_uri: uri)
|
990
|
+
|
991
|
+
subject << Punchblock::Event::End.new
|
992
|
+
end
|
993
|
+
|
994
|
+
it "should not error if multiple joined events are received for the same join" do
|
995
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
996
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
997
|
+
|
998
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
999
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1000
|
+
|
1001
|
+
subject.should be_alive
|
1002
|
+
end
|
813
1003
|
end
|
814
1004
|
|
815
1005
|
context "with a call ID" do
|
816
1006
|
let(:target) { rand.to_s }
|
1007
|
+
let(:uri) { "footransport:#{target}@#{subject.domain}" }
|
817
1008
|
|
818
1009
|
it "should send a join command joining to the provided call ID" do
|
819
|
-
expect_join_with_options call_uri:
|
1010
|
+
expect_join_with_options call_uri: uri
|
820
1011
|
subject.join target
|
821
1012
|
end
|
822
1013
|
|
823
1014
|
context "and direction/media options" do
|
824
1015
|
it "should send a join command with the correct options" do
|
825
|
-
expect_join_with_options :call_uri =>
|
1016
|
+
expect_join_with_options :call_uri => uri, :media => :bridge, :direction => :recv
|
826
1017
|
subject.join target, :media => :bridge, :direction => :recv
|
827
1018
|
end
|
828
1019
|
end
|
1020
|
+
|
1021
|
+
it "should return the command" do
|
1022
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1023
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
1024
|
+
result[:command].should be_a Punchblock::Command::Join
|
1025
|
+
result[:command].call_uri.should eql(uri)
|
1026
|
+
result[:command].media.should eql(:bridge)
|
1027
|
+
result[:command].direction.should eql(:recv)
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
it "should return something that can be blocked on until the join is complete" do
|
1031
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1032
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
1033
|
+
|
1034
|
+
result[:joined_condition].wait(0.5).should be_false
|
1035
|
+
|
1036
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1037
|
+
result[:joined_condition].wait(0.5).should be_true
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
it "should return something that can be blocked on until the entities are unjoined" do
|
1041
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1042
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
1043
|
+
|
1044
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1045
|
+
|
1046
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1047
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1048
|
+
|
1049
|
+
subject << Punchblock::Event::Unjoined.new(call_uri: uri)
|
1050
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
it "should unblock all conditions on call end if no joined/unjoined events are received" do
|
1054
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1055
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
1056
|
+
|
1057
|
+
result[:joined_condition].wait(0.5).should be_false
|
1058
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1059
|
+
|
1060
|
+
subject << Punchblock::Event::End.new
|
1061
|
+
result[:joined_condition].wait(0.5).should be_true
|
1062
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
it "should not error on call end when joined/unjoined events are received correctly" do
|
1066
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1067
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
1068
|
+
|
1069
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1070
|
+
subject << Punchblock::Event::Unjoined.new(call_uri: uri)
|
1071
|
+
|
1072
|
+
subject << Punchblock::Event::End.new
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
it "should not error if multiple joined events are received for the same join" do
|
1076
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1077
|
+
result = subject.join target, :media => :bridge, :direction => :recv
|
1078
|
+
|
1079
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1080
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1081
|
+
|
1082
|
+
subject.should be_alive
|
1083
|
+
end
|
829
1084
|
end
|
830
1085
|
|
831
1086
|
context "with a call URI as a hash key" do
|
832
1087
|
let(:call_id) { rand.to_s }
|
1088
|
+
let(:uri) { call_id }
|
833
1089
|
let(:target) { { :call_uri => call_id } }
|
834
1090
|
|
835
1091
|
it "should send a join command joining to the provided call ID" do
|
@@ -843,6 +1099,70 @@ module Adhearsion
|
|
843
1099
|
subject.join target.merge({:media => :bridge, :direction => :recv})
|
844
1100
|
end
|
845
1101
|
end
|
1102
|
+
|
1103
|
+
it "should return the command" do
|
1104
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1105
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1106
|
+
result[:command].should be_a Punchblock::Command::Join
|
1107
|
+
result[:command].call_uri.should eql(uri)
|
1108
|
+
result[:command].media.should eql(:bridge)
|
1109
|
+
result[:command].direction.should eql(:recv)
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
it "should return something that can be blocked on until the join is complete" do
|
1113
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1114
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1115
|
+
|
1116
|
+
result[:joined_condition].wait(0.5).should be_false
|
1117
|
+
|
1118
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1119
|
+
result[:joined_condition].wait(0.5).should be_true
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
it "should return something that can be blocked on until the entities are unjoined" do
|
1123
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1124
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1125
|
+
|
1126
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1127
|
+
|
1128
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1129
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1130
|
+
|
1131
|
+
subject << Punchblock::Event::Unjoined.new(call_uri: uri)
|
1132
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
it "should unblock all conditions on call end if no joined/unjoined events are received" do
|
1136
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1137
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1138
|
+
|
1139
|
+
result[:joined_condition].wait(0.5).should be_false
|
1140
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1141
|
+
|
1142
|
+
subject << Punchblock::Event::End.new
|
1143
|
+
result[:joined_condition].wait(0.5).should be_true
|
1144
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
it "should not error on call end when joined/unjoined events are received correctly" do
|
1148
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1149
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1150
|
+
|
1151
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1152
|
+
subject << Punchblock::Event::Unjoined.new(call_uri: uri)
|
1153
|
+
|
1154
|
+
subject << Punchblock::Event::End.new
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
it "should not error if multiple joined events are received for the same join" do
|
1158
|
+
expect_join_with_options :call_id => uri, :media => :bridge, :direction => :recv
|
1159
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1160
|
+
|
1161
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1162
|
+
subject << Punchblock::Event::Joined.new(call_uri: uri)
|
1163
|
+
|
1164
|
+
subject.should be_alive
|
1165
|
+
end
|
846
1166
|
end
|
847
1167
|
|
848
1168
|
context "with a mixer name as a hash key" do
|
@@ -860,6 +1180,70 @@ module Adhearsion
|
|
860
1180
|
subject.join target.merge({:media => :bridge, :direction => :recv})
|
861
1181
|
end
|
862
1182
|
end
|
1183
|
+
|
1184
|
+
it "should return the command" do
|
1185
|
+
expect_join_with_options :mixer_name => mixer_name, :media => :bridge, :direction => :recv
|
1186
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1187
|
+
result[:command].should be_a Punchblock::Command::Join
|
1188
|
+
result[:command].mixer_name.should eql(mixer_name)
|
1189
|
+
result[:command].media.should eql(:bridge)
|
1190
|
+
result[:command].direction.should eql(:recv)
|
1191
|
+
end
|
1192
|
+
|
1193
|
+
it "should return something that can be blocked on until the join is complete" do
|
1194
|
+
expect_join_with_options :mixer_name => mixer_name, :media => :bridge, :direction => :recv
|
1195
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1196
|
+
|
1197
|
+
result[:joined_condition].wait(0.5).should be_false
|
1198
|
+
|
1199
|
+
subject << Punchblock::Event::Joined.new(mixer_name: mixer_name)
|
1200
|
+
result[:joined_condition].wait(0.5).should be_true
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
it "should return something that can be blocked on until the entities are unjoined" do
|
1204
|
+
expect_join_with_options :mixer_name => mixer_name, :media => :bridge, :direction => :recv
|
1205
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1206
|
+
|
1207
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1208
|
+
|
1209
|
+
subject << Punchblock::Event::Joined.new(mixer_name: mixer_name)
|
1210
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1211
|
+
|
1212
|
+
subject << Punchblock::Event::Unjoined.new(mixer_name: mixer_name)
|
1213
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
it "should unblock all conditions on call end if no joined/unjoined events are received" do
|
1217
|
+
expect_join_with_options :mixer_name => mixer_name, :media => :bridge, :direction => :recv
|
1218
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1219
|
+
|
1220
|
+
result[:joined_condition].wait(0.5).should be_false
|
1221
|
+
result[:unjoined_condition].wait(0.5).should be_false
|
1222
|
+
|
1223
|
+
subject << Punchblock::Event::End.new
|
1224
|
+
result[:joined_condition].wait(0.5).should be_true
|
1225
|
+
result[:unjoined_condition].wait(0.5).should be_true
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
it "should not error on call end when joined/unjoined events are received correctly" do
|
1229
|
+
expect_join_with_options :mixer_name => mixer_name, :media => :bridge, :direction => :recv
|
1230
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1231
|
+
|
1232
|
+
subject << Punchblock::Event::Joined.new(mixer_name: mixer_name)
|
1233
|
+
subject << Punchblock::Event::Unjoined.new(mixer_name: mixer_name)
|
1234
|
+
|
1235
|
+
subject << Punchblock::Event::End.new
|
1236
|
+
end
|
1237
|
+
|
1238
|
+
it "should not error if multiple joined events are received for the same join" do
|
1239
|
+
expect_join_with_options :mixer_name => mixer_name, :media => :bridge, :direction => :recv
|
1240
|
+
result = subject.join target.merge({:media => :bridge, :direction => :recv})
|
1241
|
+
|
1242
|
+
subject << Punchblock::Event::Joined.new(mixer_name: mixer_name)
|
1243
|
+
subject << Punchblock::Event::Joined.new(mixer_name: mixer_name)
|
1244
|
+
|
1245
|
+
subject.should be_alive
|
1246
|
+
end
|
863
1247
|
end
|
864
1248
|
|
865
1249
|
context "with a call ID and a mixer name as hash keys" do
|