punchblock 1.9.4 → 2.0.0.beta1
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -2
- data/CHANGELOG.md +17 -0
- data/Gemfile +1 -0
- data/Guardfile +4 -0
- data/README.markdown +6 -0
- data/Rakefile +16 -0
- data/benchmarks/ami_event_name_comparison.rb +14 -0
- data/benchmarks/channel.rb +27 -0
- data/lib/punchblock/client.rb +2 -6
- data/lib/punchblock/command/accept.rb +3 -24
- data/lib/punchblock/command/answer.rb +3 -24
- data/lib/punchblock/command/dial.rb +24 -76
- data/lib/punchblock/command/hangup.rb +3 -19
- data/lib/punchblock/command/join.rb +21 -70
- data/lib/punchblock/command/mute.rb +3 -3
- data/lib/punchblock/command/redirect.rb +6 -39
- data/lib/punchblock/command/reject.rb +14 -54
- data/lib/punchblock/command/unjoin.rb +8 -40
- data/lib/punchblock/command/unmute.rb +3 -3
- data/lib/punchblock/command_node.rb +0 -17
- data/lib/punchblock/component/asterisk/agi/command.rb +20 -127
- data/lib/punchblock/component/asterisk/ami/action.rb +30 -117
- data/lib/punchblock/component/component_node.rb +1 -1
- data/lib/punchblock/component/input.rb +89 -268
- data/lib/punchblock/component/output.rb +106 -154
- data/lib/punchblock/component/prompt.rb +51 -0
- data/lib/punchblock/component/record.rb +41 -130
- data/lib/punchblock/component.rb +1 -0
- data/lib/punchblock/connection/asterisk.rb +31 -4
- data/lib/punchblock/connection/xmpp.rb +6 -14
- data/lib/punchblock/core_ext/blather/stanza.rb +1 -1
- data/lib/punchblock/event/active_speaker.rb +2 -10
- data/lib/punchblock/event/answered.rb +3 -3
- data/lib/punchblock/event/asterisk/ami/event.rb +15 -47
- data/lib/punchblock/event/complete.rb +26 -48
- data/lib/punchblock/event/dtmf.rb +3 -13
- data/lib/punchblock/event/end.rb +10 -11
- data/lib/punchblock/event/joined.rb +5 -25
- data/lib/punchblock/event/offer.rb +4 -25
- data/lib/punchblock/event/ringing.rb +3 -3
- data/lib/punchblock/event/unjoined.rb +5 -25
- data/lib/punchblock/event.rb +0 -10
- data/lib/punchblock/has_headers.rb +20 -26
- data/lib/punchblock/rayo_node.rb +46 -23
- data/lib/punchblock/ref.rb +39 -18
- data/lib/punchblock/translator/asterisk/agi_app.rb +15 -0
- data/lib/punchblock/translator/asterisk/agi_command.rb +3 -1
- data/lib/punchblock/translator/asterisk/ami_error_converter.rb +20 -0
- data/lib/punchblock/translator/asterisk/call.rb +60 -39
- data/lib/punchblock/translator/asterisk/channel.rb +41 -0
- data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +4 -1
- data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +4 -4
- data/lib/punchblock/translator/asterisk/component/composed_prompt.rb +62 -0
- data/lib/punchblock/translator/asterisk/component/input.rb +1 -0
- data/lib/punchblock/translator/asterisk/component/mrcp_native_prompt.rb +56 -0
- data/lib/punchblock/translator/asterisk/component/mrcp_prompt.rb +53 -0
- data/lib/punchblock/translator/asterisk/component/mrcp_recog_prompt.rb +99 -0
- data/lib/punchblock/translator/asterisk/component/output.rb +30 -22
- data/lib/punchblock/translator/asterisk/component/record.rb +8 -6
- data/lib/punchblock/translator/asterisk/component.rb +6 -5
- data/lib/punchblock/translator/asterisk/unimrcp_app.rb +26 -0
- data/lib/punchblock/translator/asterisk.rb +24 -28
- data/lib/punchblock/translator/dtmf_recognizer.rb +39 -20
- data/lib/punchblock/translator/freeswitch/call.rb +15 -14
- data/lib/punchblock/translator/freeswitch/component/abstract_output.rb +5 -4
- data/lib/punchblock/translator/freeswitch/component/flite_output.rb +1 -1
- data/lib/punchblock/translator/freeswitch/component/input.rb +5 -0
- data/lib/punchblock/translator/freeswitch/component/output.rb +2 -2
- data/lib/punchblock/translator/freeswitch/component/record.rb +19 -13
- data/lib/punchblock/translator/freeswitch/component/tts_output.rb +2 -2
- data/lib/punchblock/translator/freeswitch/component.rb +2 -5
- data/lib/punchblock/translator/freeswitch.rb +2 -2
- data/lib/punchblock/translator/input_component.rb +33 -13
- data/lib/punchblock/uri_list.rb +21 -0
- data/lib/punchblock/version.rb +1 -1
- data/lib/punchblock.rb +4 -3
- data/punchblock.gemspec +7 -3
- data/spec/punchblock/client/component_registry_spec.rb +1 -1
- data/spec/punchblock/client_spec.rb +10 -26
- data/spec/punchblock/command/accept_spec.rb +41 -7
- data/spec/punchblock/command/answer_spec.rb +51 -7
- data/spec/punchblock/command/dial_spec.rb +56 -14
- data/spec/punchblock/command/hangup_spec.rb +41 -7
- data/spec/punchblock/command/join_spec.rb +53 -11
- data/spec/punchblock/command/mute_spec.rb +19 -4
- data/spec/punchblock/command/redirect_spec.rb +40 -10
- data/spec/punchblock/command/reject_spec.rb +43 -11
- data/spec/punchblock/command/unjoin_spec.rb +40 -9
- data/spec/punchblock/command/unmute_spec.rb +19 -4
- data/spec/punchblock/command_node_spec.rb +0 -4
- data/spec/punchblock/component/asterisk/agi/command_spec.rb +16 -39
- data/spec/punchblock/component/asterisk/ami/action_spec.rb +50 -53
- data/spec/punchblock/component/component_node_spec.rb +3 -5
- data/spec/punchblock/component/input_spec.rb +194 -61
- data/spec/punchblock/component/output_spec.rb +194 -62
- data/spec/punchblock/component/prompt_spec.rb +132 -0
- data/spec/punchblock/component/record_spec.rb +70 -32
- data/spec/punchblock/connection/asterisk_spec.rb +17 -3
- data/spec/punchblock/connection/freeswitch_spec.rb +4 -4
- data/spec/punchblock/connection/xmpp_spec.rb +20 -38
- data/spec/punchblock/event/answered_spec.rb +12 -10
- data/spec/punchblock/event/asterisk/ami/event_spec.rb +27 -22
- data/spec/punchblock/event/complete_spec.rb +15 -19
- data/spec/punchblock/event/dtmf_spec.rb +5 -6
- data/spec/punchblock/event/end_spec.rb +20 -10
- data/spec/punchblock/event/joined_spec.rb +8 -7
- data/spec/punchblock/event/offer_spec.rb +41 -12
- data/spec/punchblock/event/ringing_spec.rb +12 -10
- data/spec/punchblock/event/started_speaking_spec.rb +5 -6
- data/spec/punchblock/event/stopped_speaking_spec.rb +5 -6
- data/spec/punchblock/event/unjoined_spec.rb +7 -7
- data/spec/punchblock/ref_spec.rb +86 -9
- data/spec/punchblock/translator/asterisk/call_spec.rb +317 -154
- data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +28 -5
- data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +15 -13
- data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +237 -0
- data/spec/punchblock/translator/asterisk/component/input_spec.rb +171 -14
- data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +652 -0
- data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +646 -0
- data/spec/punchblock/translator/asterisk/component/output_spec.rb +127 -77
- data/spec/punchblock/translator/asterisk/component/record_spec.rb +17 -8
- data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +2 -2
- data/spec/punchblock/translator/asterisk/component_spec.rb +3 -7
- data/spec/punchblock/translator/asterisk_spec.rb +20 -24
- data/spec/punchblock/translator/freeswitch/call_spec.rb +103 -99
- data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +17 -8
- data/spec/punchblock/translator/freeswitch/component/input_spec.rb +26 -14
- data/spec/punchblock/translator/freeswitch/component/output_spec.rb +30 -52
- data/spec/punchblock/translator/freeswitch/component/record_spec.rb +23 -19
- data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +18 -8
- data/spec/punchblock/translator/freeswitch/component_spec.rb +4 -8
- data/spec/punchblock/translator/freeswitch_spec.rb +11 -14
- data/spec/punchblock/uri_list_spec.rb +49 -0
- data/spec/punchblock_spec.rb +11 -1
- data/spec/spec_helper.rb +7 -11
- data/spec/support/mock_connection_with_event_handler.rb +1 -1
- metadata +104 -24
- data/lib/punchblock/header.rb +0 -9
- data/lib/punchblock/key_value_pair_node.rb +0 -51
- data/spec/punchblock/header_spec.rb +0 -11
|
@@ -11,7 +11,7 @@ module Punchblock
|
|
|
11
11
|
|
|
12
12
|
let(:id) { Punchblock.new_uuid }
|
|
13
13
|
let(:translator) { Punchblock::Translator::Freeswitch.new connection }
|
|
14
|
-
let(:mock_stream) {
|
|
14
|
+
let(:mock_stream) { double('RubyFS::Stream') }
|
|
15
15
|
let(:mock_call) { Punchblock::Translator::Freeswitch::Call.new id, translator, nil, mock_stream }
|
|
16
16
|
|
|
17
17
|
let :original_command do
|
|
@@ -48,7 +48,7 @@ module Punchblock
|
|
|
48
48
|
subject.execute
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
it "sends a
|
|
51
|
+
it "sends a maxduration complete event when the recording ends" do
|
|
52
52
|
full_filename = "file://#{filename}"
|
|
53
53
|
subject.execute
|
|
54
54
|
record_stop_event = RubyFS::Event.new nil, {
|
|
@@ -56,7 +56,7 @@ module Punchblock
|
|
|
56
56
|
:record_file_path => filename
|
|
57
57
|
}
|
|
58
58
|
mock_call.handle_es_event record_stop_event
|
|
59
|
-
reason.should be_a Punchblock::Component::Record::Complete::
|
|
59
|
+
reason.should be_a Punchblock::Component::Record::Complete::MaxDuration
|
|
60
60
|
recording.uri.should be == full_filename
|
|
61
61
|
original_command.should be_complete
|
|
62
62
|
end
|
|
@@ -94,8 +94,9 @@ module Punchblock
|
|
|
94
94
|
describe 'initial_timeout' do
|
|
95
95
|
context "set to nil" do
|
|
96
96
|
let(:command_options) { { :initial_timeout => nil } }
|
|
97
|
-
it "should
|
|
98
|
-
mock_call.should_receive(:uuid_foo).once.with(:
|
|
97
|
+
it "should setvar RECORD_INITIAL_TIMEOUT_MS with a 0 value" do
|
|
98
|
+
mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_INITIAL_TIMEOUT_MS 0").ordered
|
|
99
|
+
mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
|
|
99
100
|
subject.execute
|
|
100
101
|
original_command.response(0.1).should be_a Ref
|
|
101
102
|
end
|
|
@@ -103,8 +104,9 @@ module Punchblock
|
|
|
103
104
|
|
|
104
105
|
context "set to -1" do
|
|
105
106
|
let(:command_options) { { :initial_timeout => -1 } }
|
|
106
|
-
it "should
|
|
107
|
-
mock_call.should_receive(:uuid_foo).once.with(:
|
|
107
|
+
it "should setvar RECORD_INITIAL_TIMEOUT_MS with a 0 value" do
|
|
108
|
+
mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_INITIAL_TIMEOUT_MS 0").ordered
|
|
109
|
+
mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
|
|
108
110
|
subject.execute
|
|
109
111
|
original_command.response(0.1).should be_a Ref
|
|
110
112
|
end
|
|
@@ -112,11 +114,11 @@ module Punchblock
|
|
|
112
114
|
|
|
113
115
|
context "set to a positive number" do
|
|
114
116
|
let(:command_options) { { :initial_timeout => 10 } }
|
|
115
|
-
it "should
|
|
116
|
-
mock_call.should_receive(:uuid_foo).
|
|
117
|
+
it "should setvar RECORD_INITIAL_TIMEOUT_MS with a value in ms" do
|
|
118
|
+
mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_INITIAL_TIMEOUT_MS 10").ordered
|
|
119
|
+
mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
|
|
117
120
|
subject.execute
|
|
118
|
-
|
|
119
|
-
original_command.response(0.1).should be == error
|
|
121
|
+
original_command.response(0.1).should be_a Ref
|
|
120
122
|
end
|
|
121
123
|
end
|
|
122
124
|
end
|
|
@@ -124,8 +126,9 @@ module Punchblock
|
|
|
124
126
|
describe 'final_timeout' do
|
|
125
127
|
context "set to nil" do
|
|
126
128
|
let(:command_options) { { :final_timeout => nil } }
|
|
127
|
-
it "should
|
|
128
|
-
mock_call.should_receive(:uuid_foo).once.with(:
|
|
129
|
+
it "should setvar RECORD_FINAL_TIMEOUT_MS with a 0 value" do
|
|
130
|
+
mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_FINAL_TIMEOUT_MS 0").ordered
|
|
131
|
+
mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
|
|
129
132
|
subject.execute
|
|
130
133
|
original_command.response(0.1).should be_a Ref
|
|
131
134
|
end
|
|
@@ -133,8 +136,9 @@ module Punchblock
|
|
|
133
136
|
|
|
134
137
|
context "set to -1" do
|
|
135
138
|
let(:command_options) { { :final_timeout => -1 } }
|
|
136
|
-
it "should
|
|
137
|
-
mock_call.should_receive(:uuid_foo).once.with(:
|
|
139
|
+
it "should setvar RECORD_FINAL_TIMEOUT_MS with a 0 value" do
|
|
140
|
+
mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_FINAL_TIMEOUT_MS 0").ordered
|
|
141
|
+
mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
|
|
138
142
|
subject.execute
|
|
139
143
|
original_command.response(0.1).should be_a Ref
|
|
140
144
|
end
|
|
@@ -142,11 +146,11 @@ module Punchblock
|
|
|
142
146
|
|
|
143
147
|
context "set to a positive number" do
|
|
144
148
|
let(:command_options) { { :final_timeout => 10 } }
|
|
145
|
-
it "should
|
|
146
|
-
mock_call.should_receive(:uuid_foo).
|
|
149
|
+
it "should setvar RECORD_FINAL_TIMEOUT_MS with a value in ms" do
|
|
150
|
+
mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_FINAL_TIMEOUT_MS 10").ordered
|
|
151
|
+
mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
|
|
147
152
|
subject.execute
|
|
148
|
-
|
|
149
|
-
original_command.response(0.1).should be == error
|
|
153
|
+
original_command.response(0.1).should be_a Ref
|
|
150
154
|
end
|
|
151
155
|
end
|
|
152
156
|
end
|
|
@@ -25,7 +25,7 @@ module Punchblock
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
let :command_options do
|
|
28
|
-
{ :
|
|
28
|
+
{ :render_document => {:value => ssml_doc} }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def execute
|
|
@@ -49,16 +49,17 @@ module Punchblock
|
|
|
49
49
|
let(:command_opts) { {} }
|
|
50
50
|
|
|
51
51
|
let :command_options do
|
|
52
|
-
{ :
|
|
52
|
+
{ :render_document => {:value => ssml_doc} }.merge(command_opts)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
let :original_command do
|
|
56
56
|
Punchblock::Component::Output.new command_options
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
describe '
|
|
59
|
+
describe 'document' do
|
|
60
60
|
context 'unset' do
|
|
61
|
-
let(:
|
|
61
|
+
let(:ssml_doc) { nil }
|
|
62
|
+
|
|
62
63
|
it "should return an error and not execute any actions" do
|
|
63
64
|
execute
|
|
64
65
|
error = ProtocolError.new.setup 'option error', 'An SSML document is required.'
|
|
@@ -76,7 +77,16 @@ module Punchblock
|
|
|
76
77
|
expect_playback
|
|
77
78
|
execute
|
|
78
79
|
subject.handle_es_event RubyFS::Event.new(nil, :event_name => "CHANNEL_EXECUTE_COMPLETE")
|
|
79
|
-
original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::
|
|
80
|
+
original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Finish
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context 'with multiple documents' do
|
|
85
|
+
let(:command_opts) { { :render_documents => [{:value => ssml_doc}, {:value => ssml_doc}] } }
|
|
86
|
+
it "should return an error and not execute any actions" do
|
|
87
|
+
subject.execute
|
|
88
|
+
error = ProtocolError.new.setup 'option error', 'Only a single document is supported.'
|
|
89
|
+
original_command.response(0.1).should be == error
|
|
80
90
|
end
|
|
81
91
|
end
|
|
82
92
|
end
|
|
@@ -221,11 +231,11 @@ module Punchblock
|
|
|
221
231
|
end
|
|
222
232
|
end
|
|
223
233
|
|
|
224
|
-
context "set to :
|
|
225
|
-
let(:command_opts) { { :interrupt_on => :
|
|
234
|
+
context "set to :voice" do
|
|
235
|
+
let(:command_opts) { { :interrupt_on => :voice } }
|
|
226
236
|
it "should return an error and not execute any actions" do
|
|
227
237
|
execute
|
|
228
|
-
error = ProtocolError.new.setup 'option error', 'An interrupt-on value of
|
|
238
|
+
error = ProtocolError.new.setup 'option error', 'An interrupt-on value of voice is unsupported.'
|
|
229
239
|
original_command.response(0.1).should be == error
|
|
230
240
|
end
|
|
231
241
|
end
|
|
@@ -26,7 +26,7 @@ module Punchblock
|
|
|
26
26
|
RubyFS::Event.new nil, :event_name => 'CHANNEL_EXECUTE'
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
let(:response) {
|
|
29
|
+
let(:response) { double 'Response' }
|
|
30
30
|
|
|
31
31
|
it 'should execute the handler' do
|
|
32
32
|
response.should_receive(:call).once.with es_event
|
|
@@ -46,10 +46,8 @@ module Punchblock
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
let :expected_event do
|
|
49
|
-
Punchblock::Event::Complete.new
|
|
50
|
-
|
|
51
|
-
e.component_id = subject.id
|
|
52
|
-
end
|
|
49
|
+
Punchblock::Event::Complete.new target_call_id: call.id,
|
|
50
|
+
component_id: subject.id
|
|
53
51
|
end
|
|
54
52
|
|
|
55
53
|
it "should send the event to the connection" do
|
|
@@ -63,9 +61,7 @@ module Punchblock
|
|
|
63
61
|
|
|
64
62
|
let(:reason) { Punchblock::Event::Complete::Stop.new }
|
|
65
63
|
let :expected_event do
|
|
66
|
-
Punchblock::Event::Complete.new
|
|
67
|
-
c.reason = Punchblock::Event::Complete::Stop.new
|
|
68
|
-
end
|
|
64
|
+
Punchblock::Event::Complete.new reason: reason
|
|
69
65
|
end
|
|
70
66
|
|
|
71
67
|
it "should send a complete event with the specified reason" do
|
|
@@ -5,12 +5,12 @@ require 'spec_helper'
|
|
|
5
5
|
module Punchblock
|
|
6
6
|
module Translator
|
|
7
7
|
describe Freeswitch do
|
|
8
|
-
let(:connection) {
|
|
8
|
+
let(:connection) { double 'Connection::Freeswitch' }
|
|
9
9
|
let(:media_engine) { :flite }
|
|
10
10
|
let(:default_voice) { :hal }
|
|
11
11
|
|
|
12
12
|
let(:translator) { described_class.new connection, media_engine, default_voice }
|
|
13
|
-
let(:stream) {
|
|
13
|
+
let(:stream) { double 'RubyFS::Stream' }
|
|
14
14
|
|
|
15
15
|
before { connection.should_receive(:stream).at_most(:once).and_return stream }
|
|
16
16
|
|
|
@@ -88,14 +88,14 @@ module Punchblock
|
|
|
88
88
|
|
|
89
89
|
it 'should make the call inaccessible by ID' do
|
|
90
90
|
subject.call_with_id(call_id).should be call
|
|
91
|
-
subject.deregister_call
|
|
91
|
+
subject.deregister_call call_id
|
|
92
92
|
subject.call_with_id(call_id).should be_nil
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
describe '#register_component' do
|
|
97
97
|
let(:component_id) { 'abc123' }
|
|
98
|
-
let(:component) {
|
|
98
|
+
let(:component) { double 'Foo', :id => component_id }
|
|
99
99
|
|
|
100
100
|
it 'should make the component accessible by ID' do
|
|
101
101
|
subject.register_component component
|
|
@@ -105,7 +105,7 @@ module Punchblock
|
|
|
105
105
|
|
|
106
106
|
describe '#execute_call_command' do
|
|
107
107
|
let(:call_id) { 'abc123' }
|
|
108
|
-
let(:command) { Command::Answer.new
|
|
108
|
+
let(:command) { Command::Answer.new target_call_id: call_id }
|
|
109
109
|
|
|
110
110
|
context "with a known call ID" do
|
|
111
111
|
let(:call) { described_class::Call.new 'SIP/foo', subject }
|
|
@@ -123,16 +123,13 @@ module Punchblock
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
let :end_error_event do
|
|
126
|
-
Punchblock::Event::End.new
|
|
127
|
-
e.target_call_id = call_id
|
|
128
|
-
e.reason = :error
|
|
129
|
-
end
|
|
126
|
+
Punchblock::Event::End.new reason: :error, target_call_id: call_id
|
|
130
127
|
end
|
|
131
128
|
|
|
132
129
|
context "for an outgoing call which began executing but crashed" do
|
|
133
130
|
let(:dial_command) { Command::Dial.new :to => 'SIP/1234', :from => 'abc123' }
|
|
134
131
|
|
|
135
|
-
let(:call_id) { dial_command.response.
|
|
132
|
+
let(:call_id) { dial_command.response.call_id }
|
|
136
133
|
|
|
137
134
|
before do
|
|
138
135
|
stream.as_null_object
|
|
@@ -205,7 +202,7 @@ module Punchblock
|
|
|
205
202
|
let(:component_node) { Component::Output.new }
|
|
206
203
|
let(:component) { Translator::Freeswitch::Component::Output.new(component_node, call) }
|
|
207
204
|
|
|
208
|
-
let(:command) { Component::Stop.new
|
|
205
|
+
let(:command) { Component::Stop.new component_id: component.id }
|
|
209
206
|
|
|
210
207
|
before do
|
|
211
208
|
command.request!
|
|
@@ -256,7 +253,7 @@ module Punchblock
|
|
|
256
253
|
end
|
|
257
254
|
|
|
258
255
|
it 'should instruct the call to send a dial' do
|
|
259
|
-
mock_call =
|
|
256
|
+
mock_call = double('Freeswitch::Call').as_null_object
|
|
260
257
|
Freeswitch::Call.should_receive(:new_link).once.and_return mock_call
|
|
261
258
|
mock_call.async.should_receive(:dial).once.with command
|
|
262
259
|
subject.execute_global_command command
|
|
@@ -277,7 +274,7 @@ module Punchblock
|
|
|
277
274
|
|
|
278
275
|
describe '#handle_pb_event' do
|
|
279
276
|
it 'should forward the event to the connection' do
|
|
280
|
-
event =
|
|
277
|
+
event = double 'Punchblock::Event'
|
|
281
278
|
subject.connection.should_receive(:handle_event).once.with event
|
|
282
279
|
subject.handle_pb_event event
|
|
283
280
|
end
|
|
@@ -530,7 +527,7 @@ module Punchblock
|
|
|
530
527
|
|
|
531
528
|
describe 'with a CHANNEL_PARK event' do
|
|
532
529
|
it 'should instruct the call to send an offer' do
|
|
533
|
-
mock_call =
|
|
530
|
+
mock_call = double('Freeswitch::Call').as_null_object
|
|
534
531
|
Freeswitch::Call.should_receive(:new).once.and_return mock_call
|
|
535
532
|
subject.wrapped_object.should_receive(:link)
|
|
536
533
|
mock_call.async.should_receive(:send_offer).once
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Punchblock::URIList do
|
|
6
|
+
its(:size) { should == 0 }
|
|
7
|
+
|
|
8
|
+
context "created with a set of entries" do
|
|
9
|
+
subject { described_class.new 'http://example.com/hello.mp3', 'http://example.com/goodbye.mp3' }
|
|
10
|
+
|
|
11
|
+
its(:size) { should == 2 }
|
|
12
|
+
its(:to_ary) { should == ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
|
|
13
|
+
|
|
14
|
+
its(:to_s) { should == "http://example.com/hello.mp3\nhttp://example.com/goodbye.mp3" }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context "created with an array of entries" do
|
|
18
|
+
subject { described_class.new ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
|
|
19
|
+
|
|
20
|
+
its(:size) { should == 2 }
|
|
21
|
+
its(:to_ary) { should == ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
|
|
22
|
+
its(:to_s) { should == "http://example.com/hello.mp3\nhttp://example.com/goodbye.mp3" }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "imported from a string" do
|
|
26
|
+
let(:string) do
|
|
27
|
+
<<-STRING
|
|
28
|
+
http://example.com/hello.mp3
|
|
29
|
+
http://example.com/goodbye.mp3
|
|
30
|
+
STRING
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
subject { described_class.import string }
|
|
34
|
+
|
|
35
|
+
its(:size) { should == 2 }
|
|
36
|
+
its(:to_ary) { should == ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
|
|
37
|
+
its(:to_s) { should == "http://example.com/hello.mp3\nhttp://example.com/goodbye.mp3" }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "comparisons" do
|
|
41
|
+
context "when the elements are the same" do
|
|
42
|
+
described_class.new('foo', 'bar').should == described_class.new('foo', 'bar')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "when the elements are different" do
|
|
46
|
+
described_class.new('foo', 'baz').should_not == described_class.new('bar', 'baz')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/spec/punchblock_spec.rb
CHANGED
|
@@ -2,7 +2,17 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Punchblock do
|
|
4
4
|
describe '#client_with_connection' do
|
|
5
|
-
let(:mock_connection) {
|
|
5
|
+
let(:mock_connection) { double('Connection').as_null_object }
|
|
6
|
+
|
|
7
|
+
context 'with :xmpp' do
|
|
8
|
+
it 'sets up an XMPP connection, passing options, and a client with the connection attached' do
|
|
9
|
+
options = {:username => 'foo', :password => 'bar'}
|
|
10
|
+
Punchblock::Connection::XMPP.should_receive(:new).once.with(options).and_return mock_connection
|
|
11
|
+
client = Punchblock.client_with_connection :xmpp, options
|
|
12
|
+
client.should be_a Punchblock::Client
|
|
13
|
+
client.connection.should be mock_connection
|
|
14
|
+
end
|
|
15
|
+
end
|
|
6
16
|
|
|
7
17
|
context 'with :XMPP' do
|
|
8
18
|
it 'sets up an XMPP connection, passing options, and a client with the connection attached' do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
require 'punchblock'
|
|
4
4
|
require 'countdownlatch'
|
|
5
5
|
require 'logger'
|
|
6
|
+
require 'celluloid'
|
|
7
|
+
require 'coveralls'
|
|
8
|
+
Coveralls.wear!
|
|
6
9
|
|
|
7
10
|
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
|
8
11
|
|
|
@@ -12,6 +15,10 @@ RSpec.configure do |config|
|
|
|
12
15
|
config.filter_run :focus => true
|
|
13
16
|
config.run_all_when_everything_filtered = true
|
|
14
17
|
|
|
18
|
+
config.mock_with :rspec do |mocks|
|
|
19
|
+
mocks.add_stub_and_should_receive_to Celluloid::AbstractProxy
|
|
20
|
+
end
|
|
21
|
+
|
|
15
22
|
config.before :suite do |variable|
|
|
16
23
|
Punchblock.logger = Logger.new(STDOUT)
|
|
17
24
|
Punchblock.logger.define_singleton_method :trace, Punchblock.logger.method(:debug)
|
|
@@ -42,20 +49,9 @@ shared_examples_for 'event' do
|
|
|
42
49
|
end
|
|
43
50
|
|
|
44
51
|
shared_examples_for 'command_headers' do
|
|
45
|
-
it 'takes a hash of keys and values for headers' do
|
|
46
|
-
headers = { :x_skill => 'agent', :x_customer_id => '8877' }
|
|
47
|
-
|
|
48
|
-
control = [ Punchblock::Header.new(:x_skill, 'agent'), Punchblock::Header.new(:x_customer_id, '8877')]
|
|
49
|
-
|
|
50
|
-
di = subject.class.new :headers => headers
|
|
51
|
-
di.headers.should have(2).items
|
|
52
|
-
di.headers.each { |i| control.include?(i).should be_true }
|
|
53
|
-
end
|
|
54
52
|
end
|
|
55
53
|
|
|
56
54
|
shared_examples_for 'event_headers' do
|
|
57
|
-
its(:headers) { should be == [Punchblock::Header.new('X-skill', 'agent'), Punchblock::Header.new('X-customer-id', '8877')]}
|
|
58
|
-
its(:headers_hash) { should be == {:x_skill => 'agent', :x_customer_id => '8877'} }
|
|
59
55
|
end
|
|
60
56
|
|
|
61
57
|
shared_examples_for 'key_value_pairs' do
|