punchblock 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,16 +9,16 @@ module Punchblock
9
9
  describe Input do
10
10
  let(:connection) do
11
11
  mock_connection_with_event_handler do |event|
12
- command.add_event event
12
+ original_command.add_event event
13
13
  end
14
14
  end
15
15
  let(:media_engine) { nil }
16
16
  let(:translator) { Punchblock::Translator::Asterisk.new mock('AMI'), connection, media_engine }
17
17
  let(:call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator }
18
- let(:command_options) { {} }
18
+ let(:original_command_options) { {} }
19
19
 
20
- let :command do
21
- Punchblock::Component::Input.new command_options
20
+ let :original_command do
21
+ Punchblock::Component::Input.new original_command_options
22
22
  end
23
23
 
24
24
  let :grammar do
@@ -37,10 +37,10 @@ module Punchblock
37
37
  end
38
38
  end
39
39
 
40
- subject { Input.new command, call }
40
+ subject { Input.new original_command, call }
41
41
 
42
42
  describe '#execute' do
43
- before { command.request! }
43
+ before { original_command.request! }
44
44
 
45
45
  it "calls answer_if_not_answered on the call" do
46
46
  call.expects :answer_if_not_answered
@@ -57,10 +57,10 @@ module Punchblock
57
57
  context 'with a media engine of :asterisk' do
58
58
  let(:media_engine) { :asterisk }
59
59
 
60
- let(:command_opts) { {} }
60
+ let(:original_command_opts) { {} }
61
61
 
62
- let :command_options do
63
- { :mode => :dtmf, :grammar => { :value => grammar } }.merge(command_opts)
62
+ let :original_command_options do
63
+ { :mode => :dtmf, :grammar => { :value => grammar } }.merge(original_command_opts)
64
64
  end
65
65
 
66
66
  def ami_event_for_dtmf(digit, position)
@@ -76,7 +76,7 @@ module Punchblock
76
76
  call.process_ami_event ami_event_for_dtmf(digit, :end)
77
77
  end
78
78
 
79
- let(:reason) { command.complete_event(5).reason }
79
+ let(:reason) { original_command.complete_event(5).reason }
80
80
 
81
81
  describe "receiving DTMF events" do
82
82
  before do
@@ -92,11 +92,11 @@ module Punchblock
92
92
 
93
93
  let :expected_event do
94
94
  Punchblock::Component::Input::Complete::Success.new :mode => :dtmf,
95
- :confidence => 1,
96
- :utterance => '12',
97
- :interpretation => 'dtmf-1 dtmf-2',
98
- :component_id => subject.id,
99
- :call_id => call.id
95
+ :confidence => 1,
96
+ :utterance => '12',
97
+ :interpretation => 'dtmf-1 dtmf-2',
98
+ :component_id => subject.id,
99
+ :call_id => call.id
100
100
  end
101
101
 
102
102
  it "should send a success complete event with the relevant data" do
@@ -123,40 +123,40 @@ module Punchblock
123
123
 
124
124
  describe 'grammar' do
125
125
  context 'unset' do
126
- let(:command_opts) { { :grammar => nil } }
126
+ let(:original_command_opts) { { :grammar => nil } }
127
127
  it "should return an error and not execute any actions" do
128
128
  subject.execute
129
- error = ProtocolError.new 'option error', 'A grammar document is required.'
130
- command.response(0.1).should be == error
129
+ error = ProtocolError.new.setup 'option error', 'A grammar document is required.'
130
+ original_command.response(0.1).should be == error
131
131
  end
132
132
  end
133
133
  end
134
134
 
135
135
  describe 'mode' do
136
136
  context 'unset' do
137
- let(:command_opts) { { :mode => nil } }
137
+ let(:original_command_opts) { { :mode => nil } }
138
138
  it "should return an error and not execute any actions" do
139
139
  subject.execute
140
- error = ProtocolError.new 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
141
- command.response(0.1).should be == error
140
+ error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
141
+ original_command.response(0.1).should be == error
142
142
  end
143
143
  end
144
144
 
145
145
  context 'any' do
146
- let(:command_opts) { { :mode => :any } }
146
+ let(:original_command_opts) { { :mode => :any } }
147
147
  it "should return an error and not execute any actions" do
148
148
  subject.execute
149
- error = ProtocolError.new 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
150
- command.response(0.1).should be == error
149
+ error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
150
+ original_command.response(0.1).should be == error
151
151
  end
152
152
  end
153
153
 
154
154
  context 'speech' do
155
- let(:command_opts) { { :mode => :speech } }
155
+ let(:original_command_opts) { { :mode => :speech } }
156
156
  it "should return an error and not execute any actions" do
157
157
  subject.execute
158
- error = ProtocolError.new 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
159
- command.response(0.1).should be == error
158
+ error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
159
+ original_command.response(0.1).should be == error
160
160
  end
161
161
  end
162
162
  end
@@ -171,7 +171,7 @@ module Punchblock
171
171
 
172
172
  describe 'initial-timeout' do
173
173
  context 'a positive number' do
174
- let(:command_opts) { { :initial_timeout => 1000 } }
174
+ let(:original_command_opts) { { :initial_timeout => 1000 } }
175
175
 
176
176
  it "should not cause a NoInput if first input is received in time" do
177
177
  subject.execute
@@ -191,7 +191,7 @@ module Punchblock
191
191
  end
192
192
 
193
193
  context '-1' do
194
- let(:command_opts) { { :initial_timeout => -1 } }
194
+ let(:original_command_opts) { { :initial_timeout => -1 } }
195
195
 
196
196
  it "should not start a timer" do
197
197
  subject.wrapped_object.expects(:begin_initial_timer).never
@@ -200,7 +200,7 @@ module Punchblock
200
200
  end
201
201
 
202
202
  context 'unset' do
203
- let(:command_opts) { { :initial_timeout => nil } }
203
+ let(:original_command_opts) { { :initial_timeout => nil } }
204
204
 
205
205
  it "should not start a timer" do
206
206
  subject.wrapped_object.expects(:begin_initial_timer).never
@@ -209,19 +209,19 @@ module Punchblock
209
209
  end
210
210
 
211
211
  context 'a negative number other than -1' do
212
- let(:command_opts) { { :initial_timeout => -1000 } }
212
+ let(:original_command_opts) { { :initial_timeout => -1000 } }
213
213
 
214
214
  it "should return an error and not execute any actions" do
215
215
  subject.execute
216
- error = ProtocolError.new 'option error', 'An initial timeout value that is negative (and not -1) is invalid.'
217
- command.response(0.1).should be == error
216
+ error = ProtocolError.new.setup 'option error', 'An initial timeout value that is negative (and not -1) is invalid.'
217
+ original_command.response(0.1).should be == error
218
218
  end
219
219
  end
220
220
  end
221
221
 
222
222
  describe 'inter-digit-timeout' do
223
223
  context 'a positive number' do
224
- let(:command_opts) { { :inter_digit_timeout => 1000 } }
224
+ let(:original_command_opts) { { :inter_digit_timeout => 1000 } }
225
225
 
226
226
  it "should not prevent a Match if input is received in time" do
227
227
  subject.execute
@@ -243,7 +243,7 @@ module Punchblock
243
243
  end
244
244
 
245
245
  context '-1' do
246
- let(:command_opts) { { :inter_digit_timeout => -1 } }
246
+ let(:original_command_opts) { { :inter_digit_timeout => -1 } }
247
247
 
248
248
  it "should not start a timer" do
249
249
  subject.wrapped_object.expects(:begin_inter_digit_timer).never
@@ -252,7 +252,7 @@ module Punchblock
252
252
  end
253
253
 
254
254
  context 'unset' do
255
- let(:command_opts) { { :inter_digit_timeout => nil } }
255
+ let(:original_command_opts) { { :inter_digit_timeout => nil } }
256
256
 
257
257
  it "should not start a timer" do
258
258
  subject.wrapped_object.expects(:begin_inter_digit_timer).never
@@ -261,12 +261,12 @@ module Punchblock
261
261
  end
262
262
 
263
263
  context 'a negative number other than -1' do
264
- let(:command_opts) { { :inter_digit_timeout => -1000 } }
264
+ let(:original_command_opts) { { :inter_digit_timeout => -1000 } }
265
265
 
266
266
  it "should return an error and not execute any actions" do
267
267
  subject.execute
268
- error = ProtocolError.new 'option error', 'An inter-digit timeout value that is negative (and not -1) is invalid.'
269
- command.response(0.1).should be == error
268
+ error = ProtocolError.new.setup 'option error', 'An inter-digit timeout value that is negative (and not -1) is invalid.'
269
+ original_command.response(0.1).should be == error
270
270
  end
271
271
  end
272
272
  end
@@ -284,6 +284,37 @@ module Punchblock
284
284
  end
285
285
  end
286
286
  end
287
+
288
+ describe "#execute_command" do
289
+ context "with a command it does not understand" do
290
+ let(:command) { Punchblock::Component::Output::Pause.new }
291
+
292
+ before { command.request! }
293
+
294
+ it "returns a ProtocolError response" do
295
+ subject.execute_command command
296
+ command.response(0.1).should be_a ProtocolError
297
+ end
298
+ end
299
+
300
+ context "with a Stop command" do
301
+ let(:command) { Punchblock::Component::Stop.new }
302
+ let(:reason) { original_command.complete_event(5).reason }
303
+
304
+ before do
305
+ command.request!
306
+ original_command.request!
307
+ original_command.execute!
308
+ end
309
+
310
+ it "sets the command response to true" do
311
+ subject.execute_command command
312
+ command.response(0.1).should be == true
313
+ reason.should be_a Punchblock::Event::Complete::Stop
314
+ end
315
+ end
316
+ end
317
+
287
318
  end
288
319
  end
289
320
  end
@@ -9,14 +9,14 @@ module Punchblock
9
9
  describe Output do
10
10
  let(:connection) do
11
11
  mock_connection_with_event_handler do |event|
12
- command.add_event event
12
+ original_command.add_event event
13
13
  end
14
14
  end
15
15
  let(:media_engine) { nil }
16
16
  let(:translator) { Punchblock::Translator::Asterisk.new mock('AMI'), connection, media_engine }
17
17
  let(:mock_call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator }
18
18
 
19
- let :command do
19
+ let :original_command do
20
20
  Punchblock::Component::Output.new command_options
21
21
  end
22
22
 
@@ -30,10 +30,10 @@ module Punchblock
30
30
  { :ssml => ssml_doc }
31
31
  end
32
32
 
33
- subject { Output.new command, mock_call }
33
+ subject { Output.new original_command, mock_call }
34
34
 
35
35
  describe '#execute' do
36
- before { command.request! }
36
+ before { original_command.request! }
37
37
 
38
38
  it "calls answer_if_not_answered on the call" do
39
39
  mock_call.expects :answer_if_not_answered
@@ -75,7 +75,7 @@ module Punchblock
75
75
  block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
76
76
  end
77
77
  subject.execute
78
- command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
78
+ original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
79
79
  end
80
80
 
81
81
  describe 'interrupt_on' do
@@ -107,8 +107,8 @@ module Punchblock
107
107
  let(:command_opts) { { :interrupt_on => :speech } }
108
108
  it "should return an error and not execute any actions" do
109
109
  subject.execute
110
- error = ProtocolError.new 'option error', 'An interrupt-on value of speech is unsupported.'
111
- command.response(0.1).should be == error
110
+ error = ProtocolError.new.setup 'option error', 'An interrupt-on value of speech is unsupported.'
111
+ original_command.response(0.1).should be == error
112
112
  end
113
113
  end
114
114
  end
@@ -168,7 +168,7 @@ module Punchblock
168
168
  block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
169
169
  end
170
170
  subject.execute
171
- command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
171
+ original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
172
172
  end
173
173
 
174
174
  describe 'ssml' do
@@ -176,8 +176,8 @@ module Punchblock
176
176
  let(:command_opts) { { :ssml => nil } }
177
177
  it "should return an error and not execute any actions" do
178
178
  subject.execute
179
- error = ProtocolError.new 'option error', 'An SSML document is required.'
180
- command.response(0.1).should be == error
179
+ error = ProtocolError.new.setup 'option error', 'An SSML document is required.'
180
+ original_command.response(0.1).should be == error
181
181
  end
182
182
  end
183
183
  end
@@ -195,8 +195,8 @@ module Punchblock
195
195
  let(:command_opts) { { :start_offset => 10 } }
196
196
  it "should return an error and not execute any actions" do
197
197
  subject.execute
198
- error = ProtocolError.new 'option error', 'A start_offset value is unsupported on Asterisk.'
199
- command.response(0.1).should be == error
198
+ error = ProtocolError.new.setup 'option error', 'A start_offset value is unsupported on Asterisk.'
199
+ original_command.response(0.1).should be == error
200
200
  end
201
201
  end
202
202
  end
@@ -214,8 +214,8 @@ module Punchblock
214
214
  let(:command_opts) { { :start_paused => true } }
215
215
  it "should return an error and not execute any actions" do
216
216
  subject.execute
217
- error = ProtocolError.new 'option error', 'A start_paused value is unsupported on Asterisk.'
218
- command.response(0.1).should be == error
217
+ error = ProtocolError.new.setup 'option error', 'A start_paused value is unsupported on Asterisk.'
218
+ original_command.response(0.1).should be == error
219
219
  end
220
220
  end
221
221
  end
@@ -233,8 +233,8 @@ module Punchblock
233
233
  let(:command_opts) { { :repeat_interval => 10 } }
234
234
  it "should return an error and not execute any actions" do
235
235
  subject.execute
236
- error = ProtocolError.new 'option error', 'A repeat_interval value is unsupported on Asterisk.'
237
- command.response(0.1).should be == error
236
+ error = ProtocolError.new.setup 'option error', 'A repeat_interval value is unsupported on Asterisk.'
237
+ original_command.response(0.1).should be == error
238
238
  end
239
239
  end
240
240
  end
@@ -252,8 +252,8 @@ module Punchblock
252
252
  let(:command_opts) { { :repeat_times => 2 } }
253
253
  it "should return an error and not execute any actions" do
254
254
  subject.execute
255
- error = ProtocolError.new 'option error', 'A repeat_times value is unsupported on Asterisk.'
256
- command.response(0.1).should be == error
255
+ error = ProtocolError.new.setup 'option error', 'A repeat_times value is unsupported on Asterisk.'
256
+ original_command.response(0.1).should be == error
257
257
  end
258
258
  end
259
259
  end
@@ -271,8 +271,8 @@ module Punchblock
271
271
  let(:command_opts) { { :max_time => 30 } }
272
272
  it "should return an error and not execute any actions" do
273
273
  subject.execute
274
- error = ProtocolError.new 'option error', 'A max_time value is unsupported on Asterisk.'
275
- command.response(0.1).should be == error
274
+ error = ProtocolError.new.setup 'option error', 'A max_time value is unsupported on Asterisk.'
275
+ original_command.response(0.1).should be == error
276
276
  end
277
277
  end
278
278
  end
@@ -324,8 +324,8 @@ module Punchblock
324
324
  let(:command_opts) { { :interrupt_on => :speech } }
325
325
  it "should return an error and not execute any actions" do
326
326
  subject.execute
327
- error = ProtocolError.new 'option error', 'An interrupt-on value of speech is unsupported.'
328
- command.response(0.1).should be == error
327
+ error = ProtocolError.new.setup 'option error', 'An interrupt-on value of speech is unsupported.'
328
+ original_command.response(0.1).should be == error
329
329
  end
330
330
  end
331
331
  end
@@ -356,7 +356,7 @@ module Punchblock
356
356
  { :ssml => ssml_doc }.merge(command_opts)
357
357
  end
358
358
 
359
- let :command do
359
+ let :original_command do
360
360
  Punchblock::Component::Output.new command_options
361
361
  end
362
362
 
@@ -365,8 +365,8 @@ module Punchblock
365
365
  let(:command_opts) { { :ssml => nil } }
366
366
  it "should return an error and not execute any actions" do
367
367
  subject.execute
368
- error = ProtocolError.new 'option error', 'An SSML document is required.'
369
- command.response(0.1).should be == error
368
+ error = ProtocolError.new.setup 'option error', 'An SSML document is required.'
369
+ original_command.response(0.1).should be == error
370
370
  end
371
371
  end
372
372
 
@@ -388,7 +388,29 @@ module Punchblock
388
388
  block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
389
389
  end
390
390
  subject.execute
391
- command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
391
+ original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
392
+ end
393
+ end
394
+
395
+ context 'with a single text node without spaces' do
396
+ let(:audio_filename) { 'tt-monkeys' }
397
+ let :command_options do
398
+ {
399
+ :ssml => RubySpeech::SSML.draw { string audio_filename }
400
+ }
401
+ end
402
+
403
+ it 'should playback the audio file using STREAM FILE' do
404
+ expect_stream_file_with_options
405
+ subject.execute
406
+ end
407
+
408
+ it 'should send a complete event when the file finishes playback' do
409
+ def mock_call.send_agi_action!(*args, &block)
410
+ block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
411
+ end
412
+ subject.execute
413
+ original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
392
414
  end
393
415
  end
394
416
 
@@ -423,7 +445,7 @@ module Punchblock
423
445
  def mock_call.send_agi_action!(*args, &block)
424
446
  block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
425
447
  end
426
- command.expects(:add_event).once.with do |e|
448
+ original_command.expects(:add_event).once.with do |e|
427
449
  e.reason.should be_a Punchblock::Component::Output::Complete::Success
428
450
  end
429
451
  subject.execute
@@ -434,15 +456,15 @@ module Punchblock
434
456
  let :command_options do
435
457
  {
436
458
  :ssml => RubySpeech::SSML.draw do
437
- string "FooBar"
459
+ string "Foo Bar"
438
460
  end
439
461
  }
440
462
  end
441
463
 
442
464
  it "should return an unrenderable document error" do
443
465
  subject.execute
444
- error = ProtocolError.new 'unrenderable document error', 'The provided document could not be rendered.'
445
- command.response(0.1).should be == error
466
+ error = ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered.'
467
+ original_command.response(0.1).should be == error
446
468
  end
447
469
  end
448
470
  end
@@ -460,8 +482,8 @@ module Punchblock
460
482
  let(:command_opts) { { :start_offset => 10 } }
461
483
  it "should return an error and not execute any actions" do
462
484
  subject.execute
463
- error = ProtocolError.new 'option error', 'A start_offset value is unsupported on Asterisk.'
464
- command.response(0.1).should be == error
485
+ error = ProtocolError.new.setup 'option error', 'A start_offset value is unsupported on Asterisk.'
486
+ original_command.response(0.1).should be == error
465
487
  end
466
488
  end
467
489
  end
@@ -479,8 +501,8 @@ module Punchblock
479
501
  let(:command_opts) { { :start_paused => true } }
480
502
  it "should return an error and not execute any actions" do
481
503
  subject.execute
482
- error = ProtocolError.new 'option error', 'A start_paused value is unsupported on Asterisk.'
483
- command.response(0.1).should be == error
504
+ error = ProtocolError.new.setup 'option error', 'A start_paused value is unsupported on Asterisk.'
505
+ original_command.response(0.1).should be == error
484
506
  end
485
507
  end
486
508
  end
@@ -498,8 +520,8 @@ module Punchblock
498
520
  let(:command_opts) { { :repeat_interval => 10 } }
499
521
  it "should return an error and not execute any actions" do
500
522
  subject.execute
501
- error = ProtocolError.new 'option error', 'A repeat_interval value is unsupported on Asterisk.'
502
- command.response(0.1).should be == error
523
+ error = ProtocolError.new.setup 'option error', 'A repeat_interval value is unsupported on Asterisk.'
524
+ original_command.response(0.1).should be == error
503
525
  end
504
526
  end
505
527
  end
@@ -517,8 +539,8 @@ module Punchblock
517
539
  let(:command_opts) { { :repeat_times => 2 } }
518
540
  it "should return an error and not execute any actions" do
519
541
  subject.execute
520
- error = ProtocolError.new 'option error', 'A repeat_times value is unsupported on Asterisk.'
521
- command.response(0.1).should be == error
542
+ error = ProtocolError.new.setup 'option error', 'A repeat_times value is unsupported on Asterisk.'
543
+ original_command.response(0.1).should be == error
522
544
  end
523
545
  end
524
546
  end
@@ -536,8 +558,8 @@ module Punchblock
536
558
  let(:command_opts) { { :max_time => 30 } }
537
559
  it "should return an error and not execute any actions" do
538
560
  subject.execute
539
- error = ProtocolError.new 'option error', 'A max_time value is unsupported on Asterisk.'
540
- command.response(0.1).should be == error
561
+ error = ProtocolError.new.setup 'option error', 'A max_time value is unsupported on Asterisk.'
562
+ original_command.response(0.1).should be == error
541
563
  end
542
564
  end
543
565
  end
@@ -555,8 +577,8 @@ module Punchblock
555
577
  let(:command_opts) { { :voice => 'alison' } }
556
578
  it "should return an error and not execute any actions" do
557
579
  subject.execute
558
- error = ProtocolError.new 'option error', 'A voice value is unsupported on Asterisk.'
559
- command.response(0.1).should be == error
580
+ error = ProtocolError.new.setup 'option error', 'A voice value is unsupported on Asterisk.'
581
+ original_command.response(0.1).should be == error
560
582
  end
561
583
  end
562
584
  end
@@ -590,13 +612,65 @@ module Punchblock
590
612
  let(:command_opts) { { :interrupt_on => :speech } }
591
613
  it "should return an error and not execute any actions" do
592
614
  subject.execute
593
- error = ProtocolError.new 'option error', 'An interrupt-on value of speech is unsupported.'
594
- command.response(0.1).should be == error
615
+ error = ProtocolError.new.setup 'option error', 'An interrupt-on value of speech is unsupported.'
616
+ original_command.response(0.1).should be == error
595
617
  end
596
618
  end
597
619
  end
598
620
  end
599
621
  end
622
+
623
+ describe "#execute_command" do
624
+ context "with a command it does not understand" do
625
+ let(:command) { Punchblock::Component::Output::Pause.new }
626
+
627
+ before { command.request! }
628
+ it "returns a ProtocolError response" do
629
+ subject.execute_command command
630
+ command.response(0.1).should be_a ProtocolError
631
+ end
632
+ end
633
+
634
+ context "with a Stop command" do
635
+ let(:command) { Punchblock::Component::Stop.new }
636
+ let(:reason) { original_command.complete_event(5).reason }
637
+ let(:channel) { "SIP/1234-00000000" }
638
+ let :ami_event do
639
+ RubyAMI::Event.new('AsyncAGI').tap do |e|
640
+ e['SubEvent'] = "Start"
641
+ e['Channel'] = channel
642
+ e['Env'] = "agi_request%3A%20async%0Aagi_channel%3A%20SIP%2F1234-00000000%0Aagi_language%3A%20en%0Aagi_type%3A%20SIP%0Aagi_uniqueid%3A%201320835995.0%0Aagi_version%3A%201.8.4.1%0Aagi_callerid%3A%205678%0Aagi_calleridname%3A%20Jane%20Smith%0Aagi_callingpres%3A%200%0Aagi_callingani2%3A%200%0Aagi_callington%3A%200%0Aagi_callingtns%3A%200%0Aagi_dnid%3A%201000%0Aagi_rdnis%3A%20unknown%0Aagi_context%3A%20default%0Aagi_extension%3A%201000%0Aagi_priority%3A%201%0Aagi_enhanced%3A%200.0%0Aagi_accountcode%3A%20%0Aagi_threadid%3A%204366221312%0A%0A"
643
+ end
644
+ end
645
+
646
+ before do
647
+ command.request!
648
+ original_command.request!
649
+ original_command.execute!
650
+ end
651
+
652
+ it "sets the command response to true" do
653
+ mock_call.expects(:redirect_back!)
654
+ subject.execute_command command
655
+ command.response(0.1).should be == true
656
+ end
657
+
658
+ it "sends the correct complete event" do
659
+ mock_call.expects(:redirect_back!)
660
+ subject.execute_command command
661
+ original_command.should_not be_complete
662
+ mock_call.process_ami_event! ami_event
663
+ reason.should be_a Punchblock::Event::Complete::Stop
664
+ original_command.should be_complete
665
+ end
666
+
667
+ it "redirects the call by unjoining it" do
668
+ mock_call.expects(:redirect_back!).with(nil)
669
+ subject.execute_command command
670
+ end
671
+ end
672
+ end
673
+
600
674
  end
601
675
  end
602
676
  end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Punchblock
6
+ module Translator
7
+ class Asterisk
8
+ module Component
9
+ describe StopByRedirect do
10
+
11
+ class MockComponent < Component
12
+ include StopByRedirect
13
+ end
14
+
15
+ let(:mock_call) { mock('Call') }
16
+ subject { MockComponent.new Hash.new, mock_call }
17
+
18
+ describe "#execute_command" do
19
+ context "with a command it does not understand" do
20
+ let(:command) { Punchblock::Component::Output::Pause.new }
21
+
22
+ before { command.request! }
23
+ it "returns a ProtocolError response" do
24
+ mock_call.expects(:id)
25
+ subject.execute_command command
26
+ command.response(0.1).should be_a ProtocolError
27
+ end
28
+ end
29
+
30
+ context "with a Stop command" do
31
+ let(:command) { Punchblock::Component::Stop.new }
32
+
33
+ before do
34
+ command.request!
35
+ end
36
+
37
+ it "sets the command response to true" do
38
+ mock_call.expects(:redirect_back!)
39
+ mock_call.expects(:register_handler).with do |type, *guards|
40
+ type.should be == :ami
41
+ guards.should have(2).guards
42
+ guards[0].should be_a Proc
43
+ guards[1].should be == {:name => 'AsyncAGI'}
44
+ end
45
+
46
+ subject.execute_command command
47
+ command.response(0.1).should be == true
48
+ end
49
+
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -83,7 +83,7 @@ module Punchblock
83
83
 
84
84
  it 'sends an error in response to the command' do
85
85
  subject.execute_command component_command
86
- component_command.response.should be == ProtocolError.new('command-not-acceptable', "Did not understand command for component #{subject.id}", call.id, subject.id)
86
+ component_command.response.should be == ProtocolError.new.setup('command-not-acceptable', "Did not understand command for component #{subject.id}", call.id, subject.id)
87
87
  end
88
88
  end
89
89
  end