adhearsion-asterisk 0.1.2 → 0.1.3

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.
@@ -1,5 +1,5 @@
1
1
  module Adhearsion
2
2
  module Asterisk
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3"
4
4
  end
5
5
  end
@@ -0,0 +1,617 @@
1
+ require 'spec_helper'
2
+
3
+ module Adhearsion::Asterisk
4
+ describe CallControllerMethods do
5
+ describe "mixed in to a CallController" do
6
+
7
+ subject { Adhearsion::CallController.new mock('Call') }
8
+
9
+ before { Adhearsion::CallController.mixin CallControllerMethods }
10
+
11
+ describe '#agi' do
12
+ let :expected_agi_command do
13
+ Punchblock::Component::Asterisk::AGI::Command.new :name => 'Dial', :params => ['4044754842', 15]
14
+ end
15
+
16
+ let :complete_event do
17
+ Punchblock::Event::Complete.new.tap do |c|
18
+ c.reason = Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new :code => 200, :result => 1, :data => 'foobar'
19
+ end
20
+ end
21
+
22
+ it 'should execute an AGI command with the specified name and parameters and return the response code, response and data' do
23
+ Punchblock::Component::Asterisk::AGI::Command.any_instance.stubs :complete_event => complete_event
24
+
25
+ subject.expects(:execute_component_and_await_completion).once.with expected_agi_command
26
+ values = subject.agi 'Dial', '4044754842', 15
27
+ values.should == [200, 1, 'foobar']
28
+ end
29
+ end
30
+
31
+ describe '#execute' do
32
+ it 'calls #agi and prefixes the command with EXEC' do
33
+ subject.expects(:agi).once.with 'EXEC Dial', '4044754842', 15
34
+ subject.execute 'Dial', '4044754842', 15
35
+ end
36
+ end
37
+
38
+ describe '#verbose' do
39
+ it 'executes the VERBOSE AGI command' do
40
+ subject.expects(:agi).once.with 'VERBOSE', 'Foo Bar!', 15
41
+ subject.verbose 'Foo Bar!', 15
42
+ end
43
+ end
44
+
45
+ describe '#enable_feature' do
46
+ it 'it should fetch the variable for DYNAMIC_FEATURES at first' do
47
+ subject.expects(:variable).once.with("DYNAMIC_FEATURES").throws(:got_variable)
48
+ expect {
49
+ subject.enable_feature :foobar
50
+ }.to throw_symbol :got_variable
51
+ end
52
+
53
+ it 'should check Adhearsion::Asterisk::Plugin::DYNAMIC_FEATURE_EXTENSIONS mapping for configuration setters' do
54
+ feature_name = :attended_transfer
55
+
56
+ assertion = lambda do |arg|
57
+ arg.should == :this_is_the_right_arg
58
+ throw :inside_assertion!
59
+ end
60
+
61
+ # I had to do this ugly hack because of a bug in Flexmock which prevented me from mocking out Hash#[] :(
62
+ # FIXME: mock Hash
63
+ # ...DYNAMIC_FEATURE_EXTENSIONS.expects(feature_name => assertion)
64
+
65
+ old_hash_feature_extension = Adhearsion::Asterisk::CallControllerMethods::DYNAMIC_FEATURE_EXTENSIONS[feature_name]
66
+ begin
67
+ Adhearsion::Asterisk::CallControllerMethods::DYNAMIC_FEATURE_EXTENSIONS[feature_name] = assertion
68
+
69
+ subject.expects(:enable_feature).once.with(feature_name, :this_is_the_right_arg).throws :inside_assertion!
70
+ expect { subject.enable_feature(feature_name, :this_is_the_right_arg)}.to throw_symbol :inside_assertion!
71
+ ensure
72
+ Adhearsion::Asterisk::CallControllerMethods::DYNAMIC_FEATURE_EXTENSIONS[feature_name] = old_hash_feature_extension
73
+ end
74
+ end
75
+
76
+ it 'should separate enabled features with a "#"' do
77
+ subject.expects(:variable).once.with("DYNAMIC_FEATURES").returns("one")
78
+ subject.expects(:variable).once.with("DYNAMIC_FEATURES" => 'one#bar')
79
+ subject.enable_feature "bar"
80
+ end
81
+
82
+ it 'should not add duplicate enabled dynamic features' do
83
+ subject.expects(:variable).once.returns('eins#zwei')
84
+ subject.enable_feature "eins"
85
+ end
86
+
87
+ it 'should raise an ArgumentError if optional options are given when DYNAMIC_FEATURE_EXTENSIONS does not have a key for the feature name' do
88
+ expect { subject.enable_feature :this_is_not_recognized,
89
+ :these_features => "are not going to be recognized"
90
+ }.to raise_error ArgumentError
91
+ end
92
+
93
+ it 'enabling :attended_transfer should actually enable the atxfer feature' do
94
+ subject.expects(:variable).once.with("DYNAMIC_FEATURES").returns ''
95
+ subject.expects(:variable).once.with("DYNAMIC_FEATURES" => 'atxfer')
96
+ subject.enable_feature :attended_transfer
97
+ end
98
+
99
+ it 'the :context optional option when enabling :attended_transfer should set the TRANSFER_CONTEXT variable to the String supplied as a Hash value' do
100
+ context_name = "direct_dial"
101
+ subject.expects(:variable).once.with("DYNAMIC_FEATURES").returns ''
102
+ subject.expects(:variable).once.with("DYNAMIC_FEATURES" => 'atxfer')
103
+ subject.expects(:variable).once.with("TRANSFER_CONTEXT" => context_name)
104
+ subject.enable_feature :attended_transfer, :context => context_name
105
+ end
106
+
107
+ it 'enabling :attended_transfer should not add a duplicate if atxfer has been enabled, but it should still set the TRANSFER_CONTEXT variable' do
108
+ context_name = 'blah'
109
+ subject.expects(:variable).once.with('DYNAMIC_FEATURES').returns 'atxfer'
110
+ subject.expects(:variable).once.with('TRANSFER_CONTEXT' => context_name)
111
+ subject.enable_feature :attended_transfer, :context => context_name
112
+ end
113
+ end
114
+
115
+ describe '#disable_feature' do
116
+ it "should properly remove the feature from the DYNAMIC_FEATURES variable" do
117
+ subject.expects(:variable).once.with('DYNAMIC_FEATURES').returns 'foobar#qaz'
118
+ subject.expects(:variable).once.with('DYNAMIC_FEATURES' => 'qaz')
119
+ subject.disable_feature "foobar"
120
+ end
121
+
122
+ it "should not re-set the variable if the feature wasn't enabled in the first place" do
123
+ subject.expects(:variable).once.with('DYNAMIC_FEATURES').returns 'atxfer'
124
+ subject.expects(:variable).never
125
+ subject.disable_feature "jay"
126
+ end
127
+ end
128
+
129
+ describe "#variable" do
130
+ it "should call set_variable when Hash argument given" do
131
+ subject.expects(:set_variable).once.with :ohai, "ur_home_erly"
132
+ subject.variable :ohai => 'ur_home_erly'
133
+ end
134
+
135
+ it "should call set_variable for every Hash-key given" do
136
+ many_args = { :a => :b, :c => :d, :e => :f, :g => :h}
137
+ subject.expects(:set_variable).times(many_args.size)
138
+ subject.variable many_args
139
+ end
140
+
141
+ it "should call get_variable for every String given" do
142
+ variables = ["foo", "bar", :qaz, :qwerty, :baz]
143
+ variables.each do |var|
144
+ subject.expects(:get_variable).once.with(var).returns("X")
145
+ end
146
+ subject.variable(*variables).should == ["X"] * variables.size
147
+ end
148
+
149
+ it "should NOT return an Array when just one arg is given" do
150
+ subject.expects(:get_variable).once.returns "lol"
151
+ subject.variable(:foo).should_not be_a Array
152
+ end
153
+
154
+ it "should raise an ArgumentError when a Hash and normal args are given" do
155
+ lambda {
156
+ subject.variable 5, 4, 3, 2, 1, :foo => :bar
157
+ }.should raise_error ArgumentError
158
+ end
159
+ end
160
+
161
+ describe "#set_variable" do
162
+ it "uses SET VARIABLE" do
163
+ subject.expects(:agi).once.with 'SET VARIABLE', 'foo', 'i can " has ruby?'
164
+ subject.set_variable 'foo', 'i can " has ruby?'
165
+ end
166
+ end
167
+
168
+ describe '#get_variable' do
169
+ it 'uses GET VARIABLE and extracts the value from the data' do
170
+ subject.expects(:agi).once.with('GET VARIABLE', 'foo').returns [200, 1, 'bar']
171
+ subject.get_variable('foo').should == 'bar'
172
+ end
173
+ end
174
+
175
+ describe "#sip_add_header" do
176
+ it "executes SIPAddHeader" do
177
+ subject.expects(:execute).once.with 'SIPAddHeader', 'x-ahn-header: rubyrox'
178
+ subject.sip_add_header "x-ahn-header", "rubyrox"
179
+ end
180
+ end
181
+
182
+ describe "#sip_get_header" do
183
+ it "uses #get_variable to get the header value" do
184
+ value = 'jason-was-here'
185
+ subject.expects(:get_variable).once.with('SIP_HEADER(x-ahn-header)').returns value
186
+ subject.sip_get_header("x-ahn-header").should == value
187
+ end
188
+ end
189
+
190
+ describe '#join' do
191
+ it "should pass the 'd' flag when no options are given" do
192
+ conference_id = "123"
193
+ subject.expects(:execute).once.with("MeetMe", conference_id, "d", nil)
194
+ subject.meetme conference_id
195
+ end
196
+
197
+ it "should pass through any given flags with 'd' appended to it if necessary" do
198
+ conference_id, flags = "1000", "zomgs"
199
+ subject.expects(:execute).once.with("MeetMe", conference_id, flags + "d", nil)
200
+ subject.meetme conference_id, :options => flags
201
+ end
202
+
203
+ it "should NOT pass the 'd' flag when requiring static conferences" do
204
+ conference_id, options = "1000", {:use_static_conf => true}
205
+ subject.expects(:execute).once.with("MeetMe", conference_id, "", nil)
206
+ subject.meetme conference_id, options
207
+ end
208
+
209
+ it "should raise an ArgumentError when the pin is not numerical" do
210
+ lambda {
211
+ subject.expects(:execute).never
212
+ subject.meetme 3333, :pin => "letters are bad, mkay?!1"
213
+ }.should raise_error ArgumentError
214
+ end
215
+
216
+ it "should strip out illegal characters from a conference name" do
217
+ bizarre_conference_name = "a- bc!d&&e--`"
218
+ normal_conference_name = "abcde"
219
+ subject.expects(:execute).twice.with("MeetMe", normal_conference_name, "d", nil)
220
+
221
+ subject.meetme bizarre_conference_name
222
+ subject.meetme normal_conference_name
223
+ end
224
+
225
+ it "should allow textual conference names" do
226
+ lambda {
227
+ subject.expects(:execute).once
228
+ subject.meetme "david bowie's pants"
229
+ }.should_not raise_error
230
+ end
231
+ end
232
+
233
+ describe '#voicemail' do
234
+ it 'should not send the context name when none is given' do
235
+ subject.expects(:execute).once.with('voicemail', 123, '').throws :sent_voicemail!
236
+ lambda { subject.voicemail 123 }.should throw_symbol(:sent_voicemail!)
237
+ end
238
+
239
+ it 'should send the context name when one is given' do
240
+ mailbox_number, context_name = 333, 'doesntmatter'
241
+ subject.expects(:execute).once.with('voicemail', "#{mailbox_number}@#{context_name}", '').throws :sent_voicemail!
242
+ lambda { subject.voicemail(context_name => mailbox_number) }.should throw_symbol(:sent_voicemail!)
243
+ end
244
+
245
+ it 'should pass in the s option if :skip => true' do
246
+ mailbox_number = '012'
247
+ subject.expects(:execute).once.with('voicemail', mailbox_number, 's').throws :sent_voicemail!
248
+ lambda { subject.voicemail(mailbox_number, :skip => true) }.should throw_symbol(:sent_voicemail!)
249
+ end
250
+
251
+ it 'should combine mailbox numbers with the context name given when both are given' do
252
+ subject.expects(:variable).with("VMSTATUS").returns 'SUCCESS'
253
+ context = "lolcats"
254
+ mailboxes = [1,2,3,4,5]
255
+ mailboxes_with_context = mailboxes.map { |mailbox| [mailbox, context].join '@' }
256
+ subject.expects(:execute).once.with('voicemail', mailboxes_with_context.join('&'), '')
257
+ subject.voicemail context => mailboxes
258
+ end
259
+
260
+ it 'should raise an argument error if the mailbox number is not numerical' do
261
+ lambda {
262
+ subject.voicemail :foo => "bar"
263
+ }.should raise_error ArgumentError
264
+ end
265
+
266
+ it 'should raise an argument error if too many arguments are supplied' do
267
+ lambda {
268
+ subject.voicemail "wtfisthisargument", :context_name => 123, :greeting => :busy
269
+ }.should raise_error ArgumentError
270
+ end
271
+
272
+ it 'should raise an ArgumentError if multiple context names are given' do
273
+ lambda {
274
+ subject.voicemail :one => [1,2,3], :two => [11,22,33]
275
+ }.should raise_error ArgumentError
276
+ end
277
+
278
+ it "should raise an ArgumentError when the :greeting value isn't recognized" do
279
+ lambda {
280
+ subject.voicemail :context_name => 123, :greeting => :zomgz
281
+ }.should raise_error ArgumentError
282
+ end
283
+
284
+ it 'should pass in the u option if :greeting => :unavailable' do
285
+ mailbox_number = '776'
286
+ subject.expects(:execute).once.with('voicemail', mailbox_number, 'u').throws :sent_voicemail!
287
+ lambda { subject.voicemail(mailbox_number, :greeting => :unavailable) }.should throw_symbol(:sent_voicemail!)
288
+ end
289
+
290
+ it 'should pass in both the skip and greeting options if both are supplied' do
291
+ mailbox_number = '4'
292
+ subject.expects(:execute).once.with('voicemail', mailbox_number, 'u').throws :sent_voicemail!
293
+ lambda { subject.voicemail(mailbox_number, :greeting => :unavailable) }.should throw_symbol(:sent_voicemail!)
294
+ end
295
+
296
+ it 'should raise an ArgumentError if mailbox_number is blank?()' do
297
+ lambda {
298
+ subject.voicemail ''
299
+ }.should raise_error ArgumentError
300
+
301
+ lambda {
302
+ subject.voicemail nil
303
+ }.should raise_error ArgumentError
304
+ end
305
+
306
+ it 'should pass in the b option if :gretting => :busy' do
307
+ mailbox_number = '1'
308
+ subject.expects(:execute).once.with('voicemail', mailbox_number, 'b').throws :sent_voicemail!
309
+ lambda { subject.voicemail(mailbox_number, :greeting => :busy) }.should throw_symbol(:sent_voicemail!)
310
+ end
311
+
312
+ it 'should return true if VMSTATUS == "SUCCESS"' do
313
+ subject.expects(:execute).once
314
+ subject.expects(:variable).once.with('VMSTATUS').returns "SUCCESS"
315
+ subject.voicemail(3).should be true
316
+ end
317
+
318
+ it 'should return false if VMSTATUS == "USEREXIT"' do
319
+ subject.expects(:execute).once
320
+ subject.expects(:variable).once.with('VMSTATUS').returns "USEREXIT"
321
+ subject.voicemail(2).should be false
322
+ end
323
+
324
+ it 'should return nil if VMSTATUS == "FAILED"' do
325
+ subject.expects(:execute).once
326
+ subject.expects(:variable).once.with('VMSTATUS').returns "FAILED"
327
+ subject.voicemail(2).should be nil
328
+ end
329
+ end
330
+
331
+ describe '#voicemail_main' do
332
+ it "the :folder Hash key argument should wrap the value in a()" do
333
+ folder = "foobar"
334
+ mailbox = 81
335
+ subject.expects(:execute).once.with("VoiceMailMain", "#{mailbox}","a(#{folder})")
336
+ subject.voicemail_main :mailbox => mailbox, :folder => folder
337
+ end
338
+
339
+ it ':authenticate should pass in the "s" option if given false' do
340
+ mailbox = 333
341
+ subject.expects(:execute).once.with("VoiceMailMain", "#{mailbox}","s")
342
+ subject.voicemail_main :mailbox => mailbox, :authenticate => false
343
+ end
344
+
345
+ it ':authenticate should pass in the s option if given false' do
346
+ mailbox = 55
347
+ subject.expects(:execute).once.with("VoiceMailMain", "#{mailbox}")
348
+ subject.voicemail_main :mailbox => mailbox, :authenticate => true
349
+ end
350
+
351
+ it 'should not pass any flags only a mailbox is given' do
352
+ mailbox = "1"
353
+ subject.expects(:execute).once.with("VoiceMailMain", "#{mailbox}")
354
+ subject.voicemail_main :mailbox => mailbox
355
+ end
356
+
357
+ it 'when given no mailbox or context an empty string should be passed to execute as the first argument' do
358
+ subject.expects(:execute).once.with("VoiceMailMain", "", "s")
359
+ subject.voicemail_main :authenticate => false
360
+ end
361
+
362
+ it 'should properly concatenate the options when given multiple ones' do
363
+ folder = "ohai"
364
+ mailbox = 9999
365
+ subject.expects(:execute).once.with("VoiceMailMain", "#{mailbox}", "sa(#{folder})")
366
+ subject.voicemail_main :mailbox => mailbox, :authenticate => false, :folder => folder
367
+ end
368
+
369
+ it 'should not require any arguments' do
370
+ subject.expects(:execute).once.with("VoiceMailMain")
371
+ subject.voicemail_main
372
+ end
373
+
374
+ it 'should pass in the "@context_name" part in if a :context is given and no mailbox is given' do
375
+ context_name = "icanhascheezburger"
376
+ subject.expects(:execute).once.with("VoiceMailMain", "@#{context_name}")
377
+ subject.voicemail_main :context => context_name
378
+ end
379
+
380
+ it "should raise an exception if the folder has a space or malformed characters in it" do
381
+ ["i has a space", "exclaim!", ",", ""].each do |bad_folder_name|
382
+ lambda {
383
+ subject.voicemail_main :mailbox => 123, :folder => bad_folder_name
384
+ }.should raise_error ArgumentError
385
+ end
386
+ end
387
+ end
388
+
389
+ describe "#queue" do
390
+ it 'should not create separate objects for queues with basically the same name' do
391
+ subject.queue('foo').should be subject.queue('foo')
392
+ subject.queue('bar').should be subject.queue(:bar)
393
+ end
394
+
395
+ it "should return an instance of QueueProxy" do
396
+ subject.queue("foobar").should be_a_kind_of Adhearsion::Asterisk::QueueProxy
397
+ end
398
+
399
+ it "should set the QueueProxy's name" do
400
+ subject.queue("foobar").name.should == 'foobar'
401
+ end
402
+
403
+ it "should set the QueueProxy's environment" do
404
+ subject.queue("foobar").environment.should == subject
405
+ end
406
+ end#describe #queue
407
+
408
+ describe "#play" do
409
+ let(:audiofile) { "tt-monkeys" }
410
+ let(:audiofile2) { "tt-weasels" }
411
+
412
+ it 'should return true if play proceeds correctly' do
413
+ subject.expects(:play!).with([audiofile])
414
+ subject.play(audiofile).should be true
415
+ end
416
+
417
+ it 'should return false if an audio file cannot be found' do
418
+ subject.expects(:play!).with([audiofile]).raises(Adhearsion::PlaybackError)
419
+ subject.play(audiofile).should be false
420
+
421
+ end
422
+
423
+ it 'should return false when audio files cannot be found' do
424
+ subject.expects(:play!).with([audiofile, audiofile2]).raises(Adhearsion::PlaybackError)
425
+ subject.play(audiofile, audiofile2).should be false
426
+ end
427
+ end
428
+
429
+ describe "#play!" do
430
+ let(:audiofile) { "tt-monkeys" }
431
+ let(:audiofile2) { "tt-weasels" }
432
+ let(:numeric) { 20 }
433
+ let(:numeric_string) { "42" }
434
+ let(:date) { Date.parse('2011-10-24') }
435
+ let(:time) { Time.at(875121313) }
436
+
437
+ describe "with a single argument" do
438
+ it 'passing a single string to play() results in play_soundfile being called with that file name' do
439
+ subject.expects(:play_time).with([audiofile]).returns(false)
440
+ subject.expects(:play_numeric).with(audiofile).returns(false)
441
+ subject.expects(:play_soundfile).with(audiofile).returns(true)
442
+ subject.play!(audiofile)
443
+ end
444
+
445
+ it 'If a number is passed to play(), the play_numeric method is called with that argument' do
446
+ subject.expects(:play_time).with([numeric]).returns(false)
447
+ subject.expects(:play_numeric).with(numeric).returns(true)
448
+ subject.play!(numeric)
449
+ end
450
+
451
+ it 'if a string representation of a number is passed to play(), the play_numeric method is called with that argument' do
452
+ subject.expects(:play_time).with([numeric_string]).returns(false)
453
+ subject.expects(:play_numeric).with(numeric_string).returns(true)
454
+ subject.play!(numeric_string)
455
+ end
456
+
457
+ it 'If a Time is passed to play(), the play_time method is called with that argument' do
458
+ subject.expects(:play_time).with([time]).returns(true)
459
+ subject.play!(time)
460
+ end
461
+
462
+ it 'If a Date is passed to play(), the play_time method is called with that argument' do
463
+ subject.expects(:play_time).with([date]).returns(true)
464
+ subject.play!(date)
465
+ end
466
+
467
+ it 'raises an exception if play fails' do
468
+ subject.expects(:play_time).with([audiofile]).returns(false)
469
+ subject.expects(:play_numeric).with(audiofile).returns(false)
470
+ subject.expects(:play_soundfile).with(audiofile).returns(false)
471
+ lambda { subject.play!(audiofile) }.should raise_error(Adhearsion::PlaybackError)
472
+ end
473
+ end
474
+
475
+ describe "with multiple arguments" do
476
+ it 'loops over the arguments, issuing separate play commands' do
477
+ subject.expects(:play_time).with([audiofile, audiofile2]).returns(false)
478
+ subject.expects(:play_numeric).with(audiofile).returns(false)
479
+ subject.expects(:play_soundfile).with(audiofile).returns(true)
480
+ subject.expects(:play_numeric).with(audiofile2).returns(false)
481
+ subject.expects(:play_soundfile).with(audiofile2).returns(true)
482
+ subject.play!(audiofile, audiofile2)
483
+ end
484
+
485
+ it 'raises an exception if play fails with multiple argument' do
486
+ subject.expects(:play_time).with([audiofile, audiofile2]).returns(false)
487
+ subject.expects(:play_numeric).with(audiofile).returns(false)
488
+ subject.expects(:play_soundfile).with(audiofile).returns(false)
489
+ subject.expects(:play_numeric).with(audiofile2).returns(false)
490
+ subject.expects(:play_soundfile).with(audiofile2).returns(false)
491
+ lambda { subject.play!(audiofile, audiofile2) }.should raise_error(Adhearsion::PlaybackError)
492
+ end
493
+ end
494
+
495
+ end
496
+
497
+ describe "#play_time" do
498
+ let(:date) { Date.parse('2011-10-24') }
499
+ let(:date_format) { 'ABdY' }
500
+ let(:time) { Time.at(875121313) }
501
+ let(:time_format) { 'IMp' }
502
+
503
+ it "if a Date object is passed in, SayUnixTime is sent with the argument and format" do
504
+ subject.expects(:execute).once.with("SayUnixTime", date.to_time.to_i, "", date_format)
505
+ subject.play_time(date, :format => date_format)
506
+ end
507
+
508
+ it "if a Time object is passed in, SayUnixTime is sent with the argument and format" do
509
+ subject.expects(:execute).once.with("SayUnixTime", time.to_i, "", time_format)
510
+ subject.play_time(time, :format => time_format)
511
+ end
512
+
513
+ it "if a Time object is passed in alone, SayUnixTime is sent with the argument and the default format" do
514
+ subject.expects(:execute).once.with("SayUnixTime", time.to_i, "", "")
515
+ subject.play_time(time)
516
+ end
517
+
518
+ end
519
+
520
+ describe "#play_numeric" do
521
+ let(:numeric) { 20 }
522
+ it "should send the correct command SayNumber playing a numeric argument" do
523
+ subject.expects(:execute).once.with("SayNumber", numeric)
524
+ subject.play_numeric(numeric)
525
+ end
526
+ end
527
+
528
+ describe "#play_soundfile" do
529
+ let(:audiofile) { "tt-monkeys" }
530
+ it "should send the correct command Playback playing an audio file" do
531
+ subject.expects(:execute).once.with("Playback", audiofile)
532
+ # subject.expects(:execute).once.with("Playback", audiofile).returns([200, 1, nil])
533
+ subject.expects(:get_variable).once.with("PLAYBACKSTATUS").returns(PLAYBACK_SUCCESS)
534
+ subject.play_soundfile(audiofile)
535
+ end
536
+
537
+ it "should return false if playback fails" do
538
+ subject.expects(:execute).once.with("Playback", audiofile)
539
+ subject.expects(:get_variable).once.with("PLAYBACKSTATUS").returns('FAILED')
540
+ subject.play_soundfile(audiofile).should == false
541
+ end
542
+ end
543
+
544
+ describe "#stream_file" do
545
+ let(:allowed_digits) { '35' }
546
+ let(:prompt) { 'tt-monkeys' }
547
+
548
+ let :output_params do
549
+ {
550
+ :name => 'STREAM FILE',
551
+ :params => [
552
+ 'tt-monkeys',
553
+ '35'
554
+ ]
555
+ }
556
+ end
557
+
558
+ let(:output_component) do
559
+ Punchblock::Component::Asterisk::AGI::Command.new output_params
560
+ end
561
+
562
+ let(:result) { 53 }
563
+ let(:endpos) { '5000' }
564
+
565
+ let :reason do
566
+ Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new :code => 200,
567
+ :result => result,
568
+ :data => "endpos=#{endpos}"
569
+ end
570
+
571
+ before do
572
+ output_component
573
+ Punchblock::Component::Asterisk::AGI::Command.expects(:new).once.with(output_params).returns output_component
574
+ output_component.expects(:complete_event).at_least_once.returns mock('success', :reason => reason)
575
+ end
576
+
577
+ it "plays the correct output" do
578
+ subject.expects(:execute_component_and_await_completion).once.with(output_component).returns(output_component)
579
+ subject.stream_file prompt, allowed_digits
580
+ end
581
+
582
+ it "returns a single digit amongst the allowed when pressed" do
583
+ subject.expects(:execute_component_and_await_completion).once.with(output_component).returns(output_component)
584
+ subject.stream_file(prompt, allowed_digits).should == '5'
585
+ end
586
+
587
+ context 'when nothing was pressed' do
588
+ let(:result) { 0 }
589
+
590
+ it "returns nil" do
591
+ subject.expects(:execute_component_and_await_completion).once.with(output_component).returns(output_component)
592
+ subject.stream_file(prompt, allowed_digits).should == nil
593
+ end
594
+ end
595
+
596
+ context 'when output fails' do
597
+ let(:result) { -1 }
598
+
599
+ it "raises Adhearsion::PlaybackError" do
600
+ subject.expects(:execute_component_and_await_completion).once.with(output_component).returns(output_component)
601
+ lambda { subject.stream_file prompt, allowed_digits }.should raise_error Adhearsion::PlaybackError
602
+ end
603
+ end
604
+
605
+ context 'when output fails to open' do
606
+ let(:result) { 0 }
607
+ let(:endpos) { '0' }
608
+
609
+ it "raises Adhearsion::PlaybackError" do
610
+ subject.expects(:execute_component_and_await_completion).once.with(output_component).returns(output_component)
611
+ lambda { subject.stream_file prompt, allowed_digits }.should raise_error Adhearsion::PlaybackError
612
+ end
613
+ end
614
+ end # describe #stream_file
615
+ end
616
+ end#main describe
617
+ end