punchblock 1.5.3 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # [develop](https://github.com/adhearsion/punchblock)
2
2
 
3
+ # [v1.6.0](https://github.com/adhearsion/punchblock/compare/v1.5.3...v1.6.0) - [2012-11-14](https://rubygems.org/gems/punchblock/versions/1.6.0)
4
+ * Feature: Set dial headers on FreeSWITCH originate command (SIP only)
5
+ * Feature: Set dial headers on Asterisk originate command (SIP only)
6
+ * Bugfix: Headers were being re-written downcased and with underscores
7
+ * Bugfix: Ensure all numeric component attributes are written as the correct type
8
+
3
9
  # [v1.5.3](https://github.com/adhearsion/punchblock/compare/v1.5.2...v1.5.3) - [2012-11-01](https://rubygems.org/gems/punchblock/versions/1.5.3)
4
10
  * Doc: Add link to docs for unrenderable doc error
5
11
 
@@ -28,7 +28,7 @@ module Punchblock
28
28
  #
29
29
  def params_hash
30
30
  params.inject({}) do |hash, param|
31
- hash[param.name] = param.value
31
+ hash[param.name.downcase.gsub('-', '_').to_sym] = param.value
32
32
  hash
33
33
  end
34
34
  end
@@ -104,7 +104,7 @@ module Punchblock
104
104
  #
105
105
  def attributes_hash
106
106
  attributes.inject({}) do |hash, attribute|
107
- hash[attribute.name] = attribute.value
107
+ hash[attribute.name.downcase.gsub('-', '_').to_sym] = attribute.value
108
108
  hash
109
109
  end
110
110
  end
@@ -48,7 +48,7 @@ module Punchblock
48
48
  # @param [Integer] other the amount of time in milliseconds that an input command will wait until considered that a silence becomes a NO-MATCH
49
49
  #
50
50
  def max_silence=(other)
51
- write_attr :'max-silence', other
51
+ write_attr :'max-silence', other.to_i
52
52
  end
53
53
 
54
54
  ##
@@ -62,7 +62,7 @@ module Punchblock
62
62
  # @param [Float] min_confidence with which to consider a response acceptable
63
63
  #
64
64
  def min_confidence=(min_confidence)
65
- write_attr 'min-confidence', min_confidence
65
+ write_attr 'min-confidence', min_confidence.to_f
66
66
  end
67
67
 
68
68
  ##
@@ -118,7 +118,7 @@ module Punchblock
118
118
  # @param [Float] other Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
119
119
  #
120
120
  def sensitivity=(other)
121
- write_attr :sensitivity, other
121
+ write_attr :sensitivity, other.to_f
122
122
  end
123
123
 
124
124
  ##
@@ -132,7 +132,7 @@ module Punchblock
132
132
  # @param [Integer] timeout Indicates the amount of time preceding input which may expire before a timeout is triggered.
133
133
  #
134
134
  def initial_timeout=(other)
135
- write_attr :'initial-timeout', other
135
+ write_attr :'initial-timeout', other.to_f
136
136
  end
137
137
 
138
138
  ##
@@ -146,7 +146,7 @@ module Punchblock
146
146
  # @param [Integer] timeout Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
147
147
  #
148
148
  def inter_digit_timeout=(other)
149
- write_attr :'inter-digit-timeout', other
149
+ write_attr :'inter-digit-timeout', other.to_i
150
150
  end
151
151
 
152
152
  ##
@@ -98,7 +98,7 @@ module Punchblock
98
98
  # @param [Integer] other Indicates some offset through which the output should be skipped before rendering begins.
99
99
  #
100
100
  def start_offset=(other)
101
- write_attr :'start-offset', other
101
+ write_attr :'start-offset', other.to_i
102
102
  end
103
103
 
104
104
  ##
@@ -126,7 +126,7 @@ module Punchblock
126
126
  # @param [Integer] other Indicates the duration of silence that should space repeats of the rendered document.
127
127
  #
128
128
  def repeat_interval=(other)
129
- write_attr :'repeat-interval', other
129
+ write_attr :'repeat-interval', other.to_i
130
130
  end
131
131
 
132
132
  ##
@@ -140,7 +140,7 @@ module Punchblock
140
140
  # @param [Integer] other Indicates the number of times the output should be played.
141
141
  #
142
142
  def repeat_times=(other)
143
- write_attr :'repeat-times', other
143
+ write_attr :'repeat-times', other.to_i
144
144
  end
145
145
 
146
146
  ##
@@ -154,7 +154,7 @@ module Punchblock
154
154
  # @param [Integer] other Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
155
155
  #
156
156
  def max_time=(other)
157
- write_attr :'max-time', other
157
+ write_attr :'max-time', other.to_i
158
158
  end
159
159
 
160
160
  def inspect_attributes
@@ -41,7 +41,7 @@ module Punchblock
41
41
  # @param [Integer] timeout Controls the length of a period of silence after callers have spoken to conclude they finished.
42
42
  #
43
43
  def final_timeout=(timeout)
44
- write_attr :'final-timeout', timeout
44
+ write_attr :'final-timeout', timeout.to_i
45
45
  end
46
46
 
47
47
  ##
@@ -69,7 +69,7 @@ module Punchblock
69
69
  # @param [Integer] timeout Controls how long the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
70
70
  #
71
71
  def initial_timeout=(timeout)
72
- write_attr :'initial-timeout', timeout
72
+ write_attr :'initial-timeout', timeout.to_i
73
73
  end
74
74
 
75
75
  ##
@@ -83,7 +83,7 @@ module Punchblock
83
83
  # @param [Integer] other Indicates the maximum duration for the recording.
84
84
  #
85
85
  def max_duration=(other)
86
- write_attr :'max-duration', other
86
+ write_attr :'max-duration', other.to_i
87
87
  end
88
88
 
89
89
  ##
@@ -28,7 +28,7 @@ module Punchblock
28
28
  #
29
29
  def attributes_hash
30
30
  attributes.inject({}) do |hash, attribute|
31
- hash[attribute.name] = attribute.value
31
+ hash[attribute.name.downcase.gsub('-', '_').to_sym] = attribute.value
32
32
  hash
33
33
  end
34
34
  end
@@ -7,7 +7,7 @@ module Punchblock
7
7
  #
8
8
  def headers_hash
9
9
  headers.inject({}) do |hash, header|
10
- hash[header.name] = header.value
10
+ hash[header.name.downcase.gsub('-', '_').to_sym] = header.value
11
11
  hash
12
12
  end
13
13
  end
@@ -16,7 +16,6 @@ module KeyValuePairNode
16
16
  new_node.name = name
17
17
  new_node.value = value
18
18
  end
19
- new_node.name = new_node.name.downcase
20
19
  end
21
20
  end
22
21
  end
@@ -25,13 +24,13 @@ module KeyValuePairNode
25
24
  # The Header's name
26
25
  # @return [Symbol]
27
26
  def name
28
- read_attr(:name).gsub('-', '_').to_sym
27
+ read_attr :name
29
28
  end
30
29
 
31
30
  # Set the Header's name
32
31
  # @param [Symbol] name the new name for the param
33
32
  def name=(name)
34
- write_attr :name, name.to_s.gsub('_', '-')
33
+ write_attr :name, name
35
34
  end
36
35
 
37
36
  # The Header's value
@@ -61,9 +61,9 @@ module Punchblock
61
61
  :application => 'AGI',
62
62
  :data => 'agi:async',
63
63
  :channel => channel,
64
- :callerid => dial_command.from,
65
- :variable => "punchblock_call_id=#{id}"
64
+ :callerid => dial_command.from
66
65
  }
66
+ params[:variable] = variable_for_headers dial_command.headers
67
67
  params[:timeout] = dial_command.timeout unless dial_command.timeout.nil?
68
68
 
69
69
  originate_action = Punchblock::Component::Asterisk::AMI::Action.new :name => 'Originate',
@@ -297,6 +297,18 @@ module Punchblock
297
297
  accumulator
298
298
  end
299
299
  end
300
+
301
+ def variable_for_headers(headers)
302
+ variables = { :punchblock_call_id => id }
303
+ header_counter = 51
304
+ headers.each do |header|
305
+ variables["SIPADDHEADER#{header_counter}"] = "\"#{header.name}: #{header.value}\""
306
+ header_counter += 1
307
+ end
308
+ variables.inject([]) do |a, (k, v)|
309
+ a << "#{k}=#{v}"
310
+ end.join(',')
311
+ end
300
312
  end
301
313
  end
302
314
  end
@@ -139,6 +139,9 @@ module Punchblock
139
139
  options[:origination_caller_id_number] = "'#{cid_number}'" if cid_number.present?
140
140
  options[:origination_caller_id_name] = "'#{cid_name}'" if cid_name.present?
141
141
  options[:originate_timeout] = dial_command.timeout/1000 if dial_command.timeout
142
+ dial_command.headers.each do |header|
143
+ options["sip_h_#{header.name}"] = "'#{header.value}'"
144
+ end
142
145
  opts = options.inject([]) do |a, (k, v)|
143
146
  a << "#{k}=#{v}"
144
147
  end.join(',')
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Punchblock
4
- VERSION = "1.5.3"
4
+ VERSION = "1.6.0"
5
5
  end
@@ -28,8 +28,8 @@ module Punchblock
28
28
  <<-MESSAGE
29
29
  <dial to='tel:+14155551212' from='tel:+13035551212' timeout='30000' xmlns='urn:xmpp:rayo:1'>
30
30
  <join call-id="abc123" />
31
- <header name="x-skill" value="agent" />
32
- <header name="x-customer-id" value="8877" />
31
+ <header name="X-skill" value="agent" />
32
+ <header name="X-customer-id" value="8877" />
33
33
  </dial>
34
34
  MESSAGE
35
35
  end
@@ -38,6 +38,8 @@ module Punchblock
38
38
 
39
39
  it { should be_instance_of Dial }
40
40
 
41
+ it_should_behave_like 'event_headers'
42
+
41
43
  its(:to) { should be == 'tel:+14155551212' }
42
44
  its(:from) { should be == 'tel:+13035551212' }
43
45
  its(:timeout) { should be == 30000 }
@@ -34,14 +34,14 @@ module Punchblock
34
34
  it_should_behave_like 'event'
35
35
 
36
36
  its(:name) { should be == 'Originate' }
37
- its(:params) { should be == [Action::Param.new(:channel, 'SIP/101test'),
38
- Action::Param.new(:context, 'default'),
39
- Action::Param.new(:exten, '8135551212'),
40
- Action::Param.new(:priority, '1'),
41
- Action::Param.new(:callerid, '3125551212'),
42
- Action::Param.new(:timeout, '30000'),
43
- Action::Param.new(:variable, 'var1=23|var2=24|var3=25'),
44
- Action::Param.new(:async, '1')
37
+ its(:params) { should be == [Action::Param.new('Channel', 'SIP/101test'),
38
+ Action::Param.new('Context', 'default'),
39
+ Action::Param.new('Exten', '8135551212'),
40
+ Action::Param.new('Priority', '1'),
41
+ Action::Param.new('Callerid', '3125551212'),
42
+ Action::Param.new('Timeout', '30000'),
43
+ Action::Param.new('Variable', 'var1=23|var2=24|var3=25'),
44
+ Action::Param.new('Async', '1')
45
45
  ]}
46
46
 
47
47
  its(:params_hash) { should be == {:channel => 'SIP/101test',
@@ -112,7 +112,7 @@ module Punchblock
112
112
 
113
113
  its(:name) { should be == :success }
114
114
  its(:message) { should be == "Originate successfully queued" }
115
- its(:attributes) { should be == [Attribute.new(:channel, 'SIP/101-3f3f'), Attribute.new(:state, 'Ring')]}
115
+ its(:attributes) { should be == [Attribute.new('Channel', 'SIP/101-3f3f'), Attribute.new('State', 'Ring')]}
116
116
  its(:attributes_hash) { should be == {:channel => 'SIP/101-3f3f', :state => 'Ring'} }
117
117
 
118
118
  describe "when setting options in initializer" do
@@ -14,8 +14,8 @@ module Punchblock
14
14
  <<-MESSAGE
15
15
  <answered xmlns='urn:xmpp:rayo:1'>
16
16
  <!-- Signaling (e.g. SIP) Headers -->
17
- <header name="x-skill" value="agent" />
18
- <header name="x-customer-id" value="8877" />
17
+ <header name="X-skill" value="agent" />
18
+ <header name="X-customer-id" value="8877" />
19
19
  </answered>
20
20
  MESSAGE
21
21
  end
@@ -35,7 +35,7 @@ module Punchblock
35
35
  Answered.new :headers => { :x_skill => "agent", :x_customer_id => "8877" }
36
36
  end
37
37
 
38
- it_should_behave_like 'event_headers'
38
+ it_should_behave_like 'command_headers'
39
39
  end
40
40
  end
41
41
  end
@@ -30,7 +30,7 @@ module Punchblock
30
30
  it_should_behave_like 'event'
31
31
 
32
32
  its(:name) { should be == 'Newchannel' }
33
- its(:attributes) { should be == [Event::Attribute.new(:channel, 'SIP/101-3f3f'), Event::Attribute.new(:state, 'Ring'), Event::Attribute.new(:callerid, '101'), Event::Attribute.new(:uniqueid, '1094154427.10')]}
33
+ its(:attributes) { should be == [Event::Attribute.new('Channel', 'SIP/101-3f3f'), Event::Attribute.new('State', 'Ring'), Event::Attribute.new('Callerid', '101'), Event::Attribute.new('Uniqueid', '1094154427.10')]}
34
34
  its(:attributes_hash) { should be == {:channel => 'SIP/101-3f3f', :state => 'Ring', :callerid => '101', :uniqueid => '1094154427.10'} }
35
35
  end
36
36
 
@@ -15,8 +15,8 @@ module Punchblock
15
15
  <end xmlns="urn:xmpp:rayo:1">
16
16
  <timeout />
17
17
  <!-- Signaling (e.g. SIP) Headers -->
18
- <header name="x-skill" value="agent" />
19
- <header name="x-customer-id" value="8877" />
18
+ <header name="X-skill" value="agent" />
19
+ <header name="X-customer-id" value="8877" />
20
20
  </end>
21
21
  MESSAGE
22
22
  end
@@ -39,7 +39,7 @@ module Punchblock
39
39
  end
40
40
 
41
41
  its(:reason) { should be == :hangup }
42
- it_should_behave_like 'event_headers'
42
+ it_should_behave_like 'command_headers'
43
43
  end
44
44
  end
45
45
  end
@@ -16,8 +16,8 @@ module Punchblock
16
16
  to='tel:+18003211212'
17
17
  from='tel:+13058881212'>
18
18
  <!-- Signaling (e.g. SIP) Headers -->
19
- <header name="x-skill" value="agent" />
20
- <header name="x-customer-id" value="8877" />
19
+ <header name="X-skill" value="agent" />
20
+ <header name="X-customer-id" value="8877" />
21
21
  </offer>
22
22
  MESSAGE
23
23
  end
@@ -40,7 +40,7 @@ module Punchblock
40
40
  :headers => { :x_skill => "agent", :x_customer_id => "8877" }
41
41
  end
42
42
 
43
- it_should_behave_like 'event_headers'
43
+ it_should_behave_like 'command_headers'
44
44
 
45
45
  its(:to) { should be == 'tel:+18003211212' }
46
46
  its(:from) { should be == 'tel:+13058881212' }
@@ -14,8 +14,8 @@ module Punchblock
14
14
  <<-MESSAGE
15
15
  <ringing xmlns='urn:xmpp:rayo:1'>
16
16
  <!-- Signaling (e.g. SIP) Headers -->
17
- <header name="x-skill" value="agent" />
18
- <header name="x-customer-id" value="8877" />
17
+ <header name="X-skill" value="agent" />
18
+ <header name="X-customer-id" value="8877" />
19
19
  </ringing>
20
20
  MESSAGE
21
21
  end
@@ -35,7 +35,7 @@ module Punchblock
35
35
  Ringing.new :headers => { :x_skill => "agent", :x_customer_id => "8877" }
36
36
  end
37
37
 
38
- it_should_behave_like 'event_headers'
38
+ it_should_behave_like 'command_headers'
39
39
  end
40
40
  end
41
41
  end
@@ -4,43 +4,8 @@ require 'spec_helper'
4
4
 
5
5
  module Punchblock
6
6
  describe Header do
7
- it 'will auto-inherit nodes' do
8
- n = parse_stanza "<header name='boo' value='bah' />"
9
- h = Header.new n.root
10
- h.name.should be == :boo
11
- h.value.should be == 'bah'
12
- end
7
+ let(:element_name) { 'header' }
13
8
 
14
- it 'has a name attribute' do
15
- n = Header.new :boo, 'bah'
16
- n.name.should be == :boo
17
- n.name = :foo
18
- n.name.should be == :foo
19
- end
20
-
21
- it "substitutes - for _ on the name attribute when reading" do
22
- n = parse_stanza "<header name='boo-bah' value='foo' />"
23
- h = Header.new n.root
24
- h.name.should be == :boo_bah
25
- end
26
-
27
- it "substitutes _ for - on the name attribute when writing" do
28
- h = Header.new :boo_bah, 'foo'
29
- h.to_xml.should be == '<header name="boo-bah" value="foo"/>'
30
- end
31
-
32
- it 'has a value attribute' do
33
- n = Header.new :boo, 'en'
34
- n.value.should be == 'en'
35
- n.value = 'de'
36
- n.value.should be == 'de'
37
- end
38
-
39
- it 'can determine equality' do
40
- a = Header.new :boo, 'bah'
41
- a.should be == Header.new(:boo, 'bah')
42
- a.should_not be == Header.new(:bah, 'bah')
43
- a.should_not be == Header.new(:boo, 'boo')
44
- end
9
+ it_should_behave_like 'key_value_pairs'
45
10
  end
46
11
  end # Punchblock
@@ -215,6 +215,27 @@ module Punchblock
215
215
  end
216
216
  end
217
217
 
218
+ context 'with headers specified' do
219
+ let :dial_command_options do
220
+ { :headers => {'X-foo' => 'bar', 'X-doo' => 'dah'} }
221
+ end
222
+
223
+ it 'includes the headers in the Originate AMI action' do
224
+ expected_action = Punchblock::Component::Asterisk::AMI::Action.new(:name => 'Originate',
225
+ :params => {
226
+ :async => true,
227
+ :application => 'AGI',
228
+ :data => 'agi:async',
229
+ :channel => 'SIP/1234',
230
+ :callerid => 'sip:foo@bar.com',
231
+ :variable => "punchblock_call_id=#{subject.id},SIPADDHEADER51=\"X-foo: bar\",SIPADDHEADER52=\"X-doo: dah\""
232
+ }).tap { |a| a.request! }
233
+
234
+ translator.expects(:execute_global_command!).once.with expected_action
235
+ subject.dial dial_command
236
+ end
237
+ end
238
+
218
239
  it 'sends the call ID as a response to the Dial' do
219
240
  subject.dial dial_command
220
241
  dial_command.response
@@ -290,6 +290,17 @@ module Punchblock
290
290
  end
291
291
  end
292
292
 
293
+ context 'with headers specified' do
294
+ let :dial_command_options do
295
+ { :headers => {'X-foo' => 'bar', 'X-doo' => 'dah'} }
296
+ end
297
+
298
+ it 'includes the headers in the originate command' do
299
+ stream.expects(:bgapi).once.with "originate {return_ring_ready=true,origination_uuid=#{subject.id},origination_caller_id_number='#{from}',sip_h_X-foo='bar',sip_h_X-doo='dah'}#{to} &park()"
300
+ subject.dial dial_command
301
+ end
302
+ end
303
+
293
304
  it 'sends the call ID as a response to the Dial' do
294
305
  subject.dial dial_command
295
306
  dial_command.response
data/spec/spec_helper.rb CHANGED
@@ -55,47 +55,36 @@ shared_examples_for 'command_headers' do
55
55
  end
56
56
 
57
57
  shared_examples_for 'event_headers' do
58
- its(:headers) { should be == [Punchblock::Header.new(:x_skill, 'agent'), Punchblock::Header.new(:x_customer_id, '8877')]}
58
+ its(:headers) { should be == [Punchblock::Header.new('X-skill', 'agent'), Punchblock::Header.new('X-customer-id', '8877')]}
59
59
  its(:headers_hash) { should be == {:x_skill => 'agent', :x_customer_id => '8877'} }
60
60
  end
61
61
 
62
62
  shared_examples_for 'key_value_pairs' do
63
63
  it 'will auto-inherit nodes' do
64
64
  n = parse_stanza "<#{element_name} name='boo' value='bah' />"
65
- h = class_name.new n.root
66
- h.name.should be == :boo
65
+ h = described_class.new n.root
66
+ h.name.should be == 'boo'
67
67
  h.value.should be == 'bah'
68
68
  end
69
69
 
70
70
  it 'has a name attribute' do
71
- n = class_name.new :boo, 'bah'
72
- n.name.should be == :boo
71
+ n = described_class.new :boo, 'bah'
72
+ n.name.should be == 'boo'
73
73
  n.name = :foo
74
- n.name.should be == :foo
75
- end
76
-
77
- it "substitutes - for _ on the name attribute when reading" do
78
- n = parse_stanza "<#{element_name} name='boo-bah' value='foo' />"
79
- h = class_name.new n.root
80
- h.name.should be == :boo_bah
81
- end
82
-
83
- it "substitutes _ for - on the name attribute when writing" do
84
- h = class_name.new :boo_bah, 'foo'
85
- h.to_xml.should be == "<#{element_name} name=\"boo-bah\" value=\"foo\"/>"
74
+ n.name.should be == 'foo'
86
75
  end
87
76
 
88
77
  it 'has a value param' do
89
- n = class_name.new :boo, 'en'
78
+ n = described_class.new :boo, 'en'
90
79
  n.value.should be == 'en'
91
80
  n.value = 'de'
92
81
  n.value.should be == 'de'
93
82
  end
94
83
 
95
84
  it 'can determine equality' do
96
- a = class_name.new :boo, 'bah'
97
- a.should be == class_name.new(:boo, 'bah')
98
- a.should_not be == class_name.new(:bah, 'bah')
99
- a.should_not be == class_name.new(:boo, 'boo')
85
+ a = described_class.new :boo, 'bah'
86
+ a.should be == described_class.new(:boo, 'bah')
87
+ a.should_not be == described_class.new(:bah, 'bah')
88
+ a.should_not be == described_class.new(:boo, 'boo')
100
89
  end
101
90
  end
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: 1.5.3
4
+ version: 1.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-11-01 00:00:00.000000000 Z
14
+ date: 2012-11-14 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: niceogiri
@@ -515,7 +515,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
515
515
  version: '0'
516
516
  segments:
517
517
  - 0
518
- hash: -3789580734338132722
518
+ hash: 1883502262727865241
519
519
  required_rubygems_version: !ruby/object:Gem::Requirement
520
520
  none: false
521
521
  requirements:
@@ -524,7 +524,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
524
524
  version: 1.3.7
525
525
  requirements: []
526
526
  rubyforge_project: punchblock
527
- rubygems_version: 1.8.23
527
+ rubygems_version: 1.8.24
528
528
  signing_key:
529
529
  specification_version: 3
530
530
  summary: Punchblock is a telephony middleware library