punchblock 2.5.2 → 2.5.3
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/.hound.yml +2 -0
- data/CHANGELOG.md +6 -0
- data/README.markdown +2 -1
- data/lib/punchblock/translator/asterisk/call.rb +3 -3
- data/lib/punchblock/translator/asterisk/component/mrcp_recog_prompt.rb +15 -9
- data/lib/punchblock/translator/asterisk/component/output.rb +8 -1
- data/lib/punchblock/translator/input_component.rb +2 -0
- data/lib/punchblock/version.rb +1 -1
- data/punchblock.gemspec +1 -1
- data/spec/punchblock/client/component_registry_spec.rb +3 -3
- data/spec/punchblock/client_spec.rb +22 -15
- data/spec/punchblock/command/accept_spec.rb +17 -7
- data/spec/punchblock/command/answer_spec.rb +19 -9
- data/spec/punchblock/command/dial_spec.rb +76 -27
- data/spec/punchblock/command/hangup_spec.rb +17 -7
- data/spec/punchblock/command/join_spec.rb +78 -24
- data/spec/punchblock/command/mute_spec.rb +3 -3
- data/spec/punchblock/command/redirect_spec.rb +33 -12
- data/spec/punchblock/command/reject_spec.rb +41 -14
- data/spec/punchblock/command/unjoin_spec.rb +29 -12
- data/spec/punchblock/command/unmute_spec.rb +3 -3
- data/spec/punchblock/command_node_spec.rb +43 -20
- data/spec/punchblock/component/asterisk/agi/command_spec.rb +52 -12
- data/spec/punchblock/component/asterisk/ami/action_spec.rb +69 -21
- data/spec/punchblock/component/component_node_spec.rb +12 -12
- data/spec/punchblock/component/input_spec.rb +304 -87
- data/spec/punchblock/component/output_spec.rb +434 -173
- data/spec/punchblock/component/prompt_spec.rb +63 -20
- data/spec/punchblock/component/receive_fax_spec.rb +43 -14
- data/spec/punchblock/component/record_spec.rb +215 -71
- data/spec/punchblock/component/send_fax_spec.rb +54 -15
- data/spec/punchblock/connection/asterisk_spec.rb +34 -24
- data/spec/punchblock/connection/freeswitch_spec.rb +9 -9
- data/spec/punchblock/connection/xmpp_spec.rb +92 -83
- data/spec/punchblock/event/answered_spec.rb +14 -4
- data/spec/punchblock/event/asterisk/ami/event_spec.rb +34 -12
- data/spec/punchblock/event/complete_spec.rb +36 -16
- data/spec/punchblock/event/dtmf_spec.rb +9 -3
- data/spec/punchblock/event/end_spec.rb +43 -10
- data/spec/punchblock/event/input_timers_started_spec.rb +1 -1
- data/spec/punchblock/event/joined_spec.rb +29 -7
- data/spec/punchblock/event/offer_spec.rb +41 -10
- data/spec/punchblock/event/ringing_spec.rb +14 -4
- data/spec/punchblock/event/started_speaking_spec.rb +9 -3
- data/spec/punchblock/event/stopped_speaking_spec.rb +9 -3
- data/spec/punchblock/event/unjoined_spec.rb +24 -6
- data/spec/punchblock/protocol_error_spec.rb +16 -13
- data/spec/punchblock/ref_spec.rb +90 -26
- data/spec/punchblock/translator/asterisk/call_spec.rb +176 -161
- data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +18 -18
- data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +9 -9
- data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +14 -14
- data/spec/punchblock/translator/asterisk/component/input_spec.rb +57 -36
- data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +50 -50
- data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +59 -48
- data/spec/punchblock/translator/asterisk/component/output_spec.rb +231 -221
- data/spec/punchblock/translator/asterisk/component/record_spec.rb +82 -82
- data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +10 -10
- data/spec/punchblock/translator/asterisk/component_spec.rb +4 -4
- data/spec/punchblock/translator/asterisk_spec.rb +89 -82
- data/spec/punchblock/translator/freeswitch/call_spec.rb +114 -99
- data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +19 -19
- data/spec/punchblock/translator/freeswitch/component/input_spec.rb +24 -24
- data/spec/punchblock/translator/freeswitch/component/output_spec.rb +23 -23
- data/spec/punchblock/translator/freeswitch/component/record_spec.rb +78 -78
- data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +19 -19
- data/spec/punchblock/translator/freeswitch/component_spec.rb +8 -8
- data/spec/punchblock/translator/freeswitch_spec.rb +66 -59
- data/spec/punchblock/uri_list_spec.rb +45 -10
- data/spec/punchblock_spec.rb +13 -13
- data/spec/spec_helper.rb +18 -11
- data/spec/support/mock_connection_with_event_handler.rb +1 -1
- metadata +5 -4
|
@@ -6,7 +6,7 @@ module Punchblock
|
|
|
6
6
|
class Event
|
|
7
7
|
describe Ringing do
|
|
8
8
|
it 'registers itself' do
|
|
9
|
-
RayoNode.class_from_registration(:ringing, 'urn:xmpp:rayo:1').
|
|
9
|
+
expect(RayoNode.class_from_registration(:ringing, 'urn:xmpp:rayo:1')).to eq(described_class)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
describe "from a stanza" do
|
|
@@ -25,19 +25,29 @@ module Punchblock
|
|
|
25
25
|
it { should be_instance_of described_class }
|
|
26
26
|
|
|
27
27
|
it_should_behave_like 'event'
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
describe '#headers' do
|
|
30
|
+
subject { super().headers }
|
|
31
|
+
it { should == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
|
|
32
|
+
end
|
|
29
33
|
|
|
30
34
|
context "with no headers provided" do
|
|
31
35
|
let(:stanza) { '<ringing xmlns="urn:xmpp:rayo:1"/>' }
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
describe '#headers' do
|
|
38
|
+
subject { super().headers }
|
|
39
|
+
it { should == {} }
|
|
40
|
+
end
|
|
34
41
|
end
|
|
35
42
|
end
|
|
36
43
|
|
|
37
44
|
describe "when setting options in initializer" do
|
|
38
45
|
subject { described_class.new headers: { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
describe '#headers' do
|
|
48
|
+
subject { super().headers }
|
|
49
|
+
it { should == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
|
|
50
|
+
end
|
|
41
51
|
end
|
|
42
52
|
end
|
|
43
53
|
end
|
|
@@ -6,7 +6,7 @@ module Punchblock
|
|
|
6
6
|
class Event
|
|
7
7
|
describe StartedSpeaking do
|
|
8
8
|
it 'registers itself' do
|
|
9
|
-
RayoNode.class_from_registration(:'started-speaking', 'urn:xmpp:rayo:1').
|
|
9
|
+
expect(RayoNode.class_from_registration(:'started-speaking', 'urn:xmpp:rayo:1')).to eq(described_class)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
describe "from a stanza" do
|
|
@@ -20,7 +20,10 @@ module Punchblock
|
|
|
20
20
|
|
|
21
21
|
it_should_behave_like 'event'
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
describe '#call_id' do
|
|
24
|
+
subject { super().call_id }
|
|
25
|
+
it { should be == "x0yz4ye-lx7-6ai9njwvw8nsb" }
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
describe "when setting options in initializer" do
|
|
@@ -28,7 +31,10 @@ module Punchblock
|
|
|
28
31
|
described_class.new :call_id => 'abc123'
|
|
29
32
|
end
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
describe '#call_id' do
|
|
35
|
+
subject { super().call_id }
|
|
36
|
+
it { should be == 'abc123' }
|
|
37
|
+
end
|
|
32
38
|
end
|
|
33
39
|
end
|
|
34
40
|
end
|
|
@@ -6,7 +6,7 @@ module Punchblock
|
|
|
6
6
|
class Event
|
|
7
7
|
describe StoppedSpeaking do
|
|
8
8
|
it 'registers itself' do
|
|
9
|
-
RayoNode.class_from_registration(:'stopped-speaking', 'urn:xmpp:rayo:1').
|
|
9
|
+
expect(RayoNode.class_from_registration(:'stopped-speaking', 'urn:xmpp:rayo:1')).to eq(described_class)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
describe "from a stanza" do
|
|
@@ -20,7 +20,10 @@ module Punchblock
|
|
|
20
20
|
|
|
21
21
|
it_should_behave_like 'event'
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
describe '#call_id' do
|
|
24
|
+
subject { super().call_id }
|
|
25
|
+
it { should be == "x0yz4ye-lx7-6ai9njwvw8nsb" }
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
describe "when setting options in initializer" do
|
|
@@ -28,7 +31,10 @@ module Punchblock
|
|
|
28
31
|
described_class.new :call_id => 'abc123'
|
|
29
32
|
end
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
describe '#call_id' do
|
|
35
|
+
subject { super().call_id }
|
|
36
|
+
it { should be == 'abc123' }
|
|
37
|
+
end
|
|
32
38
|
end
|
|
33
39
|
end
|
|
34
40
|
end
|
|
@@ -6,7 +6,7 @@ module Punchblock
|
|
|
6
6
|
class Event
|
|
7
7
|
describe Unjoined do
|
|
8
8
|
it 'registers itself' do
|
|
9
|
-
RayoNode.class_from_registration(:unjoined, 'urn:xmpp:rayo:1').
|
|
9
|
+
expect(RayoNode.class_from_registration(:unjoined, 'urn:xmpp:rayo:1')).to eq(described_class)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
describe "from a stanza" do
|
|
@@ -18,16 +18,34 @@ module Punchblock
|
|
|
18
18
|
|
|
19
19
|
it_should_behave_like 'event'
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
describe '#call_uri' do
|
|
22
|
+
subject { super().call_uri }
|
|
23
|
+
it { should be == 'b' }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#call_id' do
|
|
27
|
+
subject { super().call_id }
|
|
28
|
+
it { should be == 'b' }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#mixer_name' do
|
|
32
|
+
subject { super().mixer_name }
|
|
33
|
+
it { should be == 'm' }
|
|
34
|
+
end
|
|
24
35
|
end
|
|
25
36
|
|
|
26
37
|
describe "when setting options in initializer" do
|
|
27
38
|
subject { described_class.new :call_uri => 'abc123', :mixer_name => 'blah' }
|
|
28
39
|
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
describe '#call_id' do
|
|
41
|
+
subject { super().call_id }
|
|
42
|
+
it { should be == 'abc123' }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '#mixer_name' do
|
|
46
|
+
subject { super().mixer_name }
|
|
47
|
+
it { should be == 'blah' }
|
|
48
|
+
end
|
|
31
49
|
end
|
|
32
50
|
end
|
|
33
51
|
end
|
|
@@ -10,28 +10,31 @@ module Punchblock
|
|
|
10
10
|
let(:component_id) { 'abc123' }
|
|
11
11
|
subject { ProtocolError.new.setup name, text, call_id, component_id }
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
describe '#inspect' do
|
|
14
|
+
subject { super().inspect }
|
|
15
|
+
it { should be == '#<Punchblock::ProtocolError: name=:item_not_found text="Could not find call [id=f6d437f4-1e18-457b-99f8-b5d853f50347]" call_id="f6d437f4-1e18-457b-99f8-b5d853f50347" component_id="abc123">' }
|
|
16
|
+
end
|
|
14
17
|
|
|
15
18
|
describe ".exception" do
|
|
16
19
|
context "with no arguments" do
|
|
17
20
|
it "returns the original object" do
|
|
18
|
-
ProtocolError.exception.
|
|
21
|
+
expect(ProtocolError.exception).to eq(ProtocolError.new)
|
|
19
22
|
end
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
context "with self as the argument" do
|
|
23
26
|
it "returns the original object" do
|
|
24
|
-
ProtocolError.exception(subject).
|
|
27
|
+
expect(ProtocolError.exception(subject)).to eq(ProtocolError.new(subject.to_s))
|
|
25
28
|
end
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
context "with other values" do
|
|
29
32
|
it "returns a new object with the appropriate values" do
|
|
30
33
|
e = ProtocolError.exception 'FooBar'
|
|
31
|
-
e.name.
|
|
32
|
-
e.text.
|
|
33
|
-
e.call_id.
|
|
34
|
-
e.component_id.
|
|
34
|
+
expect(e.name).to eq(nil)
|
|
35
|
+
expect(e.text).to eq(nil)
|
|
36
|
+
expect(e.call_id).to eq(nil)
|
|
37
|
+
expect(e.component_id).to eq(nil)
|
|
35
38
|
end
|
|
36
39
|
end
|
|
37
40
|
end
|
|
@@ -39,23 +42,23 @@ module Punchblock
|
|
|
39
42
|
describe "#exception" do
|
|
40
43
|
context "with no arguments" do
|
|
41
44
|
it "returns the original object" do
|
|
42
|
-
subject.exception.
|
|
45
|
+
expect(subject.exception).to be subject
|
|
43
46
|
end
|
|
44
47
|
end
|
|
45
48
|
|
|
46
49
|
context "with self as the argument" do
|
|
47
50
|
it "returns the original object" do
|
|
48
|
-
subject.exception(subject).
|
|
51
|
+
expect(subject.exception(subject)).to be subject
|
|
49
52
|
end
|
|
50
53
|
end
|
|
51
54
|
|
|
52
55
|
context "with other values" do
|
|
53
56
|
it "returns a new object with the appropriate values" do
|
|
54
57
|
e = subject.exception("Boo")
|
|
55
|
-
e.name.
|
|
56
|
-
e.text.
|
|
57
|
-
e.call_id.
|
|
58
|
-
e.component_id.
|
|
58
|
+
expect(e.name).to eq(name)
|
|
59
|
+
expect(e.text).to eq(text)
|
|
60
|
+
expect(e.call_id).to eq(call_id)
|
|
61
|
+
expect(e.component_id).to eq(component_id)
|
|
59
62
|
end
|
|
60
63
|
end
|
|
61
64
|
end
|
data/spec/punchblock/ref_spec.rb
CHANGED
|
@@ -5,7 +5,7 @@ require 'spec_helper'
|
|
|
5
5
|
module Punchblock
|
|
6
6
|
describe Ref do
|
|
7
7
|
it 'registers itself' do
|
|
8
|
-
RayoNode.class_from_registration(:ref, 'urn:xmpp:rayo:1').
|
|
8
|
+
expect(RayoNode.class_from_registration(:ref, 'urn:xmpp:rayo:1')).to eq(described_class)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe "from a stanza" do
|
|
@@ -15,36 +15,97 @@ module Punchblock
|
|
|
15
15
|
subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
|
|
16
16
|
|
|
17
17
|
it { should be_instance_of described_class }
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
describe '#target_call_id' do
|
|
20
|
+
subject { super().target_call_id }
|
|
21
|
+
it { should be == '9f00061' }
|
|
22
|
+
end
|
|
19
23
|
|
|
20
24
|
context "when the URI isn't actually a URI" do
|
|
21
25
|
let(:uri) { 'fgh4590' }
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
describe '#uri' do
|
|
28
|
+
subject { super().uri }
|
|
29
|
+
it { should be == URI('fgh4590') }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe '#scheme' do
|
|
33
|
+
subject { super().scheme }
|
|
34
|
+
it { should be == nil }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '#call_id' do
|
|
38
|
+
subject { super().call_id }
|
|
39
|
+
it { should be == 'fgh4590' }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#domain' do
|
|
43
|
+
subject { super().domain }
|
|
44
|
+
it { should be == nil }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe '#component_id' do
|
|
48
|
+
subject { super().component_id }
|
|
49
|
+
it { should be == 'fgh4590' }
|
|
50
|
+
end
|
|
28
51
|
end
|
|
29
52
|
|
|
30
53
|
context "when the URI is an XMPP JID" do
|
|
31
54
|
let(:uri) { 'xmpp:fgh4590@rayo.net/abc123' }
|
|
32
55
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
describe '#uri' do
|
|
57
|
+
subject { super().uri }
|
|
58
|
+
it { should be == URI('xmpp:fgh4590@rayo.net/abc123') }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe '#scheme' do
|
|
62
|
+
subject { super().scheme }
|
|
63
|
+
it { should be == 'xmpp' }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe '#call_id' do
|
|
67
|
+
subject { super().call_id }
|
|
68
|
+
it { should be == 'fgh4590' }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe '#domain' do
|
|
72
|
+
subject { super().domain }
|
|
73
|
+
it { should be == 'rayo.net' }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '#component_id' do
|
|
77
|
+
subject { super().component_id }
|
|
78
|
+
it { should be == 'abc123' }
|
|
79
|
+
end
|
|
38
80
|
end
|
|
39
81
|
|
|
40
82
|
context "when the URI is an asterisk UUID" do
|
|
41
83
|
let(:uri) { 'asterisk:fgh4590' }
|
|
42
84
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
85
|
+
describe '#uri' do
|
|
86
|
+
subject { super().uri }
|
|
87
|
+
it { should be == URI('asterisk:fgh4590') }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe '#scheme' do
|
|
91
|
+
subject { super().scheme }
|
|
92
|
+
it { should be == 'asterisk' }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe '#call_id' do
|
|
96
|
+
subject { super().call_id }
|
|
97
|
+
it { should be == 'fgh4590' }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe '#domain' do
|
|
101
|
+
subject { super().domain }
|
|
102
|
+
it { should be == nil }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe '#component_id' do
|
|
106
|
+
subject { super().component_id }
|
|
107
|
+
it { should be == 'fgh4590' }
|
|
108
|
+
end
|
|
48
109
|
end
|
|
49
110
|
end
|
|
50
111
|
|
|
@@ -52,7 +113,10 @@ module Punchblock
|
|
|
52
113
|
subject { Ref.new uri: uri }
|
|
53
114
|
let(:uri) { 'xmpp:fgh4590@rayo.net/abc123' }
|
|
54
115
|
|
|
55
|
-
|
|
116
|
+
describe '#uri' do
|
|
117
|
+
subject { super().uri }
|
|
118
|
+
it { should be == URI('xmpp:fgh4590@rayo.net/abc123') }
|
|
119
|
+
end
|
|
56
120
|
|
|
57
121
|
describe "exporting to Rayo" do
|
|
58
122
|
context "when the URI isn't actually a URI" do
|
|
@@ -60,8 +124,8 @@ module Punchblock
|
|
|
60
124
|
|
|
61
125
|
it "should export to XML that can be understood by its parser" do
|
|
62
126
|
new_instance = RayoNode.from_xml subject.to_rayo
|
|
63
|
-
new_instance.
|
|
64
|
-
new_instance.uri.
|
|
127
|
+
expect(new_instance).to be_instance_of described_class
|
|
128
|
+
expect(new_instance.uri).to eq(URI('fgh4590'))
|
|
65
129
|
end
|
|
66
130
|
end
|
|
67
131
|
|
|
@@ -70,8 +134,8 @@ module Punchblock
|
|
|
70
134
|
|
|
71
135
|
it "should export to XML that can be understood by its parser" do
|
|
72
136
|
new_instance = RayoNode.from_xml subject.to_rayo
|
|
73
|
-
new_instance.
|
|
74
|
-
new_instance.uri.
|
|
137
|
+
expect(new_instance).to be_instance_of described_class
|
|
138
|
+
expect(new_instance.uri).to eq(URI('xmpp:fgh4590@rayo.net'))
|
|
75
139
|
end
|
|
76
140
|
end
|
|
77
141
|
|
|
@@ -80,8 +144,8 @@ module Punchblock
|
|
|
80
144
|
|
|
81
145
|
it "should export to XML that can be understood by its parser" do
|
|
82
146
|
new_instance = RayoNode.from_xml subject.to_rayo
|
|
83
|
-
new_instance.
|
|
84
|
-
new_instance.uri.
|
|
147
|
+
expect(new_instance).to be_instance_of described_class
|
|
148
|
+
expect(new_instance.uri).to eq(URI('asterisk:fgh4590'))
|
|
85
149
|
end
|
|
86
150
|
end
|
|
87
151
|
|
|
@@ -90,14 +154,14 @@ module Punchblock
|
|
|
90
154
|
parent = Nokogiri::XML::Node.new 'foo', doc
|
|
91
155
|
doc.root = parent
|
|
92
156
|
rayo_doc = subject.to_rayo(parent)
|
|
93
|
-
rayo_doc.
|
|
157
|
+
expect(rayo_doc).to eq(parent)
|
|
94
158
|
end
|
|
95
159
|
|
|
96
160
|
context "when attributes are not set" do
|
|
97
161
|
subject { described_class.new }
|
|
98
162
|
|
|
99
163
|
it "should not include them in the XML representation" do
|
|
100
|
-
subject.to_rayo['uri'].
|
|
164
|
+
expect(subject.to_rayo['uri']).to be_nil
|
|
101
165
|
end
|
|
102
166
|
end
|
|
103
167
|
end
|
|
@@ -62,34 +62,49 @@ module Punchblock
|
|
|
62
62
|
|
|
63
63
|
subject { Call.new channel, translator, ami_client, connection, agi_env }
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
describe '#id' do
|
|
66
|
+
subject { super().id }
|
|
67
|
+
it { should be_a String }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe '#channel' do
|
|
71
|
+
subject { super().channel }
|
|
72
|
+
it { should be == channel }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe '#translator' do
|
|
76
|
+
subject { super().translator }
|
|
77
|
+
it { should be translator }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe '#agi_env' do
|
|
81
|
+
subject { super().agi_env }
|
|
82
|
+
it { should be == agi_env }
|
|
83
|
+
end
|
|
69
84
|
|
|
70
|
-
before { translator.
|
|
85
|
+
before { allow(translator).to receive :handle_pb_event }
|
|
71
86
|
|
|
72
87
|
describe '#register_component' do
|
|
73
88
|
it 'should make the component accessible by ID' do
|
|
74
89
|
component_id = 'abc123'
|
|
75
90
|
component = double 'Translator::Asterisk::Component', :id => component_id
|
|
76
91
|
subject.register_component component
|
|
77
|
-
subject.component_with_id(component_id).
|
|
92
|
+
expect(subject.component_with_id(component_id)).to be component
|
|
78
93
|
end
|
|
79
94
|
end
|
|
80
95
|
|
|
81
96
|
describe "getting channel vars" do
|
|
82
97
|
it "should do a GetVar when we don't have a cached value" do
|
|
83
98
|
response = RubyAMI::Response.new 'Value' => 'thevalue'
|
|
84
|
-
ami_client.
|
|
85
|
-
subject.channel_var('somevariable').
|
|
99
|
+
expect(ami_client).to receive(:send_action).once.with('GetVar', 'Channel' => channel, 'Variable' => 'somevariable').and_return response
|
|
100
|
+
expect(subject.channel_var('somevariable')).to eq('thevalue')
|
|
86
101
|
end
|
|
87
102
|
|
|
88
103
|
context "when the value comes back from GetVar as '(null)'" do
|
|
89
104
|
it "should return nil" do
|
|
90
105
|
response = RubyAMI::Response.new 'Value' => '(null)'
|
|
91
|
-
ami_client.
|
|
92
|
-
subject.channel_var('somevariable').
|
|
106
|
+
expect(ami_client).to receive(:send_action).once.with('GetVar', 'Channel' => channel, 'Variable' => 'somevariable').and_return response
|
|
107
|
+
expect(subject.channel_var('somevariable')).to be_nil
|
|
93
108
|
end
|
|
94
109
|
end
|
|
95
110
|
end
|
|
@@ -100,30 +115,30 @@ module Punchblock
|
|
|
100
115
|
:to => '1000',
|
|
101
116
|
:from => 'Jane Smith <SIP/5678>',
|
|
102
117
|
:headers => sip_headers
|
|
103
|
-
translator.
|
|
118
|
+
expect(translator).to receive(:handle_pb_event).with expected_offer
|
|
104
119
|
subject.send_offer
|
|
105
120
|
end
|
|
106
121
|
|
|
107
122
|
it 'should make the call identify as inbound' do
|
|
108
123
|
subject.send_offer
|
|
109
|
-
subject.direction.
|
|
110
|
-
subject.inbound
|
|
111
|
-
subject.outbound
|
|
124
|
+
expect(subject.direction).to eq(:inbound)
|
|
125
|
+
expect(subject.inbound?).to be true
|
|
126
|
+
expect(subject.outbound?).to be false
|
|
112
127
|
end
|
|
113
128
|
end
|
|
114
129
|
|
|
115
130
|
describe '#send_progress' do
|
|
116
131
|
context "with a call that is already answered" do
|
|
117
132
|
it 'should not send the EXEC Progress command' do
|
|
118
|
-
subject.
|
|
119
|
-
subject.
|
|
133
|
+
expect(subject).to receive(:'answered?').and_return true
|
|
134
|
+
expect(subject).to receive(:execute_agi_command).with("EXEC Progress").never
|
|
120
135
|
subject.send_progress
|
|
121
136
|
end
|
|
122
137
|
end
|
|
123
138
|
|
|
124
139
|
context "with an unanswered call" do
|
|
125
140
|
before do
|
|
126
|
-
subject.
|
|
141
|
+
expect(subject).to receive(:'answered?').at_least(:once).and_return(false)
|
|
127
142
|
end
|
|
128
143
|
|
|
129
144
|
context "with a call that is outbound" do
|
|
@@ -135,7 +150,7 @@ module Punchblock
|
|
|
135
150
|
end
|
|
136
151
|
|
|
137
152
|
it 'should not send the EXEC Progress command' do
|
|
138
|
-
subject.
|
|
153
|
+
expect(subject).to receive(:execute_agi_command).with("EXEC Progress").never
|
|
139
154
|
subject.send_progress
|
|
140
155
|
end
|
|
141
156
|
end
|
|
@@ -146,12 +161,12 @@ module Punchblock
|
|
|
146
161
|
end
|
|
147
162
|
|
|
148
163
|
it 'should send the EXEC Progress command to a call that is inbound and not answered' do
|
|
149
|
-
subject.
|
|
164
|
+
expect(subject).to receive(:execute_agi_command).with("EXEC Progress").and_return code: 200, result: 0
|
|
150
165
|
subject.send_progress
|
|
151
166
|
end
|
|
152
167
|
|
|
153
168
|
it 'should send the EXEC Progress command only once if called twice' do
|
|
154
|
-
subject.
|
|
169
|
+
expect(subject).to receive(:execute_agi_command).with("EXEC Progress").once.and_return code: 200, result: 0
|
|
155
170
|
subject.send_progress
|
|
156
171
|
subject.send_progress
|
|
157
172
|
end
|
|
@@ -182,7 +197,7 @@ module Punchblock
|
|
|
182
197
|
:variable => "punchblock_call_id=#{subject.id}"
|
|
183
198
|
}).tap { |a| a.request! }
|
|
184
199
|
|
|
185
|
-
translator.async.
|
|
200
|
+
expect(translator.async).to receive(:execute_global_command).once.with expected_action
|
|
186
201
|
subject.dial dial_command
|
|
187
202
|
end
|
|
188
203
|
|
|
@@ -201,7 +216,7 @@ module Punchblock
|
|
|
201
216
|
:variable => "punchblock_call_id=#{subject.id}"
|
|
202
217
|
}).tap { |a| a.request! }
|
|
203
218
|
|
|
204
|
-
translator.async.
|
|
219
|
+
expect(translator.async).to receive(:execute_global_command).once.with expected_action
|
|
205
220
|
subject.dial dial_command
|
|
206
221
|
end
|
|
207
222
|
end
|
|
@@ -224,7 +239,7 @@ module Punchblock
|
|
|
224
239
|
:timeout => 10000
|
|
225
240
|
}).tap { |a| a.request! }
|
|
226
241
|
|
|
227
|
-
translator.async.
|
|
242
|
+
expect(translator.async).to receive(:execute_global_command).once.with expected_action
|
|
228
243
|
subject.dial dial_command
|
|
229
244
|
end
|
|
230
245
|
end
|
|
@@ -246,7 +261,7 @@ module Punchblock
|
|
|
246
261
|
:variable => "punchblock_call_id=#{subject.id},SIPADDHEADER51=\"X-foo: bar\",SIPADDHEADER52=\"X-doo: dah\""
|
|
247
262
|
}).tap { |a| a.request! }
|
|
248
263
|
|
|
249
|
-
translator.async.
|
|
264
|
+
expect(translator.async).to receive(:execute_global_command).once.with expected_action
|
|
250
265
|
subject.dial dial_command
|
|
251
266
|
end
|
|
252
267
|
end
|
|
@@ -254,23 +269,23 @@ module Punchblock
|
|
|
254
269
|
it 'sends the call ID as a response to the Dial' do
|
|
255
270
|
subject.dial dial_command
|
|
256
271
|
dial_command.response
|
|
257
|
-
dial_command.target_call_id.
|
|
272
|
+
expect(dial_command.target_call_id).to eq(subject.id)
|
|
258
273
|
end
|
|
259
274
|
|
|
260
275
|
it 'should make the call identify as outbound' do
|
|
261
276
|
subject.dial dial_command
|
|
262
|
-
subject.direction.
|
|
263
|
-
subject.outbound
|
|
264
|
-
subject.inbound
|
|
277
|
+
expect(subject.direction).to eq(:outbound)
|
|
278
|
+
expect(subject.outbound?).to be true
|
|
279
|
+
expect(subject.inbound?).to be false
|
|
265
280
|
end
|
|
266
281
|
|
|
267
282
|
it 'causes accepting the call to be a null operation' do
|
|
268
283
|
subject.dial dial_command
|
|
269
284
|
accept_command = Command::Accept.new
|
|
270
285
|
accept_command.request!
|
|
271
|
-
subject.
|
|
286
|
+
expect(subject).to receive(:execute_agi_command).never
|
|
272
287
|
subject.execute_command accept_command
|
|
273
|
-
accept_command.response(0.5).
|
|
288
|
+
expect(accept_command.response(0.5)).to be true
|
|
274
289
|
end
|
|
275
290
|
end
|
|
276
291
|
|
|
@@ -290,41 +305,41 @@ module Punchblock
|
|
|
290
305
|
let(:cause_txt) { 'Normal Clearing' }
|
|
291
306
|
|
|
292
307
|
it "de-registers the call from the translator" do
|
|
293
|
-
translator.
|
|
294
|
-
translator.
|
|
308
|
+
allow(translator).to receive :handle_pb_event
|
|
309
|
+
expect(translator).to receive(:deregister_call).once.with(subject.id, subject.channel)
|
|
295
310
|
subject.process_ami_event ami_event
|
|
296
311
|
end
|
|
297
312
|
|
|
298
313
|
it "should cause all components to send complete events before sending end event" do
|
|
299
|
-
subject.
|
|
314
|
+
allow(subject).to receive :send_progress
|
|
300
315
|
comp_command = Punchblock::Component::Input.new :grammar => {:value => RubySpeech::GRXML.draw(root: 'foo') { rule id: 'foo' }}, :mode => :dtmf
|
|
301
316
|
comp_command.request!
|
|
302
317
|
component = subject.execute_command comp_command
|
|
303
|
-
comp_command.response(0.1).
|
|
318
|
+
expect(comp_command.response(0.1)).to be_a Ref
|
|
304
319
|
expected_complete_event = Punchblock::Event::Complete.new :target_call_id => subject.id, :component_id => component.id, source_uri: component.id
|
|
305
320
|
expected_complete_event.reason = Punchblock::Event::Complete::Hangup.new
|
|
306
321
|
expected_end_event = Punchblock::Event::End.new :reason => :hungup, platform_code: cause, :target_call_id => subject.id
|
|
307
322
|
|
|
308
|
-
translator.
|
|
309
|
-
translator.
|
|
323
|
+
expect(translator).to receive(:handle_pb_event).with(expected_complete_event).once.ordered
|
|
324
|
+
expect(translator).to receive(:handle_pb_event).with(expected_end_event).once.ordered
|
|
310
325
|
subject.process_ami_event ami_event
|
|
311
326
|
end
|
|
312
327
|
|
|
313
328
|
it "should not allow commands to be executed while components are shutting down" do
|
|
314
329
|
call_id = subject.id
|
|
315
330
|
|
|
316
|
-
subject.
|
|
331
|
+
allow(subject).to receive :send_progress
|
|
317
332
|
comp_command = Punchblock::Component::Input.new :grammar => {:value => RubySpeech::GRXML.draw(root: 'foo') { rule id: 'foo' }}, :mode => :dtmf
|
|
318
333
|
comp_command.request!
|
|
319
334
|
component = subject.execute_command comp_command
|
|
320
|
-
comp_command.response(0.1).
|
|
335
|
+
expect(comp_command.response(0.1)).to be_a Ref
|
|
321
336
|
|
|
322
337
|
subject.process_ami_event ami_event
|
|
323
338
|
|
|
324
339
|
comp_command = Punchblock::Component::Input.new :grammar => {:value => '<grammar root="foo"><rule id="foo"/></grammar>'}, :mode => :dtmf
|
|
325
340
|
comp_command.request!
|
|
326
341
|
subject.execute_command comp_command
|
|
327
|
-
comp_command.response(0.1).
|
|
342
|
+
expect(comp_command.response(0.1)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{call_id}", call_id))
|
|
328
343
|
end
|
|
329
344
|
|
|
330
345
|
context "when the AMI event has a timestamp" do
|
|
@@ -342,7 +357,7 @@ module Punchblock
|
|
|
342
357
|
platform_code: cause,
|
|
343
358
|
target_call_id: subject.id,
|
|
344
359
|
timestamp: DateTime.new(2014, 2, 25, 22, 46, 20)
|
|
345
|
-
translator.
|
|
360
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
346
361
|
|
|
347
362
|
subject.process_ami_event ami_event
|
|
348
363
|
end
|
|
@@ -360,7 +375,7 @@ module Punchblock
|
|
|
360
375
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup_command,
|
|
361
376
|
platform_code: cause,
|
|
362
377
|
:target_call_id => subject.id
|
|
363
|
-
translator.
|
|
378
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
364
379
|
|
|
365
380
|
subject.process_ami_event ami_event
|
|
366
381
|
end
|
|
@@ -374,7 +389,7 @@ module Punchblock
|
|
|
374
389
|
expected_end_event = Punchblock::Event::End.new :reason => :hungup,
|
|
375
390
|
platform_code: cause,
|
|
376
391
|
:target_call_id => subject.id
|
|
377
|
-
translator.
|
|
392
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
378
393
|
subject.process_ami_event ami_event
|
|
379
394
|
end
|
|
380
395
|
end
|
|
@@ -387,7 +402,7 @@ module Punchblock
|
|
|
387
402
|
expected_end_event = Punchblock::Event::End.new :reason => :hungup,
|
|
388
403
|
platform_code: cause,
|
|
389
404
|
:target_call_id => subject.id
|
|
390
|
-
translator.
|
|
405
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
391
406
|
subject.process_ami_event ami_event
|
|
392
407
|
end
|
|
393
408
|
end
|
|
@@ -400,7 +415,7 @@ module Punchblock
|
|
|
400
415
|
expected_end_event = Punchblock::Event::End.new :reason => :busy,
|
|
401
416
|
platform_code: cause,
|
|
402
417
|
:target_call_id => subject.id
|
|
403
|
-
translator.
|
|
418
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
404
419
|
subject.process_ami_event ami_event
|
|
405
420
|
end
|
|
406
421
|
end
|
|
@@ -417,7 +432,7 @@ module Punchblock
|
|
|
417
432
|
expected_end_event = Punchblock::Event::End.new :reason => :timeout,
|
|
418
433
|
platform_code: cause,
|
|
419
434
|
:target_call_id => subject.id
|
|
420
|
-
translator.
|
|
435
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
421
436
|
subject.process_ami_event ami_event
|
|
422
437
|
end
|
|
423
438
|
end
|
|
@@ -436,7 +451,7 @@ module Punchblock
|
|
|
436
451
|
expected_end_event = Punchblock::Event::End.new :reason => :reject,
|
|
437
452
|
platform_code: cause,
|
|
438
453
|
:target_call_id => subject.id
|
|
439
|
-
translator.
|
|
454
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
440
455
|
subject.process_ami_event ami_event
|
|
441
456
|
end
|
|
442
457
|
end
|
|
@@ -489,7 +504,7 @@ module Punchblock
|
|
|
489
504
|
expected_end_event = Punchblock::Event::End.new :reason => :error,
|
|
490
505
|
platform_code: cause,
|
|
491
506
|
:target_call_id => subject.id
|
|
492
|
-
translator.
|
|
507
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
493
508
|
subject.process_ami_event ami_event
|
|
494
509
|
end
|
|
495
510
|
end
|
|
@@ -516,12 +531,12 @@ module Punchblock
|
|
|
516
531
|
end
|
|
517
532
|
|
|
518
533
|
it 'should send the event to the component' do
|
|
519
|
-
component.
|
|
534
|
+
expect(component).to receive(:handle_ami_event).once.with ami_event
|
|
520
535
|
subject.process_ami_event ami_event
|
|
521
536
|
end
|
|
522
537
|
|
|
523
538
|
it 'should not send an answered event' do
|
|
524
|
-
translator.
|
|
539
|
+
expect(translator).to receive(:handle_pb_event).with(kind_of(Punchblock::Event::Answered)).never
|
|
525
540
|
subject.process_ami_event ami_event
|
|
526
541
|
end
|
|
527
542
|
end
|
|
@@ -537,20 +552,20 @@ module Punchblock
|
|
|
537
552
|
it 'should send an answered event' do
|
|
538
553
|
expected_answered = Punchblock::Event::Answered.new
|
|
539
554
|
expected_answered.target_call_id = subject.id
|
|
540
|
-
translator.
|
|
555
|
+
expect(translator).to receive(:handle_pb_event).with expected_answered
|
|
541
556
|
subject.process_ami_event ami_event
|
|
542
557
|
end
|
|
543
558
|
|
|
544
559
|
it '#answered? should be true' do
|
|
545
560
|
subject.process_ami_event ami_event
|
|
546
|
-
subject.answered
|
|
561
|
+
expect(subject.answered?).to be_true
|
|
547
562
|
end
|
|
548
563
|
|
|
549
564
|
context "for a second time" do
|
|
550
565
|
it 'should only send one answered event' do
|
|
551
566
|
expected_answered = Punchblock::Event::Answered.new
|
|
552
567
|
expected_answered.target_call_id = subject.id
|
|
553
|
-
translator.
|
|
568
|
+
expect(translator).to receive(:handle_pb_event).with(expected_answered).once
|
|
554
569
|
subject.process_ami_event ami_event
|
|
555
570
|
subject.process_ami_event ami_event
|
|
556
571
|
end
|
|
@@ -568,7 +583,7 @@ module Punchblock
|
|
|
568
583
|
it "should use the AMI timestamp for the Rayo event" do
|
|
569
584
|
expected_answered = Punchblock::Event::Answered.new target_call_id: subject.id,
|
|
570
585
|
timestamp: DateTime.new(2014, 2, 25, 22, 46, 20)
|
|
571
|
-
translator.
|
|
586
|
+
expect(translator).to receive(:handle_pb_event).with expected_answered
|
|
572
587
|
|
|
573
588
|
subject.process_ami_event ami_event
|
|
574
589
|
end
|
|
@@ -596,13 +611,13 @@ module Punchblock
|
|
|
596
611
|
it 'should send a ringing event' do
|
|
597
612
|
expected_ringing = Punchblock::Event::Ringing.new
|
|
598
613
|
expected_ringing.target_call_id = subject.id
|
|
599
|
-
translator.
|
|
614
|
+
expect(translator).to receive(:handle_pb_event).with expected_ringing
|
|
600
615
|
subject.process_ami_event ami_event
|
|
601
616
|
end
|
|
602
617
|
|
|
603
618
|
it '#answered? should return false' do
|
|
604
619
|
subject.process_ami_event ami_event
|
|
605
|
-
subject.answered
|
|
620
|
+
expect(subject.answered?).to be_false
|
|
606
621
|
end
|
|
607
622
|
|
|
608
623
|
context "when the AMI event has a timestamp" do
|
|
@@ -618,7 +633,7 @@ module Punchblock
|
|
|
618
633
|
it "should use the AMI timestamp for the Rayo event" do
|
|
619
634
|
expected_ringing = Punchblock::Event::Ringing.new target_call_id: subject.id,
|
|
620
635
|
timestamp: DateTime.new(2014, 2, 25, 22, 46, 20)
|
|
621
|
-
translator.
|
|
636
|
+
expect(translator).to receive(:handle_pb_event).with expected_ringing
|
|
622
637
|
|
|
623
638
|
subject.process_ami_event ami_event
|
|
624
639
|
end
|
|
@@ -646,7 +661,7 @@ module Punchblock
|
|
|
646
661
|
let(:uniqueid) { '<null>' }
|
|
647
662
|
|
|
648
663
|
it 'should not send an end event' do
|
|
649
|
-
translator.
|
|
664
|
+
expect(translator).to receive(:handle_pb_event).once.with an_instance_of(Punchblock::Event::Asterisk::AMI::Event)
|
|
650
665
|
subject.process_ami_event ami_event
|
|
651
666
|
end
|
|
652
667
|
end
|
|
@@ -656,7 +671,7 @@ module Punchblock
|
|
|
656
671
|
let(:uniqueid) { '1235' }
|
|
657
672
|
|
|
658
673
|
it 'should not send an end event' do
|
|
659
|
-
translator.
|
|
674
|
+
expect(translator).to receive(:handle_pb_event).once.with an_instance_of(Punchblock::Event::Asterisk::AMI::Event)
|
|
660
675
|
subject.process_ami_event ami_event
|
|
661
676
|
end
|
|
662
677
|
end
|
|
@@ -668,7 +683,7 @@ module Punchblock
|
|
|
668
683
|
it 'should send an error end event' do
|
|
669
684
|
expected_end_event = Punchblock::Event::End.new :reason => :error,
|
|
670
685
|
:target_call_id => subject.id
|
|
671
|
-
translator.
|
|
686
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
672
687
|
subject.process_ami_event ami_event
|
|
673
688
|
end
|
|
674
689
|
|
|
@@ -692,7 +707,7 @@ module Punchblock
|
|
|
692
707
|
expected_end_event = Punchblock::Event::End.new reason: :error,
|
|
693
708
|
target_call_id: subject.id,
|
|
694
709
|
timestamp: DateTime.new(2014, 2, 25, 22, 46, 20)
|
|
695
|
-
translator.
|
|
710
|
+
expect(translator).to receive(:handle_pb_event).with expected_end_event
|
|
696
711
|
|
|
697
712
|
subject.process_ami_event ami_event
|
|
698
713
|
end
|
|
@@ -713,7 +728,7 @@ module Punchblock
|
|
|
713
728
|
let(:response) { double 'Response' }
|
|
714
729
|
|
|
715
730
|
it 'should execute the handler' do
|
|
716
|
-
response.
|
|
731
|
+
expect(response).to receive(:call).once.with ami_event
|
|
717
732
|
subject.register_handler :ami, :name => 'DTMF' do |event|
|
|
718
733
|
response.call event
|
|
719
734
|
end
|
|
@@ -745,13 +760,13 @@ module Punchblock
|
|
|
745
760
|
before do
|
|
746
761
|
translator.register_call other_call
|
|
747
762
|
command.request!
|
|
748
|
-
subject.
|
|
763
|
+
expect(subject).to receive(:execute_agi_command).and_return code: 200
|
|
749
764
|
subject.execute_command command
|
|
750
765
|
end
|
|
751
766
|
|
|
752
767
|
it 'retrieves and sets success on the correct Join' do
|
|
753
768
|
subject.process_ami_event ami_event
|
|
754
|
-
command.response(0.5).
|
|
769
|
+
expect(command.response(0.5)).to eq(true)
|
|
755
770
|
end
|
|
756
771
|
|
|
757
772
|
context "with the channel names reversed" do
|
|
@@ -765,7 +780,7 @@ module Punchblock
|
|
|
765
780
|
|
|
766
781
|
it 'retrieves and sets success on the correct Join' do
|
|
767
782
|
subject.process_ami_event ami_event
|
|
768
|
-
command.response(0.5).
|
|
783
|
+
expect(command.response(0.5)).to eq(true)
|
|
769
784
|
end
|
|
770
785
|
end
|
|
771
786
|
end
|
|
@@ -812,8 +827,8 @@ module Punchblock
|
|
|
812
827
|
|
|
813
828
|
before do
|
|
814
829
|
translator.register_call other_call
|
|
815
|
-
translator.
|
|
816
|
-
other_call.
|
|
830
|
+
expect(translator).to receive(:call_for_channel).with(other_channel).and_return(other_call)
|
|
831
|
+
expect(other_call).to receive(:id).and_return other_call_id
|
|
817
832
|
end
|
|
818
833
|
|
|
819
834
|
context "of state 'Link'" do
|
|
@@ -825,12 +840,12 @@ module Punchblock
|
|
|
825
840
|
end
|
|
826
841
|
|
|
827
842
|
it 'sends the Joined event when the call is the first channel' do
|
|
828
|
-
translator.
|
|
843
|
+
expect(translator).to receive(:handle_pb_event).with expected_joined
|
|
829
844
|
subject.process_ami_event ami_event
|
|
830
845
|
end
|
|
831
846
|
|
|
832
847
|
it 'sends the Joined event when the call is the second channel' do
|
|
833
|
-
translator.
|
|
848
|
+
expect(translator).to receive(:handle_pb_event).with expected_joined
|
|
834
849
|
subject.process_ami_event switched_ami_event
|
|
835
850
|
end
|
|
836
851
|
|
|
@@ -867,7 +882,7 @@ module Punchblock
|
|
|
867
882
|
|
|
868
883
|
context "when the call is the first channel" do
|
|
869
884
|
it "should use the AMI timestamp for the Rayo event" do
|
|
870
|
-
translator.
|
|
885
|
+
expect(translator).to receive(:handle_pb_event).with expected_joined
|
|
871
886
|
|
|
872
887
|
subject.process_ami_event ami_event
|
|
873
888
|
end
|
|
@@ -875,7 +890,7 @@ module Punchblock
|
|
|
875
890
|
|
|
876
891
|
context "when the call is the second channel" do
|
|
877
892
|
it "should use the AMI timestamp for the Rayo event" do
|
|
878
|
-
translator.
|
|
893
|
+
expect(translator).to receive(:handle_pb_event).with expected_joined
|
|
879
894
|
|
|
880
895
|
subject.process_ami_event switched_ami_event
|
|
881
896
|
end
|
|
@@ -892,12 +907,12 @@ module Punchblock
|
|
|
892
907
|
end
|
|
893
908
|
|
|
894
909
|
it 'sends the Unjoined event when the call is the first channel' do
|
|
895
|
-
translator.
|
|
910
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
896
911
|
subject.process_ami_event ami_event
|
|
897
912
|
end
|
|
898
913
|
|
|
899
914
|
it 'sends the Unjoined event when the call is the second channel' do
|
|
900
|
-
translator.
|
|
915
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
901
916
|
subject.process_ami_event switched_ami_event
|
|
902
917
|
end
|
|
903
918
|
|
|
@@ -934,7 +949,7 @@ module Punchblock
|
|
|
934
949
|
|
|
935
950
|
context "when the call is the first channel" do
|
|
936
951
|
it "should use the AMI timestamp for the Rayo event" do
|
|
937
|
-
translator.
|
|
952
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
938
953
|
|
|
939
954
|
subject.process_ami_event ami_event
|
|
940
955
|
end
|
|
@@ -942,7 +957,7 @@ module Punchblock
|
|
|
942
957
|
|
|
943
958
|
context "when the call is the second channel" do
|
|
944
959
|
it "should use the AMI timestamp for the Rayo event" do
|
|
945
|
-
translator.
|
|
960
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
946
961
|
|
|
947
962
|
subject.process_ami_event switched_ami_event
|
|
948
963
|
end
|
|
@@ -982,8 +997,8 @@ module Punchblock
|
|
|
982
997
|
|
|
983
998
|
before do
|
|
984
999
|
translator.register_call other_call
|
|
985
|
-
translator.
|
|
986
|
-
other_call.
|
|
1000
|
+
expect(translator).to receive(:call_for_channel).with(other_channel).and_return(other_call)
|
|
1001
|
+
expect(other_call).to receive(:id).and_return other_call_id
|
|
987
1002
|
end
|
|
988
1003
|
|
|
989
1004
|
let :expected_unjoined do
|
|
@@ -992,12 +1007,12 @@ module Punchblock
|
|
|
992
1007
|
end
|
|
993
1008
|
|
|
994
1009
|
it 'sends the Unjoined event when the call is the first channel' do
|
|
995
|
-
translator.
|
|
1010
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
996
1011
|
subject.process_ami_event ami_event
|
|
997
1012
|
end
|
|
998
1013
|
|
|
999
1014
|
it 'sends the Unjoined event when the call is the second channel' do
|
|
1000
|
-
translator.
|
|
1015
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
1001
1016
|
subject.process_ami_event switched_ami_event
|
|
1002
1017
|
end
|
|
1003
1018
|
|
|
@@ -1030,7 +1045,7 @@ module Punchblock
|
|
|
1030
1045
|
|
|
1031
1046
|
context "when the call is the first channel" do
|
|
1032
1047
|
it "should use the AMI timestamp for the Rayo event" do
|
|
1033
|
-
translator.
|
|
1048
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
1034
1049
|
|
|
1035
1050
|
subject.process_ami_event ami_event
|
|
1036
1051
|
end
|
|
@@ -1038,7 +1053,7 @@ module Punchblock
|
|
|
1038
1053
|
|
|
1039
1054
|
context "when the call is the second channel" do
|
|
1040
1055
|
it "should use the AMI timestamp for the Rayo event" do
|
|
1041
|
-
translator.
|
|
1056
|
+
expect(translator).to receive(:handle_pb_event).with expected_unjoined
|
|
1042
1057
|
|
|
1043
1058
|
subject.process_ami_event switched_ami_event
|
|
1044
1059
|
end
|
|
@@ -1058,7 +1073,7 @@ module Punchblock
|
|
|
1058
1073
|
|
|
1059
1074
|
it 'makes the variable accessible on the call' do
|
|
1060
1075
|
subject.process_ami_event ami_event
|
|
1061
|
-
subject.channel_var('foobar').
|
|
1076
|
+
expect(subject.channel_var('foobar')).to eq('abc123')
|
|
1062
1077
|
end
|
|
1063
1078
|
end
|
|
1064
1079
|
|
|
@@ -1084,7 +1099,7 @@ module Punchblock
|
|
|
1084
1099
|
end
|
|
1085
1100
|
|
|
1086
1101
|
it 'sends the AMI event to the connection as a PB event' do
|
|
1087
|
-
translator.
|
|
1102
|
+
expect(translator).to receive(:handle_pb_event).with expected_pb_event
|
|
1088
1103
|
subject.process_ami_event ami_event
|
|
1089
1104
|
end
|
|
1090
1105
|
|
|
@@ -1093,7 +1108,7 @@ module Punchblock
|
|
|
1093
1108
|
after { Asterisk.event_filter = nil }
|
|
1094
1109
|
|
|
1095
1110
|
it 'does not send the AMI event to the connection as a PB event' do
|
|
1096
|
-
translator.
|
|
1111
|
+
expect(translator).to receive(:handle_pb_event).never
|
|
1097
1112
|
subject.process_ami_event ami_event
|
|
1098
1113
|
end
|
|
1099
1114
|
end
|
|
@@ -1103,13 +1118,13 @@ module Punchblock
|
|
|
1103
1118
|
let(:body) { 'Hello world' }
|
|
1104
1119
|
|
|
1105
1120
|
it "should invoke SendText" do
|
|
1106
|
-
subject.
|
|
1121
|
+
expect(subject).to receive(:execute_agi_command).with('EXEC SendText', body).and_return code: 200
|
|
1107
1122
|
subject.send_message body
|
|
1108
1123
|
end
|
|
1109
1124
|
|
|
1110
1125
|
context "when an AMI error is received" do
|
|
1111
1126
|
it "is silently ignored" do
|
|
1112
|
-
subject.
|
|
1127
|
+
expect(subject).to receive(:execute_agi_command).with('EXEC SendText', body).and_raise RubyAMI::Error.new.tap { |e| e.message = 'Call not found' }
|
|
1113
1128
|
subject.send_message body
|
|
1114
1129
|
end
|
|
1115
1130
|
end
|
|
@@ -1124,20 +1139,20 @@ module Punchblock
|
|
|
1124
1139
|
let(:command) { Command::Accept.new }
|
|
1125
1140
|
|
|
1126
1141
|
it "should send an EXEC RINGING AGI command and set the command's response" do
|
|
1127
|
-
subject.
|
|
1142
|
+
expect(subject).to receive(:execute_agi_command).with('EXEC RINGING').and_return code: 200
|
|
1128
1143
|
subject.execute_command command
|
|
1129
|
-
command.response(0.5).
|
|
1144
|
+
expect(command.response(0.5)).to be true
|
|
1130
1145
|
end
|
|
1131
1146
|
|
|
1132
1147
|
context "when the AMI commannd raises an error" do
|
|
1133
1148
|
let(:message) { 'Some error' }
|
|
1134
1149
|
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1135
1150
|
|
|
1136
|
-
before { subject.
|
|
1151
|
+
before { expect(subject).to receive(:execute_agi_command).and_raise error }
|
|
1137
1152
|
|
|
1138
1153
|
it "should return an error with the message" do
|
|
1139
1154
|
subject.execute_command command
|
|
1140
|
-
command.response(0.5).
|
|
1155
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup('error', message, subject.id))
|
|
1141
1156
|
end
|
|
1142
1157
|
|
|
1143
1158
|
context "because the channel is gone" do
|
|
@@ -1145,7 +1160,7 @@ module Punchblock
|
|
|
1145
1160
|
|
|
1146
1161
|
it "should return an :item_not_found event for the call" do
|
|
1147
1162
|
subject.execute_command command
|
|
1148
|
-
command.response(0.5).
|
|
1163
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1149
1164
|
end
|
|
1150
1165
|
end
|
|
1151
1166
|
end
|
|
@@ -1156,34 +1171,34 @@ module Punchblock
|
|
|
1156
1171
|
|
|
1157
1172
|
it "with a :busy reason should send an EXEC Busy AGI command and set the command's response" do
|
|
1158
1173
|
command.reason = :busy
|
|
1159
|
-
subject.
|
|
1174
|
+
expect(subject).to receive(:execute_agi_command).with('EXEC Busy').and_return code: 200
|
|
1160
1175
|
subject.execute_command command
|
|
1161
|
-
command.response(0.5).
|
|
1176
|
+
expect(command.response(0.5)).to be true
|
|
1162
1177
|
end
|
|
1163
1178
|
|
|
1164
1179
|
it "with a :decline reason should send a Hangup AMI command (cause 21) and set the command's response" do
|
|
1165
1180
|
command.reason = :decline
|
|
1166
|
-
ami_client.
|
|
1181
|
+
expect(ami_client).to receive(:send_action).once.with('Hangup', 'Channel' => channel, 'Cause' => 21).and_return RubyAMI::Response.new
|
|
1167
1182
|
subject.execute_command command
|
|
1168
|
-
command.response(0.5).
|
|
1183
|
+
expect(command.response(0.5)).to be true
|
|
1169
1184
|
end
|
|
1170
1185
|
|
|
1171
1186
|
it "with an :error reason should send an EXEC Congestion AGI command and set the command's response" do
|
|
1172
1187
|
command.reason = :error
|
|
1173
|
-
subject.
|
|
1188
|
+
expect(subject).to receive(:execute_agi_command).with('EXEC Congestion').and_return code: 200
|
|
1174
1189
|
subject.execute_command command
|
|
1175
|
-
command.response(0.5).
|
|
1190
|
+
expect(command.response(0.5)).to be true
|
|
1176
1191
|
end
|
|
1177
1192
|
|
|
1178
1193
|
context "when the AMI commannd raises an error" do
|
|
1179
1194
|
let(:message) { 'Some error' }
|
|
1180
1195
|
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1181
1196
|
|
|
1182
|
-
before { subject.
|
|
1197
|
+
before { expect(subject).to receive(:execute_agi_command).and_raise error }
|
|
1183
1198
|
|
|
1184
1199
|
it "should return an error with the message" do
|
|
1185
1200
|
subject.execute_command command
|
|
1186
|
-
command.response(0.5).
|
|
1201
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup('error', message, subject.id))
|
|
1187
1202
|
end
|
|
1188
1203
|
|
|
1189
1204
|
context "because the channel is gone" do
|
|
@@ -1191,7 +1206,7 @@ module Punchblock
|
|
|
1191
1206
|
|
|
1192
1207
|
it "should return an :item_not_found event for the call" do
|
|
1193
1208
|
subject.execute_command command
|
|
1194
|
-
command.response(0.5).
|
|
1209
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1195
1210
|
end
|
|
1196
1211
|
end
|
|
1197
1212
|
end
|
|
@@ -1201,31 +1216,31 @@ module Punchblock
|
|
|
1201
1216
|
let(:command) { Command::Answer.new }
|
|
1202
1217
|
|
|
1203
1218
|
it "should send an ANSWER AGI command and set the command's response" do
|
|
1204
|
-
subject.
|
|
1219
|
+
expect(subject).to receive(:execute_agi_command).with('ANSWER').and_return code: 200
|
|
1205
1220
|
subject.execute_command command
|
|
1206
|
-
command.response(0.5).
|
|
1221
|
+
expect(command.response(0.5)).to be true
|
|
1207
1222
|
end
|
|
1208
1223
|
|
|
1209
1224
|
it "should be answered" do
|
|
1210
|
-
subject.
|
|
1225
|
+
expect(subject).to receive(:execute_agi_command)
|
|
1211
1226
|
subject.execute_command command
|
|
1212
|
-
subject.
|
|
1227
|
+
expect(subject).to be_answered
|
|
1213
1228
|
end
|
|
1214
1229
|
|
|
1215
1230
|
context "when the AMI command raises an error" do
|
|
1216
1231
|
let(:message) { 'Some error' }
|
|
1217
1232
|
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1218
1233
|
|
|
1219
|
-
before { subject.
|
|
1234
|
+
before { expect(subject).to receive(:execute_agi_command).and_raise error }
|
|
1220
1235
|
|
|
1221
1236
|
it "should return an error with the message" do
|
|
1222
1237
|
subject.execute_command command
|
|
1223
|
-
command.response(0.5).
|
|
1238
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup('error', message, subject.id))
|
|
1224
1239
|
end
|
|
1225
1240
|
|
|
1226
1241
|
it "should not be answered" do
|
|
1227
1242
|
subject.execute_command command
|
|
1228
|
-
subject.
|
|
1243
|
+
expect(subject).not_to be_answered
|
|
1229
1244
|
end
|
|
1230
1245
|
|
|
1231
1246
|
context "because the channel is gone" do
|
|
@@ -1233,7 +1248,7 @@ module Punchblock
|
|
|
1233
1248
|
|
|
1234
1249
|
it "should return an :item_not_found event for the call" do
|
|
1235
1250
|
subject.execute_command command
|
|
1236
|
-
command.response(0.5).
|
|
1251
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1237
1252
|
end
|
|
1238
1253
|
end
|
|
1239
1254
|
end
|
|
@@ -1243,20 +1258,20 @@ module Punchblock
|
|
|
1243
1258
|
let(:command) { Command::Hangup.new }
|
|
1244
1259
|
|
|
1245
1260
|
it "should send a Hangup AMI command and set the command's response" do
|
|
1246
|
-
ami_client.
|
|
1261
|
+
expect(ami_client).to receive(:send_action).once.with('Hangup', 'Channel' => channel, 'Cause' => 16).and_return RubyAMI::Response.new
|
|
1247
1262
|
subject.execute_command command
|
|
1248
|
-
command.response(0.5).
|
|
1263
|
+
expect(command.response(0.5)).to be true
|
|
1249
1264
|
end
|
|
1250
1265
|
|
|
1251
1266
|
context "when the AMI commannd raises an error" do
|
|
1252
1267
|
let(:message) { 'Some error' }
|
|
1253
1268
|
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1254
1269
|
|
|
1255
|
-
before { ami_client.
|
|
1270
|
+
before { expect(ami_client).to receive(:send_action).and_raise error }
|
|
1256
1271
|
|
|
1257
1272
|
it "should return an error with the message" do
|
|
1258
1273
|
subject.execute_command command
|
|
1259
|
-
command.response(0.5).
|
|
1274
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup('error', message, subject.id))
|
|
1260
1275
|
end
|
|
1261
1276
|
|
|
1262
1277
|
context "which is 'No such channel'" do
|
|
@@ -1264,7 +1279,7 @@ module Punchblock
|
|
|
1264
1279
|
|
|
1265
1280
|
it "should return an :item_not_found event for the call" do
|
|
1266
1281
|
subject.execute_command command
|
|
1267
|
-
command.response(0.5).
|
|
1282
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1268
1283
|
end
|
|
1269
1284
|
end
|
|
1270
1285
|
|
|
@@ -1273,7 +1288,7 @@ module Punchblock
|
|
|
1273
1288
|
|
|
1274
1289
|
it "should return an :item_not_found event for the call" do
|
|
1275
1290
|
subject.execute_command command
|
|
1276
|
-
command.response(0.5).
|
|
1291
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1277
1292
|
end
|
|
1278
1293
|
end
|
|
1279
1294
|
end
|
|
@@ -1292,10 +1307,10 @@ module Punchblock
|
|
|
1292
1307
|
Punchblock::Command::Join.new call_uri: other_call_id
|
|
1293
1308
|
end
|
|
1294
1309
|
|
|
1295
|
-
before { translator.
|
|
1310
|
+
before { expect(translator).to receive(:call_with_id).with(other_call_id).and_return(other_call) }
|
|
1296
1311
|
|
|
1297
1312
|
it "executes the proper dialplan Bridge application" do
|
|
1298
|
-
subject.
|
|
1313
|
+
expect(subject).to receive(:execute_agi_command).with('EXEC Bridge', "#{other_channel},F(#{REDIRECT_CONTEXT},#{REDIRECT_EXTENSION},#{REDIRECT_PRIORITY})").and_return code: 200
|
|
1299
1314
|
subject.execute_command command
|
|
1300
1315
|
end
|
|
1301
1316
|
|
|
@@ -1303,16 +1318,16 @@ module Punchblock
|
|
|
1303
1318
|
let(:message) { 'Some error' }
|
|
1304
1319
|
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1305
1320
|
|
|
1306
|
-
before { subject.
|
|
1321
|
+
before { expect(subject).to receive(:execute_agi_command).and_raise error }
|
|
1307
1322
|
|
|
1308
1323
|
it "should return an error with the message" do
|
|
1309
1324
|
subject.execute_command command
|
|
1310
|
-
command.response(0.5).
|
|
1325
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup('error', message, subject.id))
|
|
1311
1326
|
end
|
|
1312
1327
|
|
|
1313
1328
|
it "should not be answered" do
|
|
1314
1329
|
subject.execute_command command
|
|
1315
|
-
subject.
|
|
1330
|
+
expect(subject).not_to be_answered
|
|
1316
1331
|
end
|
|
1317
1332
|
|
|
1318
1333
|
context "because the channel is gone" do
|
|
@@ -1320,7 +1335,7 @@ module Punchblock
|
|
|
1320
1335
|
|
|
1321
1336
|
it "should return an :item_not_found event for the call" do
|
|
1322
1337
|
subject.execute_command command
|
|
1323
|
-
command.response(0.5).
|
|
1338
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1324
1339
|
end
|
|
1325
1340
|
end
|
|
1326
1341
|
end
|
|
@@ -1339,9 +1354,9 @@ module Punchblock
|
|
|
1339
1354
|
end
|
|
1340
1355
|
|
|
1341
1356
|
it "executes the unjoin through redirection" do
|
|
1342
|
-
translator.
|
|
1357
|
+
expect(translator).to receive(:call_with_id).with(other_call_id).and_return(nil)
|
|
1343
1358
|
|
|
1344
|
-
ami_client.
|
|
1359
|
+
expect(ami_client).to receive(:send_action).once.with("Redirect",
|
|
1345
1360
|
'Channel' => channel,
|
|
1346
1361
|
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1347
1362
|
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
@@ -1350,13 +1365,13 @@ module Punchblock
|
|
|
1350
1365
|
|
|
1351
1366
|
subject.execute_command command
|
|
1352
1367
|
|
|
1353
|
-
command.response(1).
|
|
1368
|
+
expect(command.response(1)).to be_true
|
|
1354
1369
|
end
|
|
1355
1370
|
|
|
1356
1371
|
it "executes the unjoin through redirection, on the subject call and the other call" do
|
|
1357
|
-
translator.
|
|
1372
|
+
expect(translator).to receive(:call_with_id).with(other_call_id).and_return(other_call)
|
|
1358
1373
|
|
|
1359
|
-
ami_client.
|
|
1374
|
+
expect(ami_client).to receive(:send_action).once.with("Redirect",
|
|
1360
1375
|
'Channel' => channel,
|
|
1361
1376
|
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1362
1377
|
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
@@ -1375,13 +1390,13 @@ module Punchblock
|
|
|
1375
1390
|
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1376
1391
|
|
|
1377
1392
|
before do
|
|
1378
|
-
translator.
|
|
1379
|
-
ami_client.
|
|
1393
|
+
expect(translator).to receive(:call_with_id).with(other_call_id).and_return(nil)
|
|
1394
|
+
expect(ami_client).to receive(:send_action).and_raise error
|
|
1380
1395
|
end
|
|
1381
1396
|
|
|
1382
1397
|
it "should return an error with the message" do
|
|
1383
1398
|
subject.execute_command command
|
|
1384
|
-
command.response(0.5).
|
|
1399
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup('error', message, subject.id))
|
|
1385
1400
|
end
|
|
1386
1401
|
|
|
1387
1402
|
context "which is 'No such channel'" do
|
|
@@ -1389,7 +1404,7 @@ module Punchblock
|
|
|
1389
1404
|
|
|
1390
1405
|
it "should return an :item_not_found event for the call" do
|
|
1391
1406
|
subject.execute_command command
|
|
1392
|
-
command.response(0.5).
|
|
1407
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1393
1408
|
end
|
|
1394
1409
|
end
|
|
1395
1410
|
|
|
@@ -1398,7 +1413,7 @@ module Punchblock
|
|
|
1398
1413
|
|
|
1399
1414
|
it "should return an :item_not_found event for the call" do
|
|
1400
1415
|
subject.execute_command command
|
|
1401
|
-
command.response(0.5).
|
|
1416
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id))
|
|
1402
1417
|
end
|
|
1403
1418
|
end
|
|
1404
1419
|
end
|
|
@@ -1411,8 +1426,8 @@ module Punchblock
|
|
|
1411
1426
|
|
|
1412
1427
|
it 'should create an AGI command component actor and execute it asynchronously' do
|
|
1413
1428
|
mock_action = Translator::Asterisk::Component::Asterisk::AGICommand.new(command, subject)
|
|
1414
|
-
Component::Asterisk::AGICommand.
|
|
1415
|
-
mock_action.
|
|
1429
|
+
expect(Component::Asterisk::AGICommand).to receive(:new).once.with(command, subject).and_return mock_action
|
|
1430
|
+
expect(mock_action).to receive(:execute).once
|
|
1416
1431
|
subject.execute_command command
|
|
1417
1432
|
end
|
|
1418
1433
|
end
|
|
@@ -1424,8 +1439,8 @@ module Punchblock
|
|
|
1424
1439
|
|
|
1425
1440
|
it 'should create an Output component and execute it asynchronously' do
|
|
1426
1441
|
mock_action = Translator::Asterisk::Component::Output.new(command, subject)
|
|
1427
|
-
Component::Output.
|
|
1428
|
-
mock_action.
|
|
1442
|
+
expect(Component::Output).to receive(:new).once.with(command, subject).and_return mock_action
|
|
1443
|
+
expect(mock_action).to receive(:execute).once
|
|
1429
1444
|
subject.execute_command command
|
|
1430
1445
|
end
|
|
1431
1446
|
end
|
|
@@ -1437,8 +1452,8 @@ module Punchblock
|
|
|
1437
1452
|
|
|
1438
1453
|
it 'should create an Input component and execute it asynchronously' do
|
|
1439
1454
|
mock_action = Translator::Asterisk::Component::Input.new(command, subject)
|
|
1440
|
-
Component::Input.
|
|
1441
|
-
mock_action.
|
|
1455
|
+
expect(Component::Input).to receive(:new).once.with(command, subject).and_return mock_action
|
|
1456
|
+
expect(mock_action).to receive(:execute).once
|
|
1442
1457
|
subject.execute_command command
|
|
1443
1458
|
end
|
|
1444
1459
|
end
|
|
@@ -1481,8 +1496,8 @@ module Punchblock
|
|
|
1481
1496
|
let(:renderer) { :unimrcp }
|
|
1482
1497
|
|
|
1483
1498
|
it 'should create an MRCPPrompt component and execute it asynchronously' do
|
|
1484
|
-
Component::MRCPPrompt.
|
|
1485
|
-
mock_action.
|
|
1499
|
+
expect(Component::MRCPPrompt).to receive(:new).once.with(command, subject).and_return mock_action
|
|
1500
|
+
expect(mock_action).to receive(:execute).once
|
|
1486
1501
|
subject.execute_command command
|
|
1487
1502
|
end
|
|
1488
1503
|
end
|
|
@@ -1492,8 +1507,8 @@ module Punchblock
|
|
|
1492
1507
|
let(:renderer) { :asterisk }
|
|
1493
1508
|
|
|
1494
1509
|
it 'should create an MRCPPrompt component and execute it asynchronously' do
|
|
1495
|
-
Component::MRCPNativePrompt.
|
|
1496
|
-
mock_action.
|
|
1510
|
+
expect(Component::MRCPNativePrompt).to receive(:new).once.with(command, subject).and_return mock_action
|
|
1511
|
+
expect(mock_action).to receive(:execute).once
|
|
1497
1512
|
subject.execute_command command
|
|
1498
1513
|
end
|
|
1499
1514
|
end
|
|
@@ -1504,7 +1519,7 @@ module Punchblock
|
|
|
1504
1519
|
|
|
1505
1520
|
it 'should return an error' do
|
|
1506
1521
|
subject.execute_command command
|
|
1507
|
-
command.response(0.5).
|
|
1522
|
+
expect(command.response(0.5)).to eq(ProtocolError.new.setup(:invalid_command, "Invalid recognizer/renderer combination", subject.id))
|
|
1508
1523
|
end
|
|
1509
1524
|
end
|
|
1510
1525
|
|
|
@@ -1513,8 +1528,8 @@ module Punchblock
|
|
|
1513
1528
|
let(:renderer) { :unimrcp }
|
|
1514
1529
|
|
|
1515
1530
|
it 'should create a ComposedPrompt component and execute it asynchronously' do
|
|
1516
|
-
Component::ComposedPrompt.
|
|
1517
|
-
mock_action.
|
|
1531
|
+
expect(Component::ComposedPrompt).to receive(:new).once.with(command, subject).and_return mock_action
|
|
1532
|
+
expect(mock_action).to receive(:execute).once
|
|
1518
1533
|
subject.execute_command command
|
|
1519
1534
|
end
|
|
1520
1535
|
end
|
|
@@ -1527,8 +1542,8 @@ module Punchblock
|
|
|
1527
1542
|
|
|
1528
1543
|
it 'should create a Record component and execute it asynchronously' do
|
|
1529
1544
|
mock_action = Translator::Asterisk::Component::Record.new(command, subject)
|
|
1530
|
-
Component::Record.
|
|
1531
|
-
mock_action.
|
|
1545
|
+
expect(Component::Record).to receive(:new).once.with(command, subject).and_return mock_action
|
|
1546
|
+
expect(mock_action).to receive(:execute).once
|
|
1532
1547
|
subject.execute_command command
|
|
1533
1548
|
end
|
|
1534
1549
|
end
|
|
@@ -1548,7 +1563,7 @@ module Punchblock
|
|
|
1548
1563
|
before { subject.register_component mock_component }
|
|
1549
1564
|
|
|
1550
1565
|
it 'should send the command to the component for execution' do
|
|
1551
|
-
mock_component.
|
|
1566
|
+
expect(mock_component).to receive(:execute_command).once
|
|
1552
1567
|
subject.execute_command command
|
|
1553
1568
|
end
|
|
1554
1569
|
end
|
|
@@ -1580,11 +1595,11 @@ module Punchblock
|
|
|
1580
1595
|
|
|
1581
1596
|
component.send_complete_event Punchblock::Component::Asterisk::AGI::Command::Complete.new
|
|
1582
1597
|
|
|
1583
|
-
subject.component_with_id(comp_id).
|
|
1598
|
+
expect(subject.component_with_id(comp_id)).to be_nil
|
|
1584
1599
|
|
|
1585
1600
|
subsequent_command.request!
|
|
1586
1601
|
subject.execute_command subsequent_command
|
|
1587
|
-
subsequent_command.response.
|
|
1602
|
+
expect(subsequent_command.response).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id))
|
|
1588
1603
|
end
|
|
1589
1604
|
end
|
|
1590
1605
|
|
|
@@ -1593,11 +1608,11 @@ module Punchblock
|
|
|
1593
1608
|
it 'sends an error in response to the command' do
|
|
1594
1609
|
component = subject.component_with_id comp_id
|
|
1595
1610
|
|
|
1596
|
-
component.
|
|
1611
|
+
expect(component).to receive(:execute_command).and_raise(Celluloid::DeadActorError)
|
|
1597
1612
|
|
|
1598
1613
|
subsequent_command.request!
|
|
1599
1614
|
subject.execute_command subsequent_command
|
|
1600
|
-
subsequent_command.response.
|
|
1615
|
+
expect(subsequent_command.response).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id))
|
|
1601
1616
|
end
|
|
1602
1617
|
end
|
|
1603
1618
|
end
|
|
@@ -1606,7 +1621,7 @@ module Punchblock
|
|
|
1606
1621
|
context "for an unknown component ID" do
|
|
1607
1622
|
it 'sends an error in response to the command' do
|
|
1608
1623
|
subject.execute_command command
|
|
1609
|
-
command.response.
|
|
1624
|
+
expect(command.response).to eq(ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{component_id} for call #{subject.id}", subject.id, component_id))
|
|
1610
1625
|
end
|
|
1611
1626
|
end
|
|
1612
1627
|
end
|
|
@@ -1618,7 +1633,7 @@ module Punchblock
|
|
|
1618
1633
|
|
|
1619
1634
|
it 'sends an error in response to the command' do
|
|
1620
1635
|
subject.execute_command command
|
|
1621
|
-
command.response.
|
|
1636
|
+
expect(command.response).to eq(ProtocolError.new.setup('command-not-acceptable', "Did not understand command for call #{subject.id}", subject.id))
|
|
1622
1637
|
end
|
|
1623
1638
|
end
|
|
1624
1639
|
end#execute_command
|
|
@@ -1632,8 +1647,8 @@ module Punchblock
|
|
|
1632
1647
|
end
|
|
1633
1648
|
|
|
1634
1649
|
it 'should send an appropriate AsyncAGI AMI action' do
|
|
1635
|
-
Celluloid::
|
|
1636
|
-
ami_client.
|
|
1650
|
+
expect_any_instance_of(Celluloid::Future).to receive(:value).and_return nil
|
|
1651
|
+
expect(ami_client).to receive(:send_action).once.with('AGI', 'Channel' => channel, 'Command' => 'EXEC ANSWER', 'CommandID' => Punchblock.new_uuid).and_return(response)
|
|
1637
1652
|
subject.execute_agi_command 'EXEC ANSWER'
|
|
1638
1653
|
end
|
|
1639
1654
|
|
|
@@ -1641,8 +1656,8 @@ module Punchblock
|
|
|
1641
1656
|
let(:params) { [1000, 'foo'] }
|
|
1642
1657
|
|
|
1643
1658
|
it 'should send the appropriate action' do
|
|
1644
|
-
Celluloid::
|
|
1645
|
-
ami_client.
|
|
1659
|
+
expect_any_instance_of(Celluloid::Future).to receive(:value).and_return nil
|
|
1660
|
+
expect(ami_client).to receive(:send_action).once.with('AGI', 'Channel' => channel, 'Command' => 'WAIT FOR DIGIT "1000" "foo"', 'CommandID' => Punchblock.new_uuid).and_return(response)
|
|
1646
1661
|
subject.execute_agi_command 'WAIT FOR DIGIT', *params
|
|
1647
1662
|
end
|
|
1648
1663
|
end
|
|
@@ -1655,7 +1670,7 @@ module Punchblock
|
|
|
1655
1670
|
end
|
|
1656
1671
|
|
|
1657
1672
|
it 'should raise the error' do
|
|
1658
|
-
ami_client.
|
|
1673
|
+
expect(ami_client).to receive(:send_action).once.and_raise error
|
|
1659
1674
|
expect { subject.execute_agi_command 'EXEC ANSWER' }.to raise_error(RubyAMI::Error, 'Action failed')
|
|
1660
1675
|
end
|
|
1661
1676
|
|
|
@@ -1663,7 +1678,7 @@ module Punchblock
|
|
|
1663
1678
|
let(:message) { 'No such channel' }
|
|
1664
1679
|
|
|
1665
1680
|
it 'should raise ChannelGoneError' do
|
|
1666
|
-
ami_client.
|
|
1681
|
+
expect(ami_client).to receive(:send_action).once.and_raise error
|
|
1667
1682
|
expect { subject.execute_agi_command 'EXEC ANSWER' }.to raise_error(ChannelGoneError, message)
|
|
1668
1683
|
end
|
|
1669
1684
|
end
|
|
@@ -1672,7 +1687,7 @@ module Punchblock
|
|
|
1672
1687
|
let(:message) { 'Channel SIP/nosuchchannel does not exist.' }
|
|
1673
1688
|
|
|
1674
1689
|
it 'should raise ChannelGoneError' do
|
|
1675
|
-
ami_client.
|
|
1690
|
+
expect(ami_client).to receive(:send_action).once.and_raise error
|
|
1676
1691
|
expect { subject.execute_agi_command 'EXEC ANSWER' }.to raise_error(ChannelGoneError, message)
|
|
1677
1692
|
end
|
|
1678
1693
|
end
|
|
@@ -1696,7 +1711,7 @@ module Punchblock
|
|
|
1696
1711
|
|
|
1697
1712
|
subject.process_ami_event ami_event
|
|
1698
1713
|
|
|
1699
|
-
fut.value.
|
|
1714
|
+
expect(fut.value).to eq({code: 200, result: 123, data: 'timeout'})
|
|
1700
1715
|
end
|
|
1701
1716
|
end
|
|
1702
1717
|
end
|
|
@@ -1710,7 +1725,7 @@ module Punchblock
|
|
|
1710
1725
|
end
|
|
1711
1726
|
|
|
1712
1727
|
it "executes the proper AMI action with only the subject call" do
|
|
1713
|
-
ami_client.
|
|
1728
|
+
expect(ami_client).to receive(:send_action).once.with 'Redirect',
|
|
1714
1729
|
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1715
1730
|
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1716
1731
|
'Context' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT,
|
|
@@ -1719,7 +1734,7 @@ module Punchblock
|
|
|
1719
1734
|
end
|
|
1720
1735
|
|
|
1721
1736
|
it "executes the proper AMI action with another call specified" do
|
|
1722
|
-
ami_client.
|
|
1737
|
+
expect(ami_client).to receive(:send_action).once.with 'Redirect',
|
|
1723
1738
|
'Channel' => channel,
|
|
1724
1739
|
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1725
1740
|
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|