punchblock 2.6.0 → 2.7.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.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/lib/punchblock/component/output.rb +12 -4
  4. data/lib/punchblock/translator/asterisk.rb +3 -4
  5. data/lib/punchblock/translator/asterisk/agi_command.rb +3 -0
  6. data/lib/punchblock/translator/asterisk/call.rb +53 -7
  7. data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +1 -1
  8. data/lib/punchblock/translator/asterisk/component/composed_prompt.rb +1 -1
  9. data/lib/punchblock/translator/asterisk/component/input.rb +1 -1
  10. data/lib/punchblock/translator/asterisk/component/mrcp_native_prompt.rb +14 -2
  11. data/lib/punchblock/translator/asterisk/component/mrcp_recog_prompt.rb +39 -0
  12. data/lib/punchblock/translator/asterisk/component/output.rb +1 -1
  13. data/lib/punchblock/translator/asterisk/component/stop_by_redirect.rb +1 -1
  14. data/lib/punchblock/version.rb +1 -1
  15. data/spec/punchblock/translator/asterisk/call_spec.rb +250 -35
  16. data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +55 -2
  17. data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +24 -5
  18. data/spec/punchblock/translator/asterisk/component/input_spec.rb +26 -5
  19. data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +42 -2
  20. data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +479 -0
  21. data/spec/punchblock/translator/asterisk/component/output_spec.rb +40 -17
  22. data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +4 -3
  23. data/spec/punchblock/translator/asterisk_spec.rb +36 -9
  24. metadata +2 -2
@@ -30,6 +30,8 @@ module Punchblock
30
30
  { :render_document => {:value => ssml_doc}, renderer: renderer }
31
31
  end
32
32
 
33
+ let(:ast13mode) { false }
34
+
33
35
  subject { Output.new original_command, mock_call }
34
36
 
35
37
  def expect_answered(value = true)
@@ -933,10 +935,15 @@ module Punchblock
933
935
 
934
936
  describe 'interrupt_on' do
935
937
  def ami_event_for_dtmf(digit, position)
936
- RubyAMI::Event.new 'DTMF',
937
- 'Digit' => digit.to_s,
938
- 'Start' => position == :start ? 'Yes' : 'No',
939
- 'End' => position == :end ? 'Yes' : 'No'
938
+ if ast13mode
939
+ RubyAMI::Event.new 'DTMF' + (position == :start ? 'Begin' : '') + (position == :end ? 'End' : ''),
940
+ 'Digit' => digit.to_s
941
+ else
942
+ RubyAMI::Event.new 'DTMF',
943
+ 'Digit' => digit.to_s,
944
+ 'Start' => position == :start ? 'Yes' : 'No',
945
+ 'End' => position == :end ? 'Yes' : 'No'
946
+ end
940
947
  end
941
948
 
942
949
  def send_ami_events_for_dtmf(digit)
@@ -1664,10 +1671,15 @@ module Punchblock
1664
1671
 
1665
1672
  describe 'interrupt_on' do
1666
1673
  def ami_event_for_dtmf(digit, position)
1667
- RubyAMI::Event.new 'DTMF',
1668
- 'Digit' => digit.to_s,
1669
- 'Start' => position == :start ? 'Yes' : 'No',
1670
- 'End' => position == :end ? 'Yes' : 'No'
1674
+ if ast13mode
1675
+ RubyAMI::Event.new 'DTMF' + (position == :start ? 'Begin' : '') + (position == :end ? 'End' : ''),
1676
+ 'Digit' => digit.to_s
1677
+ else
1678
+ RubyAMI::Event.new 'DTMF',
1679
+ 'Digit' => digit.to_s,
1680
+ 'Start' => position == :start ? 'Yes' : 'No',
1681
+ 'End' => position == :end ? 'Yes' : 'No'
1682
+ end
1671
1683
  end
1672
1684
 
1673
1685
  def send_ami_events_for_dtmf(digit)
@@ -1736,17 +1748,21 @@ module Punchblock
1736
1748
  expect(subject).to receive(:send_finish).and_return nil
1737
1749
  end
1738
1750
 
1751
+ def send_correct_complete_event
1752
+ expect(mock_call).to receive :redirect_back
1753
+ subject.execute
1754
+ expect(original_command.response(0.1)).to be_a Ref
1755
+ expect(original_command).not_to be_complete
1756
+ send_ami_events_for_dtmf 1
1757
+ mock_call.process_ami_event ami_event
1758
+ sleep 0.2
1759
+ expect(original_command).to be_complete
1760
+ expect(reason).to be_a Punchblock::Component::Output::Complete::Finish
1761
+ end
1762
+
1739
1763
  context "when a DTMF digit is received" do
1740
1764
  it "sends the correct complete event" do
1741
- expect(mock_call).to receive :redirect_back
1742
- subject.execute
1743
- expect(original_command.response(0.1)).to be_a Ref
1744
- expect(original_command).not_to be_complete
1745
- send_ami_events_for_dtmf 1
1746
- mock_call.process_ami_event ami_event
1747
- sleep 0.2
1748
- expect(original_command).to be_complete
1749
- expect(reason).to be_a Punchblock::Component::Output::Complete::Finish
1765
+ send_correct_complete_event
1750
1766
  end
1751
1767
 
1752
1768
  it "redirects the call back to async AGI" do
@@ -1755,6 +1771,13 @@ module Punchblock
1755
1771
  expect(original_command.response(0.1)).to be_a Ref
1756
1772
  send_ami_events_for_dtmf 1
1757
1773
  end
1774
+
1775
+ context 'with an Asterisk 13 DTMFEnd event' do
1776
+ let(:ast13mode) { true }
1777
+ it "sends the correct complete event" do
1778
+ send_correct_complete_event
1779
+ end
1780
+ end
1758
1781
  end
1759
1782
  end
1760
1783
 
@@ -44,9 +44,10 @@ module Punchblock
44
44
  expect(mock_call).to receive(:redirect_back)
45
45
  expect(mock_call).to receive(:register_handler).with { |type, *guards|
46
46
  expect(type).to eq(:ami)
47
- expect(guards.size).to eq(2)
48
- expect(guards[0]).to be_a Proc
49
- expect(guards[1]).to eq({:name => 'AsyncAGI'})
47
+ expect(guards.size).to eq(1)
48
+ expect(guards[0]).to be_a Array
49
+ expect(guards[0][0]).to eq({:name => 'AsyncAGI', [:[], 'SubEvent']=>'Start'})
50
+ expect(guards[0][1]).to eq({:name => 'AsyncAGIExec'})
50
51
  }
51
52
 
52
53
  subject.execute_command command
@@ -377,14 +377,8 @@ module Punchblock
377
377
  '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"
378
378
  end
379
379
 
380
- before { allow(subject.wrapped_object).to receive :handle_pb_event }
381
-
382
- it 'should be able to look up the call by channel ID' do
383
- subject.handle_ami_event ami_event
384
- call = subject.call_for_channel('SIP/1234-00000000')
385
- expect(call).to be_a Asterisk::Call
386
- expect(call.agi_env).to be_a Hash
387
- expect(call.agi_env).to eq({
380
+ let :expected_agi_env do
381
+ {
388
382
  :agi_request => 'async',
389
383
  :agi_channel => 'SIP/1234-00000000',
390
384
  :agi_language => 'en',
@@ -405,7 +399,17 @@ module Punchblock
405
399
  :agi_enhanced => '0.0',
406
400
  :agi_accountcode => '',
407
401
  :agi_threadid => '4366221312'
408
- })
402
+ }
403
+ end
404
+
405
+ before { allow(subject.wrapped_object).to receive :handle_pb_event }
406
+
407
+ it 'should be able to look up the call by channel ID' do
408
+ subject.handle_ami_event ami_event
409
+ call = subject.call_for_channel('SIP/1234-00000000')
410
+ expect(call).to be_a Asterisk::Call
411
+ expect(call.agi_env).to be_a Hash
412
+ expect(call.agi_env).to eq(expected_agi_env)
409
413
  end
410
414
 
411
415
  it 'should instruct the call to send an offer' do
@@ -415,6 +419,29 @@ module Punchblock
415
419
  subject.handle_ami_event ami_event
416
420
  end
417
421
 
422
+ context 'with an Asterisk 13 AsyncAGIStart event' do
423
+ let :ami_event do
424
+ RubyAMI::Event.new 'AsyncAGIStart',
425
+ 'Channel' => "SIP/1234-00000000",
426
+ '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"
427
+ end
428
+
429
+ it 'should be able to look up the call by channel ID' do
430
+ subject.handle_ami_event ami_event
431
+ call = subject.call_for_channel('SIP/1234-00000000')
432
+ expect(call).to be_a Asterisk::Call
433
+ expect(call.agi_env).to be_a Hash
434
+ expect(call.agi_env).to eq(expected_agi_env)
435
+ end
436
+
437
+ it 'should instruct the call to send an offer' do
438
+ mock_call = double('Asterisk::Call').as_null_object
439
+ expect(Asterisk::Call).to receive(:new).once.and_return mock_call
440
+ expect(mock_call).to receive(:send_offer).once
441
+ subject.handle_ami_event ami_event
442
+ end
443
+ end
444
+
418
445
  context 'if a call already exists for a matching channel' do
419
446
  let(:call) { Asterisk::Call.new "SIP/1234-00000000", subject, ami_client, connection }
420
447
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: punchblock
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Goecke
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-02-01 00:00:00.000000000 Z
13
+ date: 2015-06-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri