punchblock 0.9.1 → 0.9.2

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.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # develop
2
2
 
3
+ # v0.9.2 - 2012-02-18
4
+ * Feature: Asterisk calls receiving media commands are implicitly answered
5
+ * Bugfix: Unrenderable output documents on Asterisk should return a sensible error
6
+ * Bugfix: Log the target of commands correctly
7
+ * Bugfix: Do not wrap exceptions in ProtocolError
8
+
3
9
  # v0.9.1 - 2012-01-30
4
10
  * Bugfix: Closing an disconnected XMPP connection is a no-op
5
11
 
@@ -61,7 +61,7 @@ module Punchblock
61
61
  command.mixer_name ||= options[:mixer_name]
62
62
  command.component_id ||= options[:component_id]
63
63
  create_iq(jid_for_command(command)).tap do |iq|
64
- pb_logger.debug "Sending IQ ID #{iq.id} #{command.inspect} to #{jid}"
64
+ pb_logger.debug "Sending IQ ID #{iq.id} #{command.inspect} to #{iq.to}"
65
65
  iq << command
66
66
  end
67
67
  end
@@ -78,11 +78,6 @@ module Punchblock
78
78
  EM.run { client.run }
79
79
  rescue Blather::Stream::ConnectionFailed, Blather::Stream::ConnectionTimeout => e
80
80
  raise DisconnectedError.new(e.class.to_s, e.message)
81
- rescue => e
82
- # Preserve Punchblock native exceptions
83
- raise e if e.class.to_s =~ /^Punchblock/
84
- # Wrap everything else
85
- raise ProtocolError.new(e.class.to_s, e.message)
86
81
  end
87
82
  end
88
83
 
@@ -22,6 +22,7 @@ module Punchblock
22
22
  @channel, @translator = channel, translator
23
23
  @agi_env = parse_environment agi_env
24
24
  @id, @components = UUIDTools::UUID.random_create.to_s, {}
25
+ @answered = false
25
26
  pb_logger.debug "Starting up call with channel #{channel}, id #{@id}"
26
27
  end
27
28
 
@@ -73,6 +74,15 @@ module Punchblock
73
74
  direction == :inbound
74
75
  end
75
76
 
77
+ def answered?
78
+ @answered
79
+ end
80
+
81
+ def answer_if_not_answered
82
+ return if answered? || outbound?
83
+ execute_command Command::Answer.new
84
+ end
85
+
76
86
  def channel=(other)
77
87
  pb_logger.info "Channel is changing from #{channel} to #{other}."
78
88
  @channel = other
@@ -98,6 +108,7 @@ module Punchblock
98
108
  when '5'
99
109
  send_pb_event Event::Ringing.new
100
110
  when '6'
111
+ @answered = true
101
112
  send_pb_event Event::Answered.new
102
113
  end
103
114
  end
@@ -12,6 +12,7 @@ module Punchblock
12
12
  end
13
13
 
14
14
  def execute
15
+ @call.answer_if_not_answered
15
16
  initial_timeout = @component_node.initial_timeout || -1
16
17
  @inter_digit_timeout = @component_node.inter_digit_timeout || -1
17
18
 
@@ -11,6 +11,8 @@ module Punchblock
11
11
  end
12
12
 
13
13
  def execute
14
+ @call.answer_if_not_answered
15
+
14
16
  return with_error 'option error', 'An SSML document is required.' unless @component_node.ssml
15
17
 
16
18
  return with_error 'option error', 'An interrupt-on value of speech is unsupported.' if @component_node.interrupt_on == :speech
@@ -27,6 +29,8 @@ module Punchblock
27
29
  case node
28
30
  when RubySpeech::SSML::Audio
29
31
  lambda { current_actor.play_audio! node.src }
32
+ else
33
+ return with_error 'unrenderable document error', 'The provided document could not be rendered.'
30
34
  end
31
35
  end.compact
32
36
 
@@ -1,3 +1,3 @@
1
1
  module Punchblock
2
- VERSION = "0.9.1"
2
+ VERSION = "0.9.2"
3
3
  end
@@ -99,6 +99,49 @@ module Punchblock
99
99
  end
100
100
  end
101
101
 
102
+ describe '#answer_if_not_answered' do
103
+ let(:answer_command) { Command::Answer.new }
104
+
105
+ context "with a call that is already answered" do
106
+ it 'should not answer the call' do
107
+ subject.wrapped_object.expects(:'answered?').returns true
108
+ subject.wrapped_object.expects(:execute_command).never
109
+ subject.answer_if_not_answered
110
+ end
111
+ end
112
+
113
+ context "with an unanswered call" do
114
+ before do
115
+ subject.wrapped_object.expects(:'answered?').returns false
116
+ end
117
+
118
+ context "with a call that is outbound" do
119
+ let(:dial_command) { Command::Dial.new }
120
+
121
+ before do
122
+ dial_command.request!
123
+ subject.dial dial_command
124
+ end
125
+
126
+ it 'should not answer the call' do
127
+ subject.wrapped_object.expects(:execute_command).never
128
+ subject.answer_if_not_answered
129
+ end
130
+ end
131
+
132
+ context "with a call that is inbound" do
133
+ before do
134
+ subject.send_offer
135
+ end
136
+
137
+ it 'should answer a call that is inbound and not answered' do
138
+ subject.wrapped_object.expects(:execute_command).with(answer_command)
139
+ subject.answer_if_not_answered
140
+ end
141
+ end
142
+ end
143
+ end
144
+
102
145
  describe '#dial' do
103
146
  let(:dial_command_options) { {} }
104
147
 
@@ -354,6 +397,11 @@ module Punchblock
354
397
  translator.expects(:handle_pb_event!).with expected_ringing
355
398
  subject.process_ami_event ami_event
356
399
  end
400
+
401
+ it '#answered? should return false' do
402
+ subject.process_ami_event ami_event
403
+ subject.answered?.should be_false
404
+ end
357
405
  end
358
406
 
359
407
  context 'up' do
@@ -366,6 +414,11 @@ module Punchblock
366
414
  translator.expects(:handle_pb_event!).with expected_answered
367
415
  subject.process_ami_event ami_event
368
416
  end
417
+
418
+ it '#answered? should be true' do
419
+ subject.process_ami_event ami_event
420
+ subject.answered?.should be_true
421
+ end
369
422
  end
370
423
  end
371
424
 
@@ -40,6 +40,13 @@ module Punchblock
40
40
  describe '#execute' do
41
41
  before { command.request! }
42
42
 
43
+ it "calls answer_if_not_answered on the call" do
44
+ call.expects :answer_if_not_answered
45
+ subject.execute
46
+ end
47
+
48
+ before { call.stubs :answer_if_not_answered }
49
+
43
50
  context 'with a media engine of :unimrcp' do
44
51
  pending
45
52
  let(:media_engine) { :unimrcp }
@@ -33,6 +33,13 @@ module Punchblock
33
33
  describe '#execute' do
34
34
  before { command.request! }
35
35
 
36
+ it "calls answer_if_not_answered on the call" do
37
+ mock_call.expects :answer_if_not_answered
38
+ subject.execute
39
+ end
40
+
41
+ before { mock_call.stubs :answer_if_not_answered }
42
+
36
43
  context 'with a media engine of :unimrcp' do
37
44
  let(:media_engine) { :unimrcp }
38
45
 
@@ -247,7 +254,6 @@ module Punchblock
247
254
  let :ssml_doc do
248
255
  RubySpeech::SSML.draw do
249
256
  audio :src => audio_filename
250
- say_as(:interpret_as => :cardinal) { 'FOO' }
251
257
  end
252
258
  end
253
259
 
@@ -332,6 +338,22 @@ module Punchblock
332
338
  subject.execute
333
339
  end
334
340
  end
341
+
342
+ context "with an SSML document containing elements other than <audio/>" do
343
+ let :command_options do
344
+ {
345
+ :ssml => RubySpeech::SSML.draw do
346
+ string "FooBar"
347
+ end
348
+ }
349
+ end
350
+
351
+ it "should return an unrenderable document error" do
352
+ subject.execute
353
+ error = ProtocolError.new 'unrenderable document error', 'The provided document could not be rendered.'
354
+ command.response(0.1).should == error
355
+ end
356
+ end
335
357
  end
336
358
 
337
359
  describe 'start-offset' do
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: 0.9.1
4
+ version: 0.9.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-01-30 00:00:00.000000000 Z
14
+ date: 2012-02-18 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: niceogiri
18
- requirement: &2156532180 !ruby/object:Gem::Requirement
18
+ requirement: &2160948720 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: 0.0.4
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *2156532180
26
+ version_requirements: *2160948720
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: blather
29
- requirement: &2156531500 !ruby/object:Gem::Requirement
29
+ requirement: &2160948120 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 0.5.12
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *2156531500
37
+ version_requirements: *2160948120
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: activesupport
40
- requirement: &2156530720 !ruby/object:Gem::Requirement
40
+ requirement: &2160942420 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: 2.1.0
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *2156530720
48
+ version_requirements: *2160942420
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: state_machine
51
- requirement: &2156527320 !ruby/object:Gem::Requirement
51
+ requirement: &2160941560 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: 1.0.1
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *2156527320
59
+ version_requirements: *2160941560
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: future-resource
62
- requirement: &2156526620 !ruby/object:Gem::Requirement
62
+ requirement: &2160940660 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: 0.0.2
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *2156526620
70
+ version_requirements: *2160940660
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: has-guarded-handlers
73
- requirement: &2156525820 !ruby/object:Gem::Requirement
73
+ requirement: &2160939900 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: 0.1.0
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *2156525820
81
+ version_requirements: *2160939900
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: celluloid
84
- requirement: &2156525140 !ruby/object:Gem::Requirement
84
+ requirement: &2160939080 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: 0.6.0
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *2156525140
92
+ version_requirements: *2160939080
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: ruby_ami
95
- requirement: &2156524300 !ruby/object:Gem::Requirement
95
+ requirement: &2160938500 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: 0.1.3
101
101
  type: :runtime
102
102
  prerelease: false
103
- version_requirements: *2156524300
103
+ version_requirements: *2160938500
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: ruby_speech
106
- requirement: &2156523400 !ruby/object:Gem::Requirement
106
+ requirement: &2160937920 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: 0.5.1
112
112
  type: :runtime
113
113
  prerelease: false
114
- version_requirements: *2156523400
114
+ version_requirements: *2160937920
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: bundler
117
- requirement: &2156522860 !ruby/object:Gem::Requirement
117
+ requirement: &2160937220 !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
120
120
  - - ~>
@@ -122,10 +122,10 @@ dependencies:
122
122
  version: 1.0.0
123
123
  type: :development
124
124
  prerelease: false
125
- version_requirements: *2156522860
125
+ version_requirements: *2160937220
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: rspec
128
- requirement: &2156522160 !ruby/object:Gem::Requirement
128
+ requirement: &2160936620 !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
131
131
  - - ~>
@@ -133,10 +133,10 @@ dependencies:
133
133
  version: 2.7.0
134
134
  type: :development
135
135
  prerelease: false
136
- version_requirements: *2156522160
136
+ version_requirements: *2160936620
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: ci_reporter
139
- requirement: &2156521620 !ruby/object:Gem::Requirement
139
+ requirement: &2160935800 !ruby/object:Gem::Requirement
140
140
  none: false
141
141
  requirements:
142
142
  - - ! '>='
@@ -144,10 +144,10 @@ dependencies:
144
144
  version: 1.6.3
145
145
  type: :development
146
146
  prerelease: false
147
- version_requirements: *2156521620
147
+ version_requirements: *2160935800
148
148
  - !ruby/object:Gem::Dependency
149
149
  name: yard
150
- requirement: &2156520980 !ruby/object:Gem::Requirement
150
+ requirement: &2160935180 !ruby/object:Gem::Requirement
151
151
  none: false
152
152
  requirements:
153
153
  - - ~>
@@ -155,10 +155,10 @@ dependencies:
155
155
  version: 0.6.0
156
156
  type: :development
157
157
  prerelease: false
158
- version_requirements: *2156520980
158
+ version_requirements: *2160935180
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: rake
161
- requirement: &2156520420 !ruby/object:Gem::Requirement
161
+ requirement: &2160934640 !ruby/object:Gem::Requirement
162
162
  none: false
163
163
  requirements:
164
164
  - - ! '>='
@@ -166,10 +166,10 @@ dependencies:
166
166
  version: '0'
167
167
  type: :development
168
168
  prerelease: false
169
- version_requirements: *2156520420
169
+ version_requirements: *2160934640
170
170
  - !ruby/object:Gem::Dependency
171
171
  name: mocha
172
- requirement: &2156519840 !ruby/object:Gem::Requirement
172
+ requirement: &2160934140 !ruby/object:Gem::Requirement
173
173
  none: false
174
174
  requirements:
175
175
  - - ! '>='
@@ -177,10 +177,10 @@ dependencies:
177
177
  version: '0'
178
178
  type: :development
179
179
  prerelease: false
180
- version_requirements: *2156519840
180
+ version_requirements: *2160934140
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: i18n
183
- requirement: &2156516740 !ruby/object:Gem::Requirement
183
+ requirement: &2160933560 !ruby/object:Gem::Requirement
184
184
  none: false
185
185
  requirements:
186
186
  - - ! '>='
@@ -188,10 +188,10 @@ dependencies:
188
188
  version: '0'
189
189
  type: :development
190
190
  prerelease: false
191
- version_requirements: *2156516740
191
+ version_requirements: *2160933560
192
192
  - !ruby/object:Gem::Dependency
193
193
  name: countdownlatch
194
- requirement: &2156515500 !ruby/object:Gem::Requirement
194
+ requirement: &2160933040 !ruby/object:Gem::Requirement
195
195
  none: false
196
196
  requirements:
197
197
  - - ! '>='
@@ -199,10 +199,10 @@ dependencies:
199
199
  version: '0'
200
200
  type: :development
201
201
  prerelease: false
202
- version_requirements: *2156515500
202
+ version_requirements: *2160933040
203
203
  - !ruby/object:Gem::Dependency
204
204
  name: guard-rspec
205
- requirement: &2156514720 !ruby/object:Gem::Requirement
205
+ requirement: &2160932600 !ruby/object:Gem::Requirement
206
206
  none: false
207
207
  requirements:
208
208
  - - ! '>='
@@ -210,7 +210,7 @@ dependencies:
210
210
  version: '0'
211
211
  type: :development
212
212
  prerelease: false
213
- version_requirements: *2156514720
213
+ version_requirements: *2160932600
214
214
  description: Like Rack is to Rails and Sinatra, Punchblock provides a consistent API
215
215
  on top of several underlying third-party call control protocols.
216
216
  email: punchblock@adhearsion.com
@@ -351,7 +351,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
351
351
  version: '0'
352
352
  segments:
353
353
  - 0
354
- hash: 4401159301210104639
354
+ hash: 326151845753571314
355
355
  required_rubygems_version: !ruby/object:Gem::Requirement
356
356
  none: false
357
357
  requirements: