punchblock 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/.travis.yml +3 -3
  2. data/CHANGELOG.md +23 -0
  3. data/lib/punchblock.rb +24 -0
  4. data/lib/punchblock/command/reject.rb +10 -2
  5. data/lib/punchblock/component/record.rb +16 -0
  6. data/lib/punchblock/core_ext/blather/stanza.rb +3 -1
  7. data/lib/punchblock/dead_actor_safety.rb +9 -0
  8. data/lib/punchblock/event/complete.rb +9 -11
  9. data/lib/punchblock/rayo_node.rb +4 -0
  10. data/lib/punchblock/translator/asterisk.rb +65 -22
  11. data/lib/punchblock/translator/asterisk/call.rb +49 -30
  12. data/lib/punchblock/translator/asterisk/component.rb +6 -8
  13. data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +13 -20
  14. data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +1 -1
  15. data/lib/punchblock/translator/asterisk/component/input.rb +3 -6
  16. data/lib/punchblock/translator/asterisk/component/output.rb +40 -45
  17. data/lib/punchblock/translator/asterisk/component/record.rb +1 -1
  18. data/lib/punchblock/translator/asterisk/component/stop_by_redirect.rb +5 -2
  19. data/lib/punchblock/version.rb +1 -1
  20. data/punchblock.gemspec +5 -5
  21. data/spec/punchblock/command/reject_spec.rb +7 -1
  22. data/spec/punchblock/command_node_spec.rb +5 -2
  23. data/spec/punchblock/component/component_node_spec.rb +4 -0
  24. data/spec/punchblock/component/output_spec.rb +1 -1
  25. data/spec/punchblock/component/record_spec.rb +30 -0
  26. data/spec/punchblock/event/complete_spec.rb +10 -0
  27. data/spec/punchblock/translator/asterisk/call_spec.rb +191 -48
  28. data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +6 -39
  29. data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +3 -3
  30. data/spec/punchblock/translator/asterisk/component/input_spec.rb +8 -3
  31. data/spec/punchblock/translator/asterisk/component/output_spec.rb +153 -46
  32. data/spec/punchblock/translator/asterisk/component/record_spec.rb +6 -5
  33. data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +1 -2
  34. data/spec/punchblock/translator/asterisk/component_spec.rb +1 -0
  35. data/spec/punchblock/translator/asterisk_spec.rb +147 -12
  36. data/spec/punchblock_spec.rb +34 -0
  37. data/spec/spec_helper.rb +5 -1
  38. metadata +30 -20
@@ -33,13 +33,14 @@ module Punchblock
33
33
 
34
34
  before { original_command.request! }
35
35
 
36
- it "calls answer_if_not_answered on the call" do
37
- mock_call.expects :send_ami_action!
38
- mock_call.expects :answer_if_not_answered
36
+ it "returns an error if the call is not answered yet" do
37
+ mock_call.expects(:answered?).returns(false)
39
38
  subject.execute
39
+ error = ProtocolError.new.setup 'option error', 'Record cannot be used on a call that is not answered.'
40
+ original_command.response(0.1).should be == error
40
41
  end
41
42
 
42
- before { mock_call.stubs :answer_if_not_answered }
43
+ before { mock_call.stubs(:answered?).returns(true) }
43
44
 
44
45
  it "sets command response to a reference to the component" do
45
46
  mock_call.expects(:send_ami_action!)
@@ -321,8 +322,8 @@ module Punchblock
321
322
  let(:command) { Punchblock::Component::Stop.new }
322
323
 
323
324
  before do
324
- mock_call.expects :answer_if_not_answered
325
325
  mock_call.expects :send_ami_action!
326
+ mock_call.expects(:answered?).returns(true)
326
327
  command.request!
327
328
  original_command.request!
328
329
  subject.execute
@@ -12,7 +12,7 @@ module Punchblock
12
12
  include StopByRedirect
13
13
  end
14
14
 
15
- let(:mock_call) { mock('Call') }
15
+ let(:mock_call) { mock 'Call', :id => 'foo' }
16
16
  subject { MockComponent.new Hash.new, mock_call }
17
17
 
18
18
  describe "#execute_command" do
@@ -21,7 +21,6 @@ module Punchblock
21
21
 
22
22
  before { command.request! }
23
23
  it "returns a ProtocolError response" do
24
- mock_call.expects(:id)
25
24
  subject.execute_command command
26
25
  command.response(0.1).should be_a ProtocolError
27
26
  end
@@ -67,6 +67,7 @@ module Punchblock
67
67
  it "should cause the actor to be shut down" do
68
68
  subject.wrapped_object.stubs(:send_event).returns true
69
69
  subject.send_complete_event reason
70
+ sleep 0.2
70
71
  subject.should_not be_alive
71
72
  end
72
73
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'spec_helper'
4
+ require 'ostruct'
4
5
 
5
6
  module Punchblock
6
7
  module Translator
@@ -38,6 +39,7 @@ module Punchblock
38
39
 
39
40
  it "terminates the actor" do
40
41
  subject.shutdown
42
+ sleep 0.2
41
43
  subject.should_not be_alive
42
44
  end
43
45
  end
@@ -98,6 +100,29 @@ module Punchblock
98
100
  end
99
101
  end
100
102
 
103
+ describe '#deregister_call' do
104
+ let(:call_id) { 'abc123' }
105
+ let(:channel) { 'SIP/foo' }
106
+ let(:call) { Translator::Asterisk::Call.new channel, subject }
107
+
108
+ before do
109
+ call.stubs(:id).returns call_id
110
+ subject.register_call call
111
+ end
112
+
113
+ it 'should make the call inaccessible by ID' do
114
+ subject.call_with_id(call_id).should be call
115
+ subject.deregister_call call
116
+ subject.call_with_id(call_id).should be_nil
117
+ end
118
+
119
+ it 'should make the call inaccessible by channel' do
120
+ subject.call_for_channel(channel).should be call
121
+ subject.deregister_call call
122
+ subject.call_for_channel(channel).should be_nil
123
+ end
124
+ end
125
+
101
126
  describe '#register_component' do
102
127
  let(:component_id) { 'abc123' }
103
128
  let(:component) { mock 'Asterisk::Component::Asterisk::AMIAction', :id => component_id }
@@ -110,16 +135,14 @@ module Punchblock
110
135
 
111
136
  describe '#execute_call_command' do
112
137
  let(:call_id) { 'abc123' }
113
- let(:call) { Translator::Asterisk::Call.new 'SIP/foo', subject }
114
138
  let(:command) { Command::Answer.new.tap { |c| c.target_call_id = call_id } }
115
139
 
116
- before do
117
- command.request!
118
- call.stubs(:id).returns call_id
119
- end
120
-
121
140
  context "with a known call ID" do
141
+ let(:call) { Translator::Asterisk::Call.new 'SIP/foo', subject }
142
+
122
143
  before do
144
+ command.request!
145
+ call.stubs(:id).returns call_id
123
146
  subject.register_call call
124
147
  end
125
148
 
@@ -129,10 +152,84 @@ module Punchblock
129
152
  end
130
153
  end
131
154
 
155
+ let :end_error_event do
156
+ Punchblock::Event::End.new.tap do |e|
157
+ e.target_call_id = call_id
158
+ e.reason = :error
159
+ end
160
+ end
161
+
162
+ context "for an outgoing call which began executing but crashed" do
163
+ let(:dial_command) { Command::Dial.new :to => 'SIP/1234', :from => 'abc123' }
164
+
165
+ let(:call_id) { dial_command.response.id }
166
+
167
+ before do
168
+ subject.execute_command dial_command
169
+ ami_client.stub_everything
170
+ end
171
+
172
+ it 'sends an error in response to the command' do
173
+ call = subject.call_with_id call_id
174
+
175
+ call.wrapped_object.define_singleton_method(:oops) do
176
+ raise 'Woops, I died'
177
+ end
178
+
179
+ connection.expects(:handle_event).once.with end_error_event
180
+
181
+ lambda { call.oops }.should raise_error(/Woops, I died/)
182
+ sleep 0.1
183
+ call.should_not be_alive
184
+ subject.call_with_id(call_id).should be_nil
185
+
186
+ command.request!
187
+ subject.execute_call_command command
188
+ command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{call_id}", call_id)
189
+ end
190
+ end
191
+
192
+ context "for an incoming call which began executing but crashed" do
193
+ let :ami_event do
194
+ RubyAMI::Event.new('AsyncAGI').tap do |e|
195
+ e['SubEvent'] = "Start"
196
+ e['Channel'] = "SIP/1234-00000000"
197
+ 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"
198
+ end
199
+ end
200
+
201
+ let(:call) { subject.call_for_channel('SIP/1234-00000000') }
202
+ let(:call_id) { call.id }
203
+
204
+ before do
205
+ connection.expects(:handle_event).at_least(1)
206
+ subject.handle_ami_event ami_event
207
+ call_id
208
+ end
209
+
210
+ it 'sends an error in response to the command' do
211
+ call.wrapped_object.define_singleton_method(:oops) do
212
+ raise 'Woops, I died'
213
+ end
214
+
215
+ connection.expects(:handle_event).once.with end_error_event
216
+
217
+ lambda { call.oops }.should raise_error(/Woops, I died/)
218
+ sleep 0.1
219
+ call.should_not be_alive
220
+ subject.call_with_id(call_id).should be_nil
221
+
222
+ command.request!
223
+ subject.execute_call_command command
224
+ command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{call_id}", call_id)
225
+ end
226
+ end
227
+
132
228
  context "with an unknown call ID" do
133
229
  it 'sends an error in response to the command' do
230
+ command.request!
134
231
  subject.execute_call_command command
135
- command.response.should be == ProtocolError.new.setup('call-not-found', "Could not find a call with ID #{call_id}", call_id, nil)
232
+ command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{call_id}", call_id, nil)
136
233
  end
137
234
  end
138
235
  end
@@ -161,7 +258,7 @@ module Punchblock
161
258
  context "with an unknown component ID" do
162
259
  it 'sends an error in response to the command' do
163
260
  subject.execute_component_command command
164
- command.response.should be == ProtocolError.new.setup('component-not-found', "Could not find a component with ID #{component_id}", nil, component_id)
261
+ command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{component_id}", nil, component_id)
165
262
  end
166
263
  end
167
264
  end
@@ -185,7 +282,7 @@ module Punchblock
185
282
 
186
283
  it 'should instruct the call to send a dial' do
187
284
  mock_call = stub_everything 'Asterisk::Call'
188
- Asterisk::Call.expects(:new).once.returns mock_call
285
+ Asterisk::Call.expects(:new_link).once.returns mock_call
189
286
  mock_call.expects(:dial!).once.with command
190
287
  subject.execute_global_command command
191
288
  end
@@ -324,6 +421,7 @@ module Punchblock
324
421
  it 'should instruct the call to send an offer' do
325
422
  mock_call = stub_everything 'Asterisk::Call'
326
423
  Asterisk::Call.expects(:new).once.returns mock_call
424
+ subject.wrapped_object.expects(:link)
327
425
  mock_call.expects(:send_offer!).once
328
426
  subject.handle_ami_event ami_event
329
427
  end
@@ -452,12 +550,10 @@ module Punchblock
452
550
  end
453
551
 
454
552
  before do
455
- subject.wrapped_object.stubs :handle_pb_event
456
553
  subject.register_call call
457
554
  end
458
555
 
459
556
  it 'sends the AMI event to the call and to the connection as a PB event' do
460
- subject.wrapped_object.expects(:handle_pb_event).once
461
557
  call.expects(:process_ami_event!).once.with ami_event
462
558
  subject.handle_ami_event ami_event
463
559
  end
@@ -480,7 +576,6 @@ module Punchblock
480
576
  before { subject.register_call call2 }
481
577
 
482
578
  it 'should send the event to both calls and to the connection once as a PB event' do
483
- subject.wrapped_object.expects(:handle_pb_event).once
484
579
  call.expects(:process_ami_event!).once.with ami_event
485
580
  call2.expects(:process_ami_event!).once.with ami_event
486
581
  subject.handle_ami_event ami_event
@@ -498,10 +593,50 @@ module Punchblock
498
593
  end
499
594
 
500
595
  describe '#run_at_fully_booted' do
596
+ let(:passed_show) do
597
+ OpenStruct.new({:text_body => "[ Context 'adhearsion-redirect' created by 'pbx_config' ]\n '1' => 1. AGI(agi:async)[pbx_config]\n\n-= 1 extension (1 priority) in 1 context. =-"})
598
+ end
599
+
600
+ let(:failed_show) do
601
+ OpenStruct.new({:text_body => "There is no existence of 'adhearsion-redirect' context\nCommand 'dialplan show adhearsion-redirect' failed."})
602
+ end
603
+
501
604
  it 'should send the redirect extension Command to the AMI client' do
502
605
  ami_client.expects(:send_action).once.with 'Command', 'Command' => "dialplan add extension #{Asterisk::REDIRECT_EXTENSION},#{Asterisk::REDIRECT_PRIORITY},AGI,agi:async into #{Asterisk::REDIRECT_CONTEXT}"
606
+ ami_client.expects(:send_action).once.with('Command', 'Command' => "dialplan show #{Asterisk::REDIRECT_CONTEXT}")
503
607
  subject.run_at_fully_booted
504
608
  end
609
+
610
+ it 'should check the context for existence and do nothing if it is there' do
611
+ ami_client.expects(:send_action).once.with 'Command', 'Command' => "dialplan add extension #{Asterisk::REDIRECT_EXTENSION},#{Asterisk::REDIRECT_PRIORITY},AGI,agi:async into #{Asterisk::REDIRECT_CONTEXT}"
612
+ ami_client.expects(:send_action).once.with('Command', 'Command' => "dialplan show #{Asterisk::REDIRECT_CONTEXT}").yields(passed_show)
613
+ subject.run_at_fully_booted
614
+ end
615
+
616
+ it 'should check the context for existence and log an error if it is not there' do
617
+ ami_client.expects(:send_action).once.with 'Command', 'Command' => "dialplan add extension #{Asterisk::REDIRECT_EXTENSION},#{Asterisk::REDIRECT_PRIORITY},AGI,agi:async into #{Asterisk::REDIRECT_CONTEXT}"
618
+ ami_client.expects(:send_action).once.with('Command', 'Command' => "dialplan show #{Asterisk::REDIRECT_CONTEXT}").yields(failed_show)
619
+ Punchblock.logger.expects(:error).once.with("Punchblock failed to add the #{Asterisk::REDIRECT_EXTENSION} extension to the #{Asterisk::REDIRECT_CONTEXT} context. Please add a [#{Asterisk::REDIRECT_CONTEXT}] entry to your dialplan.")
620
+ subject.run_at_fully_booted
621
+ end
622
+ end
623
+
624
+ describe '#check_recording_directory' do
625
+ let(:broken_path) { "/this/is/not/a/valid/path" }
626
+ before do
627
+ @new_constant = broken_path
628
+ @old_constant = Punchblock::Translator::Asterisk::Component::Record::RECORDING_BASE_PATH
629
+ Punchblock::Translator::Asterisk::Component::Record.__send__(:remove_const,'RECORDING_BASE_PATH')
630
+ Punchblock::Translator::Asterisk::Component::Record.const_set('RECORDING_BASE_PATH', @new_constant)
631
+ end
632
+ after do
633
+ Punchblock::Translator::Asterisk::Component::Record.__send__(:remove_const,'RECORDING_BASE_PATH')
634
+ Punchblock::Translator::Asterisk::Component::Record.const_set('RECORDING_BASE_PATH', @old_constant)
635
+ end
636
+ it 'logs a warning if the recording directory does not exist' do
637
+ Punchblock.logger.expects(:warning).once.with("Recordings directory #{broken_path} does not exist. Recording might not work. This warning can be ignored if Adhearsion is running on a separate machine than Asterisk. See http://adhearsion.com/docs/call-controllers#recording")
638
+ subject.check_recording_directory
639
+ end
505
640
  end
506
641
  end
507
642
  end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Punchblock do
4
+ describe '#client_with_connection' do
5
+ context 'with :XMPP' do
6
+ it 'sets up an XMPP connection, passing options, and a client with the connection attached' do
7
+ mock_connection = stub_everything 'Connection'
8
+ options = {:username => 'foo', :password => 'bar'}
9
+ Punchblock::Connection::XMPP.expects(:new).once.with(options).returns mock_connection
10
+ client = Punchblock.client_with_connection :XMPP, options
11
+ client.should be_a Punchblock::Client
12
+ client.connection.should be mock_connection
13
+ end
14
+ end
15
+
16
+ context 'with :asterisk' do
17
+ it 'sets up an Asterisk connection, passing options, and a client with the connection attached' do
18
+ mock_connection = stub_everything 'Connection'
19
+ options = {:username => 'foo', :password => 'bar'}
20
+ Punchblock::Connection::Asterisk.expects(:new).once.with(options).returns mock_connection
21
+ client = Punchblock.client_with_connection :asterisk, options
22
+ client.should be_a Punchblock::Client
23
+ client.connection.should be mock_connection
24
+ end
25
+ end
26
+
27
+ context 'with :yate' do
28
+ it 'raises ArgumentError' do
29
+ options = {:username => 'foo', :password => 'bar'}
30
+ lambda { Punchblock.client_with_connection :yate, options }.should raise_error(ArgumentError)
31
+ end
32
+ end
33
+ end
34
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'punchblock'
4
- require 'mocha'
5
4
  require 'countdownlatch'
6
5
  require 'logger'
7
6
 
@@ -31,6 +30,11 @@ def import_stanza(xml)
31
30
  Blather::Stanza.import parse_stanza(xml).root
32
31
  end
33
32
 
33
+ def stub_uuids(value)
34
+ RubyAMI.stubs :new_uuid => value
35
+ Punchblock.stubs :new_uuid => value
36
+ end
37
+
34
38
  # FIXME: change this to rayo_event? It can be ambigous
35
39
  shared_examples_for 'event' do
36
40
  its(:target_call_id) { should be == '9f00061' }
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.2.0
4
+ version: 1.3.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-04-29 00:00:00.000000000 Z
14
+ date: 2012-07-22 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: niceogiri
@@ -132,7 +132,10 @@ dependencies:
132
132
  requirements:
133
133
  - - ~>
134
134
  - !ruby/object:Gem::Version
135
- version: '1.0'
135
+ version: '1.2'
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: 1.2.1
136
139
  type: :runtime
137
140
  prerelease: false
138
141
  version_requirements: !ruby/object:Gem::Requirement
@@ -140,7 +143,10 @@ dependencies:
140
143
  requirements:
141
144
  - - ~>
142
145
  - !ruby/object:Gem::Version
143
- version: '1.0'
146
+ version: '1.2'
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: 1.2.1
144
150
  - !ruby/object:Gem::Dependency
145
151
  name: ruby_speech
146
152
  requirement: !ruby/object:Gem::Requirement
@@ -162,17 +168,17 @@ dependencies:
162
168
  requirement: !ruby/object:Gem::Requirement
163
169
  none: false
164
170
  requirements:
165
- - - ! '>='
171
+ - - ~>
166
172
  - !ruby/object:Gem::Version
167
- version: 1.0.0
173
+ version: '1.0'
168
174
  type: :development
169
175
  prerelease: false
170
176
  version_requirements: !ruby/object:Gem::Requirement
171
177
  none: false
172
178
  requirements:
173
- - - ! '>='
179
+ - - ~>
174
180
  - !ruby/object:Gem::Version
175
- version: 1.0.0
181
+ version: '1.0'
176
182
  - !ruby/object:Gem::Dependency
177
183
  name: rspec
178
184
  requirement: !ruby/object:Gem::Requirement
@@ -180,7 +186,7 @@ dependencies:
180
186
  requirements:
181
187
  - - ~>
182
188
  - !ruby/object:Gem::Version
183
- version: 2.7.0
189
+ version: '2.7'
184
190
  type: :development
185
191
  prerelease: false
186
192
  version_requirements: !ruby/object:Gem::Requirement
@@ -188,39 +194,39 @@ dependencies:
188
194
  requirements:
189
195
  - - ~>
190
196
  - !ruby/object:Gem::Version
191
- version: 2.7.0
197
+ version: '2.7'
192
198
  - !ruby/object:Gem::Dependency
193
199
  name: ci_reporter
194
200
  requirement: !ruby/object:Gem::Requirement
195
201
  none: false
196
202
  requirements:
197
- - - ! '>='
203
+ - - ~>
198
204
  - !ruby/object:Gem::Version
199
- version: 1.6.3
205
+ version: '1.6'
200
206
  type: :development
201
207
  prerelease: false
202
208
  version_requirements: !ruby/object:Gem::Requirement
203
209
  none: false
204
210
  requirements:
205
- - - ! '>='
211
+ - - ~>
206
212
  - !ruby/object:Gem::Version
207
- version: 1.6.3
213
+ version: '1.6'
208
214
  - !ruby/object:Gem::Dependency
209
215
  name: yard
210
216
  requirement: !ruby/object:Gem::Requirement
211
217
  none: false
212
218
  requirements:
213
- - - ! '>='
219
+ - - ~>
214
220
  - !ruby/object:Gem::Version
215
- version: 0.6.0
221
+ version: '0.6'
216
222
  type: :development
217
223
  prerelease: false
218
224
  version_requirements: !ruby/object:Gem::Requirement
219
225
  none: false
220
226
  requirements:
221
- - - ! '>='
227
+ - - ~>
222
228
  - !ruby/object:Gem::Version
223
- version: 0.6.0
229
+ version: '0.6'
224
230
  - !ruby/object:Gem::Dependency
225
231
  name: rake
226
232
  requirement: !ruby/object:Gem::Requirement
@@ -368,6 +374,7 @@ files:
368
374
  - lib/punchblock/core_ext/blather/stanza.rb
369
375
  - lib/punchblock/core_ext/blather/stanza/presence.rb
370
376
  - lib/punchblock/core_ext/ruby.rb
377
+ - lib/punchblock/dead_actor_safety.rb
371
378
  - lib/punchblock/disconnected_error.rb
372
379
  - lib/punchblock/event.rb
373
380
  - lib/punchblock/event/active_speaker.rb
@@ -450,6 +457,7 @@ files:
450
457
  - spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb
451
458
  - spec/punchblock/translator/asterisk/component_spec.rb
452
459
  - spec/punchblock/translator/asterisk_spec.rb
460
+ - spec/punchblock_spec.rb
453
461
  - spec/spec_helper.rb
454
462
  - spec/support/mock_connection_with_event_handler.rb
455
463
  homepage: http://github.com/adhearsion/punchblock
@@ -467,7 +475,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
467
475
  version: '0'
468
476
  segments:
469
477
  - 0
470
- hash: 621112647086219314
478
+ hash: -421186305561513496
471
479
  required_rubygems_version: !ruby/object:Gem::Requirement
472
480
  none: false
473
481
  requirements:
@@ -476,7 +484,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
476
484
  version: 1.3.7
477
485
  requirements: []
478
486
  rubyforge_project: punchblock
479
- rubygems_version: 1.8.21
487
+ rubygems_version: 1.8.24
480
488
  signing_key:
481
489
  specification_version: 3
482
490
  summary: Punchblock is a telephony middleware library
@@ -526,5 +534,7 @@ test_files:
526
534
  - spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb
527
535
  - spec/punchblock/translator/asterisk/component_spec.rb
528
536
  - spec/punchblock/translator/asterisk_spec.rb
537
+ - spec/punchblock_spec.rb
529
538
  - spec/spec_helper.rb
530
539
  - spec/support/mock_connection_with_event_handler.rb
540
+ has_rdoc: