punchblock 2.0.0.beta1 → 2.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -5
  3. data/lib/punchblock/connection/asterisk.rb +1 -2
  4. data/lib/punchblock/connection/freeswitch.rb +1 -1
  5. data/lib/punchblock/core_ext/blather/stanza.rb +5 -4
  6. data/lib/punchblock/rayo_node.rb +2 -3
  7. data/lib/punchblock/translator/asterisk.rb +3 -3
  8. data/lib/punchblock/translator/asterisk/component/output.rb +1 -5
  9. data/lib/punchblock/translator/freeswitch.rb +5 -5
  10. data/lib/punchblock/translator/freeswitch/call.rb +9 -9
  11. data/lib/punchblock/translator/freeswitch/component/abstract_output.rb +2 -2
  12. data/lib/punchblock/translator/freeswitch/component/flite_output.rb +4 -0
  13. data/lib/punchblock/translator/freeswitch/component/tts_output.rb +7 -3
  14. data/lib/punchblock/version.rb +1 -1
  15. data/spec/punchblock/connection/asterisk_spec.rb +1 -6
  16. data/spec/punchblock/connection/freeswitch_spec.rb +3 -15
  17. data/spec/punchblock/connection/xmpp_spec.rb +37 -19
  18. data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +1 -2
  19. data/spec/punchblock/translator/asterisk/component/input_spec.rb +1 -2
  20. data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +1 -2
  21. data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +1 -2
  22. data/spec/punchblock/translator/asterisk/component/output_spec.rb +18 -47
  23. data/spec/punchblock/translator/asterisk/component/record_spec.rb +1 -2
  24. data/spec/punchblock/translator/asterisk_spec.rb +1 -12
  25. data/spec/punchblock/translator/freeswitch/call_spec.rb +19 -37
  26. data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +4 -6
  27. data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +6 -8
  28. data/spec/punchblock/translator/freeswitch_spec.rb +1 -7
  29. data/spec/spec_helper.rb +4 -1
  30. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49f42b835052273a5744b92e6b84779b2782e0cc
4
- data.tar.gz: fbcc1abd28ccbf6fbd8ecb200fda82c31ec1ac6c
3
+ metadata.gz: 4f0d1de96c4233bf0c4b8ed7943e4dc93e23138c
4
+ data.tar.gz: 57aeccc7ef70667f12f582f96b9a40e357d1e1f2
5
5
  SHA512:
6
- metadata.gz: 5f6b8381a4bb5f30389ee46854e7a5ce569147721de0af96d4a995cea6ca5a6b3f97ecdf53538ea81c48cda8530476f5568a66b985c14254bd9c5f9254993cf8
7
- data.tar.gz: 7af2927dda7105ab22949cecca00725c97906f0df79d3996b662e0460c3e562137ed3f2a4bab3293902cec8c525165fb67d624727bd2708f70a9ac9ec25e6056
6
+ metadata.gz: 605b57ffde8d82ceb9fc87f625a21c1c9ac55fc32135a4d3bd9c3b689febabe4741e8877a7eeae2f0c5bd9861583bce9643d17289d5a5b15d79ac91f254cf0d5
7
+ data.tar.gz: 57030a3403b343c3c6846d1b2bd958837ccca4caf25afbef8a2babad25a0b17e25ad17790d5d5680a303bb4a8695ce73357e17dd7a5e6da9e1b1f238f39c4941
data/CHANGELOG.md CHANGED
@@ -1,17 +1,18 @@
1
1
  # [develop](https://github.com/adhearsion/punchblock)
2
2
 
3
- # [v2.0.0.beta1](https://github.com/adhearsion/punchblock/compare/v1.9.4...v2.0.0.beta1) - [2013-08-20](https://rubygems.org/gems/punchblock/versions/2.0.0.beta1)
4
- * Bugfix: Reconnect dead Asterisk streams correctly
5
- * Feature: Added FS support for initial timeout and final timeout on Record.
3
+ # [v2.0.0.beta2](https://github.com/adhearsion/punchblock/compare/v1.9.4...v2.0.0.beta2) - [2013-08-27](https://rubygems.org/gems/punchblock/versions/2.0.0.beta2)
6
4
  * Feature: Compliance with v0.2 of the published Rayo spec (http://xmpp.org/extensions/xep-0327.html)
7
- * Feature: Add support for Rayo Prompt component (no support on FS)
5
+ * Feature: Add support for Rayo Prompt component
6
+ * Feature: Added FS support for initial timeout and final timeout on Record
8
7
  * Change: Models are now plain ruby objects, not XML nodes, and are imported from/exported to XML when necessary for communicating over XMPP.
9
8
  * Change: `#headers` and AMI `#attributes` now do not have their names modified. A header of `'Call-ID'` will no longer be modified to `:call_id`.
10
9
  * Change: AMI Events/Actions now have `#headers(=)` rather than `#attributes(=)`
11
10
  * Change: Remove event queue
11
+ * Change: Removed `media_engine` and `default_voice` settings
12
+ * Bugfix: Reconnect dead Asterisk streams correctly
12
13
  * Bugfix: Include AMI response text_body in AMI component complete events
13
14
  * Bugfix: Avoid crashing translators (Asterisk or FreeSWITCH) by instructing them to call back to terminated Call objects
14
- * Bugfix: Detect MRCPSynth failure in output component.
15
+ * Bugfix: Detect MRCPSynth failure in output component
15
16
  * Bugfix: Handle AMI errors indicating dead channels correctly
16
17
 
17
18
  # [v1.9.4](https://github.com/adhearsion/punchblock/compare/v1.9.3...v1.9.4) - [2013-06-08](https://rubygems.org/gems/punchblock/versions/1.9.4)
@@ -10,9 +10,8 @@ module Punchblock
10
10
 
11
11
  def initialize(options = {})
12
12
  @stream_options = options.values_at(:host, :port, :username, :password)
13
- @translator_options = options.values_at(:media_engine)
14
13
  @ami_client = new_ami_stream
15
- @translator = Translator::Asterisk.new @ami_client, self, *@translator_options
14
+ @translator = Translator::Asterisk.new @ami_client, self
16
15
  super()
17
16
  end
18
17
 
@@ -9,7 +9,7 @@ module Punchblock
9
9
  attr_accessor :event_handler
10
10
 
11
11
  def initialize(options = {})
12
- @translator = Translator::Freeswitch.new self, options[:media_engine], options[:default_voice]
12
+ @translator = Translator::Freeswitch.new self
13
13
  @stream_options = options.values_at(:host, :port, :password)
14
14
  @stream = new_fs_stream
15
15
  super()
@@ -2,15 +2,16 @@
2
2
 
3
3
  module Blather
4
4
  class Stanza
5
+ RAYO_NODE_PATH = "(#{Punchblock::RAYO_NAMESPACES.keys.map { |k| "#{k}:*" }.join("|")})".freeze
5
6
  ##
6
7
  # @return [Punchblock::RayoNode] a child of RayoNode
7
8
  # representing the Rayo command/event contained within the stanza
8
9
  #
9
10
  def rayo_node
10
- first_child = at_xpath '*'
11
- Punchblock::RayoNode.from_xml first_child, nil, component_id if first_child
12
- rescue Punchblock::RayoNode::InvalidNodeError
13
- nil
11
+ @rayo_node ||= begin
12
+ first_child = at_xpath RAYO_NODE_PATH, Punchblock::RAYO_NAMESPACES
13
+ Punchblock::RayoNode.from_xml first_child, nil, component_id if first_child
14
+ end
14
15
  end
15
16
 
16
17
  ##
@@ -7,8 +7,6 @@ module Punchblock
7
7
  class RayoNode
8
8
  include Virtus
9
9
 
10
- InvalidNodeError = Class.new Punchblock::Error
11
-
12
10
  @@registrations = {}
13
11
 
14
12
  class_attribute :registered_ns, :registered_name
@@ -65,7 +63,8 @@ module Punchblock
65
63
 
66
64
  def inherit(xml_node)
67
65
  xml_node.attributes.each do |key, attr_node|
68
- send "#{key.gsub('-', '_')}=", xml_node[key]
66
+ setter_method = "#{key.gsub('-', '_')}="
67
+ send setter_method, xml_node[key] if respond_to?(setter_method)
69
68
  end
70
69
  self
71
70
  end
@@ -18,7 +18,7 @@ module Punchblock
18
18
  autoload :Channel
19
19
  autoload :Component
20
20
 
21
- attr_reader :ami_client, :connection, :media_engine, :calls
21
+ attr_reader :ami_client, :connection, :calls
22
22
 
23
23
  REDIRECT_CONTEXT = 'adhearsion-redirect'
24
24
  REDIRECT_EXTENSION = '1'
@@ -28,8 +28,8 @@ module Punchblock
28
28
 
29
29
  trap_exit :actor_died
30
30
 
31
- def initialize(ami_client, connection, media_engine = nil)
32
- @ami_client, @connection, @media_engine = ami_client, connection, media_engine
31
+ def initialize(ami_client, connection)
32
+ @ami_client, @connection = ami_client, connection
33
33
  @calls, @components, @channel_to_call_id = {}, {}, {}
34
34
  end
35
35
 
@@ -14,10 +14,6 @@ module Punchblock
14
14
  UniMRCPError = Class.new Punchblock::Error
15
15
  PlaybackError = Class.new Punchblock::Error
16
16
 
17
- def setup
18
- @media_engine = @call.translator.media_engine
19
- end
20
-
21
17
  def execute
22
18
  raise OptionError, 'An SSML document is required.' unless @component_node.render_documents.first.value
23
19
  raise OptionError, 'Only a single document is supported.' unless @component_node.render_documents.size == 1
@@ -29,7 +25,7 @@ module Punchblock
29
25
 
30
26
  early = !@call.answered?
31
27
 
32
- rendering_engine = @component_node.renderer || @media_engine || :asterisk
28
+ rendering_engine = @component_node.renderer || :asterisk
33
29
 
34
30
  case rendering_engine.to_sym
35
31
  when :asterisk
@@ -18,14 +18,14 @@ module Punchblock
18
18
  autoload :Call
19
19
  autoload :Component
20
20
 
21
- attr_reader :connection, :media_engine, :default_voice, :calls
21
+ attr_reader :connection, :calls
22
22
 
23
23
  trap_exit :actor_died
24
24
 
25
25
  finalizer :finalize
26
26
 
27
- def initialize(connection, media_engine = nil, default_voice = nil)
28
- @connection, @media_engine, @default_voice = connection, media_engine, default_voice
27
+ def initialize(connection)
28
+ @connection = connection
29
29
  @calls, @components = {}, {}
30
30
  setup_handlers
31
31
  end
@@ -62,7 +62,7 @@ module Punchblock
62
62
 
63
63
  register_handler :es, :event_name => 'CHANNEL_PARK' do |event|
64
64
  throw :pass if es_event_known_call? event
65
- call = Call.new event[:unique_id], current_actor, event.content.select { |k,v| k.to_s =~ /variable/ }, stream, @media_engine, @default_voice
65
+ call = Call.new event[:unique_id], current_actor, event.content.select { |k,v| k.to_s =~ /variable/ }, stream
66
66
  link call
67
67
  register_call call
68
68
  call.async.send_offer
@@ -135,7 +135,7 @@ module Punchblock
135
135
  def execute_global_command(command)
136
136
  case command
137
137
  when Punchblock::Command::Dial
138
- call = Call.new_link Punchblock.new_uuid, current_actor, nil, stream, @media_engine, @default_voice
138
+ call = Call.new_link Punchblock.new_uuid, current_actor, nil, stream
139
139
  register_call call
140
140
  call.async.dial command
141
141
  else
@@ -37,12 +37,12 @@ module Punchblock
37
37
  REJECT_TO_HANGUP_REASON = Hash.new 'NORMAL_TEMPORARY_FAILURE'
38
38
  REJECT_TO_HANGUP_REASON.merge! :busy => 'USER_BUSY', :decline => 'CALL_REJECTED'
39
39
 
40
- attr_reader :id, :translator, :es_env, :direction, :stream, :media_engine, :default_voice
40
+ attr_reader :id, :translator, :es_env, :direction, :stream
41
41
 
42
42
  trap_exit :actor_died
43
43
 
44
- def initialize(id, translator, es_env = nil, stream = nil, media_engine = nil, default_voice = nil)
45
- @id, @translator, @stream, @media_engine, @default_voice = id, translator, stream, media_engine, default_voice
44
+ def initialize(id, translator, es_env = nil, stream = nil)
45
+ @id, @translator, @stream = id, translator, stream
46
46
  @es_env = es_env || {}
47
47
  @components = {}
48
48
  @pending_joins, @pending_unjoins = {}, {}
@@ -205,14 +205,14 @@ module Punchblock
205
205
  hangup REJECT_TO_HANGUP_REASON[command.reason]
206
206
  command.response = true
207
207
  when Punchblock::Component::Output
208
- media_renderer = command.renderer || media_engine || :freeswitch
209
- case media_renderer.to_sym
210
- when :freeswitch, :native, nil
208
+ media_renderer = command.renderer || :freeswitch
209
+ case media_renderer.to_s
210
+ when 'freeswitch', 'native'
211
211
  execute_component Component::Output, command
212
- when :flite
213
- execute_component Component::FliteOutput, command, media_engine, default_voice
212
+ when 'flite'
213
+ execute_component Component::FliteOutput, command
214
214
  else
215
- execute_component Component::TTSOutput, command, media_engine, default_voice
215
+ execute_component Component::TTSOutput, command
216
216
  end
217
217
  when Punchblock::Component::Input
218
218
  execute_component Component::Input, command
@@ -7,10 +7,10 @@ module Punchblock
7
7
  class AbstractOutput < Component
8
8
  UnrenderableDocError = Class.new OptionError
9
9
 
10
- def execute(*args)
10
+ def execute
11
11
  validate
12
12
  send_ref
13
- do_output(*args)
13
+ do_output
14
14
  rescue UnrenderableDocError => e
15
15
  with_error 'unrenderable document error', e.message
16
16
  rescue OptionError => e
@@ -7,6 +7,10 @@ module Punchblock
7
7
  class FliteOutput < TTSOutput
8
8
  private
9
9
 
10
+ def renderer
11
+ :flite
12
+ end
13
+
10
14
  def document
11
15
  @component_node.render_documents.first.value.inner_text.to_s
12
16
  end
@@ -7,12 +7,16 @@ module Punchblock
7
7
  class TTSOutput < AbstractOutput
8
8
  private
9
9
 
10
- def do_output(engine, default_voice = nil)
10
+ def do_output
11
11
  register_handler :es, :event_name => 'CHANNEL_EXECUTE_COMPLETE' do |event|
12
12
  send_complete_event finish_reason
13
13
  end
14
- voice = @component_node.voice || default_voice || 'kal'
15
- application :speak, [engine, voice, document].join('|')
14
+ voice = @component_node.voice || :kal
15
+ application :speak, [renderer, voice, document].join('|')
16
+ end
17
+
18
+ def renderer
19
+ @component_node.renderer || :flite
16
20
  end
17
21
 
18
22
  def document
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Punchblock
4
- VERSION = "2.0.0.beta1"
4
+ VERSION = "2.0.0.beta2"
5
5
  end
@@ -10,8 +10,7 @@ module Punchblock
10
10
  :host => '127.0.0.1',
11
11
  :port => 5038,
12
12
  :username => 'test',
13
- :password => 'test',
14
- :media_engine => :swift
13
+ :password => 'test'
15
14
  }
16
15
  end
17
16
 
@@ -32,10 +31,6 @@ module Punchblock
32
31
  subject.translator.connection.should be subject
33
32
  end
34
33
 
35
- it 'should set the media engine on the translator' do
36
- subject.translator.media_engine.should be == :swift
37
- end
38
-
39
34
  describe '#run' do
40
35
  it 'starts the RubyAMI::Stream' do
41
36
  subject.ami_client.async.should_receive(:run).once do
@@ -5,15 +5,11 @@ require 'spec_helper'
5
5
  module Punchblock
6
6
  module Connection
7
7
  describe Freeswitch do
8
- let(:media_engine) { :flite }
9
- let(:default_voice) { :hal }
10
8
  let :options do
11
9
  {
12
- :host => '127.0.0.1',
13
- :port => 8021,
14
- :password => 'test',
15
- :media_engine => media_engine,
16
- :default_voice => default_voice
10
+ :host => '127.0.0.1',
11
+ :port => 8021,
12
+ :password => 'test'
17
13
  }
18
14
  end
19
15
 
@@ -33,14 +29,6 @@ module Punchblock
33
29
  subject.translator.connection.should be subject
34
30
  end
35
31
 
36
- it 'should set the media engine on the translator' do
37
- subject.translator.media_engine.should be media_engine
38
- end
39
-
40
- it 'should set the default voice on the translator' do
41
- subject.translator.default_voice.should be default_voice
42
- end
43
-
44
32
  describe '#run' do
45
33
  it 'starts a RubyFS stream' do
46
34
  # subject.should_receive(:new_fs_stream).once.with('127.0.0.1', 8021, 'test').and_return mock_stream
@@ -125,21 +125,6 @@ module Punchblock
125
125
  end
126
126
 
127
127
  describe '#handle_presence' do
128
- let :offer_xml do
129
- <<-MSG
130
- <presence to='16577@app.rayo.net/1' from='9f00061@call.rayo.net'>
131
- <offer xmlns="urn:xmpp:rayo:1" to="sip:whatever@127.0.0.1" from="sip:ylcaomxb@192.168.1.9">
132
- <header name="Max-Forwards" value="70"/>
133
- <header name="Content-Length" value="367"/>
134
- </offer>
135
- </presence>
136
- MSG
137
- end
138
-
139
- let(:example_offer) { import_stanza offer_xml }
140
-
141
- it { example_offer.should be_a Blather::Stanza::Presence }
142
-
143
128
  let :complete_xml do
144
129
  <<-MSG
145
130
  <presence to='16577@app.rayo.net/1' from='9f00061@call.rayo.net/fgh4590'>
@@ -154,9 +139,34 @@ module Punchblock
154
139
 
155
140
  it { example_complete.should be_a Blather::Stanza::Presence }
156
141
 
142
+ describe "accessing the rayo node for a presence stanza" do
143
+ it "should import the rayo node" do
144
+ example_complete.rayo_node.should be_a Punchblock::Event::Complete
145
+ end
146
+
147
+ it "should be memoized" do
148
+ example_complete.rayo_node.should be example_complete.rayo_node
149
+ end
150
+ end
151
+
157
152
  describe "presence received" do
153
+ let(:handle_presence) { connection.__send__ :handle_presence, example_event }
154
+
158
155
  describe "from an offer" do
159
- let(:handle_presence) { connection.__send__ :handle_presence, example_offer }
156
+ let :offer_xml do
157
+ <<-MSG
158
+ <presence to='16577@app.rayo.net/1' from='9f00061@call.rayo.net'>
159
+ <offer xmlns="urn:xmpp:rayo:1" to="sip:whatever@127.0.0.1" from="sip:ylcaomxb@192.168.1.9">
160
+ <header name="Max-Forwards" value="70"/>
161
+ <header name="Content-Length" value="367"/>
162
+ </offer>
163
+ </presence>
164
+ MSG
165
+ end
166
+
167
+ let(:example_event) { import_stanza offer_xml }
168
+
169
+ it { example_event.should be_a Blather::Stanza::Presence }
160
170
 
161
171
  it 'should call the event handler with the event' do
162
172
  mock_event_handler.should_receive(:call).once.with do |event|
@@ -173,16 +183,24 @@ module Punchblock
173
183
  let :irrelevant_xml do
174
184
  <<-MSG
175
185
  <presence to='16577@app.rayo.net/1' from='9f00061@call.rayo.net/fgh4590'>
176
- <foo/>
186
+ <foo bar="baz"/>
177
187
  </presence>
178
188
  MSG
179
189
  end
180
190
 
181
- let(:example_irrelevant_event) { import_stanza irrelevant_xml }
191
+ let(:example_event) { import_stanza irrelevant_xml }
192
+
193
+ it 'should not be considered to be a rayo event' do
194
+ example_event.rayo_event?.should be_false
195
+ end
196
+
197
+ it 'should have a nil rayo_node' do
198
+ example_event.rayo_node.should be_nil
199
+ end
182
200
 
183
201
  it 'should not handle the event' do
184
202
  mock_event_handler.should_receive(:call).never
185
- lambda { connection.__send__ :handle_presence, example_irrelevant_event }.should throw_symbol(:pass)
203
+ lambda { handle_presence }.should throw_symbol(:pass)
186
204
  end
187
205
  end
188
206
  end
@@ -20,9 +20,8 @@ module Punchblock
20
20
  end
21
21
 
22
22
  let(:connection) { MockConnection.new }
23
- let(:media_engine) { nil }
24
23
  let(:ami_client) { double('AMI') }
25
- let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection, media_engine }
24
+ let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection }
26
25
  let(:call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator, ami_client, connection }
27
26
 
28
27
  let :ssml_doc do
@@ -9,9 +9,8 @@ module Punchblock
9
9
  describe Input do
10
10
  include HasMockCallbackConnection
11
11
 
12
- let(:media_engine) { nil }
13
12
  let(:ami_client) { double('AMI') }
14
- let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection, media_engine }
13
+ let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection }
15
14
  let(:call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator, ami_client, connection }
16
15
  let(:original_command_options) { {} }
17
16
 
@@ -9,9 +9,8 @@ module Punchblock
9
9
  describe MRCPNativePrompt do
10
10
  include HasMockCallbackConnection
11
11
 
12
- let(:media_engine) { :unimrcp }
13
12
  let(:ami_client) { double('AMI') }
14
- let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection, media_engine }
13
+ let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection }
15
14
  let(:mock_call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator, ami_client, connection }
16
15
 
17
16
  let :ssml_doc do
@@ -9,9 +9,8 @@ module Punchblock
9
9
  describe MRCPPrompt do
10
10
  include HasMockCallbackConnection
11
11
 
12
- let(:media_engine) { :unimrcp }
13
12
  let(:ami_client) { double('AMI') }
14
- let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection, media_engine }
13
+ let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection }
15
14
  let(:mock_call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator, ami_client, connection }
16
15
 
17
16
  let :ssml_doc do
@@ -9,10 +9,10 @@ module Punchblock
9
9
  describe Output do
10
10
  include HasMockCallbackConnection
11
11
 
12
- let(:media_engine) { nil }
13
- let(:ami_client) { double('AMI') }
14
- let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection, media_engine }
15
- let(:mock_call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator, ami_client, connection }
12
+ let(:renderer) { nil }
13
+ let(:ami_client) { double('AMI') }
14
+ let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection }
15
+ let(:mock_call) { Punchblock::Translator::Asterisk::Call.new 'foo', translator, ami_client, connection }
16
16
 
17
17
  let :original_command do
18
18
  Punchblock::Component::Output.new command_options
@@ -24,8 +24,10 @@ module Punchblock
24
24
  end
25
25
  end
26
26
 
27
+ let(:command_opts) { {} }
28
+
27
29
  let :command_options do
28
- { :render_document => {:value => ssml_doc} }
30
+ { :render_document => {:value => ssml_doc}, renderer: renderer }
29
31
  end
30
32
 
31
33
  subject { Output.new original_command, mock_call }
@@ -37,8 +39,8 @@ module Punchblock
37
39
  describe '#execute' do
38
40
  before { original_command.request! }
39
41
 
40
- context 'with an invalid media engine' do
41
- let(:media_engine) { 'foobar' }
42
+ context 'with an invalid renderer' do
43
+ let(:renderer) { 'foobar' }
42
44
 
43
45
  it "should return an error and not execute any actions" do
44
46
  subject.execute
@@ -47,8 +49,8 @@ module Punchblock
47
49
  end
48
50
  end
49
51
 
50
- context 'with a media engine of :swift' do
51
- let(:media_engine) { 'swift' }
52
+ context 'with a renderer of :swift' do
53
+ let(:renderer) { 'swift' }
52
54
 
53
55
  let(:audio_filename) { 'http://foo.com/bar.mp3' }
54
56
 
@@ -59,10 +61,8 @@ module Punchblock
59
61
  end
60
62
  end
61
63
 
62
- let(:command_opts) { {} }
63
-
64
64
  let :command_options do
65
- { :render_document => {:value => ssml_doc} }.merge(command_opts)
65
+ { :render_document => {:value => ssml_doc}, renderer: renderer }.merge(command_opts)
66
66
  end
67
67
 
68
68
  def ssml_with_options(prefix = '', postfix = '')
@@ -169,8 +169,8 @@ module Punchblock
169
169
  end
170
170
  end
171
171
 
172
- context 'with a media engine of :unimrcp' do
173
- let(:media_engine) { :unimrcp }
172
+ context 'with a renderer of :unimrcp' do
173
+ let(:renderer) { :unimrcp }
174
174
 
175
175
  let(:audio_filename) { 'http://foo.com/bar.mp3' }
176
176
 
@@ -184,7 +184,7 @@ module Punchblock
184
184
  let(:command_opts) { {} }
185
185
 
186
186
  let :command_options do
187
- { :render_document => {:value => ssml_doc} }.merge(command_opts)
187
+ { :render_document => {:value => ssml_doc}, renderer: renderer }.merge(command_opts)
188
188
  end
189
189
 
190
190
  let(:synthstatus) { 'OK' }
@@ -422,8 +422,8 @@ module Punchblock
422
422
  end
423
423
  end
424
424
 
425
- [:asterisk, nil].each do |media_engine|
426
- context "with a media engine of #{media_engine.inspect}" do
425
+ [:asterisk, nil].each do |renderer|
426
+ context "with a renderer of #{renderer.inspect}" do
427
427
  def expect_playback(filename = audio_filename)
428
428
  mock_call.should_receive(:execute_agi_command).once.with('EXEC Playback', filename).and_return code: 200
429
429
  end
@@ -443,7 +443,7 @@ module Punchblock
443
443
  let(:command_opts) { {} }
444
444
 
445
445
  let :command_options do
446
- { :render_document => {:value => ssml_doc} }.merge(command_opts)
446
+ { :render_document => {:value => ssml_doc}, renderer: renderer }.merge(command_opts)
447
447
  end
448
448
 
449
449
  let :original_command do
@@ -864,35 +864,6 @@ module Punchblock
864
864
  end
865
865
  end
866
866
  end
867
-
868
- context "with a media renderer set on itself" do
869
- let(:media_engine) { :swift }
870
- let(:audio_filename) { '/foo/bar.wav' }
871
- let :ssml_doc do
872
- RubySpeech::SSML.draw do
873
- audio :src => audio_filename
874
- end
875
- end
876
-
877
- let(:command_opts) { {:renderer => :asterisk} }
878
-
879
- let :command_options do
880
- { :render_document => {:value => ssml_doc} }.merge(command_opts)
881
- end
882
-
883
- let :original_command do
884
- Punchblock::Component::Output.new command_options
885
- end
886
-
887
- let(:playbackstatus) { 'SUCCESS' }
888
- before { mock_call.stub(:channel_var).with('PLAYBACKSTATUS').and_return playbackstatus }
889
-
890
- it "should use the media renderer set and not the platform default" do
891
- expect_answered
892
- mock_call.should_receive(:execute_agi_command).once.with 'EXEC Playback', audio_filename
893
- subject.execute
894
- end
895
- end
896
867
  end
897
868
 
898
869
  describe "#execute_command" do
@@ -9,10 +9,9 @@ module Punchblock
9
9
  describe Record do
10
10
  include HasMockCallbackConnection
11
11
 
12
- let(:media_engine) { nil }
13
12
  let(:channel) { 'SIP/foo' }
14
13
  let(:ami_client) { double('AMI Client').as_null_object }
15
- let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection, media_engine }
14
+ let(:translator) { Punchblock::Translator::Asterisk.new ami_client, connection }
16
15
  let(:mock_call) { Punchblock::Translator::Asterisk::Call.new channel, translator, ami_client, connection }
17
16
 
18
17
  let :original_command do
@@ -8,9 +8,8 @@ module Punchblock
8
8
  describe Asterisk do
9
9
  let(:ami_client) { double 'RubyAMI::Client' }
10
10
  let(:connection) { double 'Connection::Asterisk', handle_event: nil }
11
- let(:media_engine) { :asterisk }
12
11
 
13
- let(:translator) { Asterisk.new ami_client, connection, media_engine }
12
+ let(:translator) { Asterisk.new ami_client, connection }
14
13
 
15
14
  subject { translator }
16
15
 
@@ -19,16 +18,6 @@ module Punchblock
19
18
 
20
19
  after { translator.terminate if translator.alive? }
21
20
 
22
- context 'with a configured media engine of :asterisk' do
23
- let(:media_engine) { :asterisk }
24
- its(:media_engine) { should be == :asterisk }
25
- end
26
-
27
- context 'with a configured media engine of :unimrcp' do
28
- let(:media_engine) { :unimrcp }
29
- its(:media_engine) { should be == :unimrcp }
30
- end
31
-
32
21
  describe '#shutdown' do
33
22
  it "instructs all calls to shutdown" do
34
23
  call = Asterisk::Call.new 'foo', subject, ami_client, connection
@@ -6,10 +6,8 @@ module Punchblock
6
6
  module Translator
7
7
  class Freeswitch
8
8
  describe Call do
9
- let(:id) { Punchblock.new_uuid }
9
+ let(:id) { Punchblock.new_uuid }
10
10
  let(:stream) { double('RubyFS::Stream').as_null_object }
11
- let(:media_engine) { 'freeswitch' }
12
- let(:default_voice) { :hal }
13
11
  let(:translator) { Freeswitch.new double('Connection::Freeswitch').as_null_object }
14
12
  let(:es_env) do
15
13
  {
@@ -165,13 +163,12 @@ module Punchblock
165
163
  }
166
164
  end
167
165
 
168
- subject { Call.new id, translator, es_env, stream, media_engine, default_voice }
166
+ subject { Call.new id, translator, es_env, stream }
169
167
 
170
- its(:id) { should be == id }
171
- its(:translator) { should be translator }
172
- its(:es_env) { should be == es_env }
173
- its(:stream) { should be stream }
174
- its(:media_engine) { should be media_engine }
168
+ its(:id) { should be == id }
169
+ its(:translator) { should be translator }
170
+ its(:es_env) { should be == es_env }
171
+ its(:stream) { should be stream }
175
172
 
176
173
  describe '#register_component' do
177
174
  it 'should make the component accessible by ID' do
@@ -777,15 +774,15 @@ module Punchblock
777
774
 
778
775
  context 'with an Output component' do
779
776
  let :command do
780
- Punchblock::Component::Output.new
777
+ Punchblock::Component::Output.new renderer: renderer
781
778
  end
782
779
 
783
780
  let(:mock_component) { Translator::Freeswitch::Component::Output.new(command, subject) }
784
781
 
785
- ['freeswitch', nil].each do |media_engine|
786
- let(:media_engine) { media_engine }
782
+ ['freeswitch', 'native', nil].each do |renderer|
783
+ let(:renderer) { renderer }
787
784
 
788
- context "with a media engine of #{media_engine}" do
785
+ context "with a renderer of #{renderer}" do
789
786
  it 'should create an Output component and execute it asynchronously' do
790
787
  Component::Output.should_receive(:new_link).once.with(command, subject).and_return mock_component
791
788
  mock_component.should_receive(:execute).once
@@ -795,50 +792,35 @@ module Punchblock
795
792
  end
796
793
  end
797
794
 
798
- context 'with the media engine of :flite' do
799
- let(:media_engine) { :flite }
795
+ context 'with the renderer of :flite' do
796
+ let(:renderer) { :flite }
800
797
 
801
798
  it 'should create a FliteOutput component and execute it asynchronously using flite and the calls default voice' do
802
799
  Component::FliteOutput.should_receive(:new_link).once.with(command, subject).and_return mock_component
803
- mock_component.should_receive(:execute).once.with(media_engine, default_voice)
800
+ mock_component.should_receive(:execute).once
804
801
  subject.execute_command command
805
802
  subject.component_with_id(mock_component.id).should be mock_component
806
803
  end
807
804
  end
808
805
 
809
- context 'with the media engine of :cepstral' do
810
- let(:media_engine) { :cepstral }
806
+ context 'with the renderer of :cepstral' do
807
+ let(:renderer) { :cepstral }
811
808
 
812
809
  it 'should create a TTSOutput component and execute it asynchronously using cepstral and the calls default voice' do
813
810
  Component::TTSOutput.should_receive(:new_link).once.with(command, subject).and_return mock_component
814
- mock_component.should_receive(:execute).once.with(media_engine, default_voice)
811
+ mock_component.should_receive(:execute).once
815
812
  subject.execute_command command
816
813
  subject.component_with_id(mock_component.id).should be mock_component
817
814
  end
818
815
  end
819
816
 
820
- context 'with the media engine of :unimrcp' do
821
- let(:media_engine) { :unimrcp }
817
+ context 'with the renderer of :unimrcp' do
818
+ let(:renderer) { :unimrcp }
822
819
 
823
820
  it 'should create a TTSOutput component and execute it asynchronously using unimrcp and the calls default voice' do
824
821
  Component::TTSOutput.should_receive(:new_link).once.with(command, subject).and_return mock_component
825
- mock_component.should_receive(:execute).once.with(media_engine, default_voice)
826
- subject.execute_command command
827
- subject.component_with_id(mock_component.id).should be mock_component
828
- end
829
- end
830
-
831
- context "with a media renderer set on the component" do
832
- let(:media_engine) { :cepstral }
833
- let(:media_renderer) { :native }
834
- let :command_with_renderer do
835
- Punchblock::Component::Output.new :renderer => media_renderer
836
- end
837
-
838
- it "should use the component media engine and not the platform one if it is set" do
839
- Component::Output.should_receive(:new_link).once.with(command_with_renderer, subject).and_return mock_component
840
822
  mock_component.should_receive(:execute).once
841
- subject.execute_command command_with_renderer
823
+ subject.execute_command command
842
824
  subject.component_with_id(mock_component.id).should be mock_component
843
825
  end
844
826
  end
@@ -9,10 +9,8 @@ module Punchblock
9
9
  describe FliteOutput do
10
10
  include HasMockCallbackConnection
11
11
 
12
- let(:media_engine) { :flite }
13
- let(:default_voice) { nil }
14
- let(:translator) { Punchblock::Translator::Freeswitch.new connection }
15
- let(:mock_call) { Punchblock::Translator::Freeswitch::Call.new 'foo', translator }
12
+ let(:translator) { Punchblock::Translator::Freeswitch.new connection }
13
+ let(:mock_call) { Punchblock::Translator::Freeswitch::Call.new 'foo', translator }
16
14
 
17
15
  let :original_command do
18
16
  Punchblock::Component::Output.new command_options
@@ -29,7 +27,7 @@ module Punchblock
29
27
  end
30
28
 
31
29
  def execute
32
- subject.execute media_engine, default_voice
30
+ subject.execute
33
31
  end
34
32
 
35
33
  subject { described_class.new original_command, mock_call }
@@ -37,7 +35,7 @@ module Punchblock
37
35
  describe '#execute' do
38
36
  before { original_command.request! }
39
37
  def expect_playback(voice = :kal)
40
- subject.wrapped_object.should_receive(:application).once.with :speak, "#{media_engine}|#{voice}|FOO"
38
+ subject.wrapped_object.should_receive(:application).once.with :speak, "flite|#{voice}|FOO"
41
39
  end
42
40
 
43
41
  let(:command_opts) { {} }
@@ -9,10 +9,8 @@ module Punchblock
9
9
  describe TTSOutput do
10
10
  include HasMockCallbackConnection
11
11
 
12
- let(:media_engine) { :flite }
13
- let(:default_voice) { :hal }
14
- let(:translator) { Punchblock::Translator::Freeswitch.new connection }
15
- let(:mock_call) { Punchblock::Translator::Freeswitch::Call.new 'foo', translator }
12
+ let(:translator) { Punchblock::Translator::Freeswitch.new connection }
13
+ let(:mock_call) { Punchblock::Translator::Freeswitch::Call.new 'foo', translator }
16
14
 
17
15
  let :original_command do
18
16
  Punchblock::Component::Output.new command_options
@@ -25,19 +23,19 @@ module Punchblock
25
23
  end
26
24
 
27
25
  let :command_options do
28
- { :render_document => {:value => ssml_doc} }
26
+ { :render_document => {:value => ssml_doc}, :renderer => :flite }
29
27
  end
30
28
 
31
29
  def execute
32
- subject.execute media_engine, default_voice
30
+ subject.execute
33
31
  end
34
32
 
35
33
  subject { described_class.new original_command, mock_call }
36
34
 
37
35
  describe '#execute' do
38
36
  before { original_command.request! }
39
- def expect_playback(voice = default_voice)
40
- subject.wrapped_object.should_receive(:application).once.with :speak, "#{media_engine}|#{voice}|#{ssml_doc}"
37
+ def expect_playback(voice = :kal, renderer = :flite)
38
+ subject.wrapped_object.should_receive(:application).once.with :speak, "#{renderer}|#{voice}|#{ssml_doc}"
41
39
  end
42
40
 
43
41
  let :ssml_doc do
@@ -6,10 +6,8 @@ module Punchblock
6
6
  module Translator
7
7
  describe Freeswitch do
8
8
  let(:connection) { double 'Connection::Freeswitch' }
9
- let(:media_engine) { :flite }
10
- let(:default_voice) { :hal }
11
9
 
12
- let(:translator) { described_class.new connection, media_engine, default_voice }
10
+ let(:translator) { described_class.new connection }
13
11
  let(:stream) { double 'RubyFS::Stream' }
14
12
 
15
13
  before { connection.should_receive(:stream).at_most(:once).and_return stream }
@@ -248,8 +246,6 @@ module Punchblock
248
246
  call.should be_a Freeswitch::Call
249
247
  call.translator.should be subject
250
248
  call.stream.should be stream
251
- call.media_engine.should be media_engine
252
- call.default_voice.should be default_voice
253
249
  end
254
250
 
255
251
  it 'should instruct the call to send a dial' do
@@ -430,8 +426,6 @@ module Punchblock
430
426
  call.should be_a Freeswitch::Call
431
427
  call.translator.should be subject
432
428
  call.stream.should be stream
433
- call.media_engine.should be media_engine
434
- call.default_voice.should be default_voice
435
429
  call.es_env.should be == {
436
430
  :variable_direction => "inbound",
437
431
  :variable_uuid => "3f0e1e18-c056-11e1-b099-fffeda3ce54f",
data/spec/spec_helper.rb CHANGED
@@ -25,7 +25,10 @@ RSpec.configure do |config|
25
25
  end
26
26
 
27
27
  config.after :each do
28
- Object.const_defined?(:Celluloid) && Celluloid.shutdown
28
+ if Object.const_defined?(:Celluloid)
29
+ Celluloid.shutdown
30
+ Celluloid.boot
31
+ end
29
32
  end
30
33
  end
31
34
 
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.0.0.beta1
4
+ version: 2.0.0.beta2
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: 2013-08-21 00:00:00.000000000 Z
13
+ date: 2013-08-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri