adhearsion-asterisk 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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