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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -2
  4. data/CHANGELOG.md +17 -0
  5. data/Gemfile +1 -0
  6. data/Guardfile +4 -0
  7. data/README.markdown +6 -0
  8. data/Rakefile +16 -0
  9. data/benchmarks/ami_event_name_comparison.rb +14 -0
  10. data/benchmarks/channel.rb +27 -0
  11. data/lib/punchblock/client.rb +2 -6
  12. data/lib/punchblock/command/accept.rb +3 -24
  13. data/lib/punchblock/command/answer.rb +3 -24
  14. data/lib/punchblock/command/dial.rb +24 -76
  15. data/lib/punchblock/command/hangup.rb +3 -19
  16. data/lib/punchblock/command/join.rb +21 -70
  17. data/lib/punchblock/command/mute.rb +3 -3
  18. data/lib/punchblock/command/redirect.rb +6 -39
  19. data/lib/punchblock/command/reject.rb +14 -54
  20. data/lib/punchblock/command/unjoin.rb +8 -40
  21. data/lib/punchblock/command/unmute.rb +3 -3
  22. data/lib/punchblock/command_node.rb +0 -17
  23. data/lib/punchblock/component/asterisk/agi/command.rb +20 -127
  24. data/lib/punchblock/component/asterisk/ami/action.rb +30 -117
  25. data/lib/punchblock/component/component_node.rb +1 -1
  26. data/lib/punchblock/component/input.rb +89 -268
  27. data/lib/punchblock/component/output.rb +106 -154
  28. data/lib/punchblock/component/prompt.rb +51 -0
  29. data/lib/punchblock/component/record.rb +41 -130
  30. data/lib/punchblock/component.rb +1 -0
  31. data/lib/punchblock/connection/asterisk.rb +31 -4
  32. data/lib/punchblock/connection/xmpp.rb +6 -14
  33. data/lib/punchblock/core_ext/blather/stanza.rb +1 -1
  34. data/lib/punchblock/event/active_speaker.rb +2 -10
  35. data/lib/punchblock/event/answered.rb +3 -3
  36. data/lib/punchblock/event/asterisk/ami/event.rb +15 -47
  37. data/lib/punchblock/event/complete.rb +26 -48
  38. data/lib/punchblock/event/dtmf.rb +3 -13
  39. data/lib/punchblock/event/end.rb +10 -11
  40. data/lib/punchblock/event/joined.rb +5 -25
  41. data/lib/punchblock/event/offer.rb +4 -25
  42. data/lib/punchblock/event/ringing.rb +3 -3
  43. data/lib/punchblock/event/unjoined.rb +5 -25
  44. data/lib/punchblock/event.rb +0 -10
  45. data/lib/punchblock/has_headers.rb +20 -26
  46. data/lib/punchblock/rayo_node.rb +46 -23
  47. data/lib/punchblock/ref.rb +39 -18
  48. data/lib/punchblock/translator/asterisk/agi_app.rb +15 -0
  49. data/lib/punchblock/translator/asterisk/agi_command.rb +3 -1
  50. data/lib/punchblock/translator/asterisk/ami_error_converter.rb +20 -0
  51. data/lib/punchblock/translator/asterisk/call.rb +60 -39
  52. data/lib/punchblock/translator/asterisk/channel.rb +41 -0
  53. data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +4 -1
  54. data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +4 -4
  55. data/lib/punchblock/translator/asterisk/component/composed_prompt.rb +62 -0
  56. data/lib/punchblock/translator/asterisk/component/input.rb +1 -0
  57. data/lib/punchblock/translator/asterisk/component/mrcp_native_prompt.rb +56 -0
  58. data/lib/punchblock/translator/asterisk/component/mrcp_prompt.rb +53 -0
  59. data/lib/punchblock/translator/asterisk/component/mrcp_recog_prompt.rb +99 -0
  60. data/lib/punchblock/translator/asterisk/component/output.rb +30 -22
  61. data/lib/punchblock/translator/asterisk/component/record.rb +8 -6
  62. data/lib/punchblock/translator/asterisk/component.rb +6 -5
  63. data/lib/punchblock/translator/asterisk/unimrcp_app.rb +26 -0
  64. data/lib/punchblock/translator/asterisk.rb +24 -28
  65. data/lib/punchblock/translator/dtmf_recognizer.rb +39 -20
  66. data/lib/punchblock/translator/freeswitch/call.rb +15 -14
  67. data/lib/punchblock/translator/freeswitch/component/abstract_output.rb +5 -4
  68. data/lib/punchblock/translator/freeswitch/component/flite_output.rb +1 -1
  69. data/lib/punchblock/translator/freeswitch/component/input.rb +5 -0
  70. data/lib/punchblock/translator/freeswitch/component/output.rb +2 -2
  71. data/lib/punchblock/translator/freeswitch/component/record.rb +19 -13
  72. data/lib/punchblock/translator/freeswitch/component/tts_output.rb +2 -2
  73. data/lib/punchblock/translator/freeswitch/component.rb +2 -5
  74. data/lib/punchblock/translator/freeswitch.rb +2 -2
  75. data/lib/punchblock/translator/input_component.rb +33 -13
  76. data/lib/punchblock/uri_list.rb +21 -0
  77. data/lib/punchblock/version.rb +1 -1
  78. data/lib/punchblock.rb +4 -3
  79. data/punchblock.gemspec +7 -3
  80. data/spec/punchblock/client/component_registry_spec.rb +1 -1
  81. data/spec/punchblock/client_spec.rb +10 -26
  82. data/spec/punchblock/command/accept_spec.rb +41 -7
  83. data/spec/punchblock/command/answer_spec.rb +51 -7
  84. data/spec/punchblock/command/dial_spec.rb +56 -14
  85. data/spec/punchblock/command/hangup_spec.rb +41 -7
  86. data/spec/punchblock/command/join_spec.rb +53 -11
  87. data/spec/punchblock/command/mute_spec.rb +19 -4
  88. data/spec/punchblock/command/redirect_spec.rb +40 -10
  89. data/spec/punchblock/command/reject_spec.rb +43 -11
  90. data/spec/punchblock/command/unjoin_spec.rb +40 -9
  91. data/spec/punchblock/command/unmute_spec.rb +19 -4
  92. data/spec/punchblock/command_node_spec.rb +0 -4
  93. data/spec/punchblock/component/asterisk/agi/command_spec.rb +16 -39
  94. data/spec/punchblock/component/asterisk/ami/action_spec.rb +50 -53
  95. data/spec/punchblock/component/component_node_spec.rb +3 -5
  96. data/spec/punchblock/component/input_spec.rb +194 -61
  97. data/spec/punchblock/component/output_spec.rb +194 -62
  98. data/spec/punchblock/component/prompt_spec.rb +132 -0
  99. data/spec/punchblock/component/record_spec.rb +70 -32
  100. data/spec/punchblock/connection/asterisk_spec.rb +17 -3
  101. data/spec/punchblock/connection/freeswitch_spec.rb +4 -4
  102. data/spec/punchblock/connection/xmpp_spec.rb +20 -38
  103. data/spec/punchblock/event/answered_spec.rb +12 -10
  104. data/spec/punchblock/event/asterisk/ami/event_spec.rb +27 -22
  105. data/spec/punchblock/event/complete_spec.rb +15 -19
  106. data/spec/punchblock/event/dtmf_spec.rb +5 -6
  107. data/spec/punchblock/event/end_spec.rb +20 -10
  108. data/spec/punchblock/event/joined_spec.rb +8 -7
  109. data/spec/punchblock/event/offer_spec.rb +41 -12
  110. data/spec/punchblock/event/ringing_spec.rb +12 -10
  111. data/spec/punchblock/event/started_speaking_spec.rb +5 -6
  112. data/spec/punchblock/event/stopped_speaking_spec.rb +5 -6
  113. data/spec/punchblock/event/unjoined_spec.rb +7 -7
  114. data/spec/punchblock/ref_spec.rb +86 -9
  115. data/spec/punchblock/translator/asterisk/call_spec.rb +317 -154
  116. data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +28 -5
  117. data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +15 -13
  118. data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +237 -0
  119. data/spec/punchblock/translator/asterisk/component/input_spec.rb +171 -14
  120. data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +652 -0
  121. data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +646 -0
  122. data/spec/punchblock/translator/asterisk/component/output_spec.rb +127 -77
  123. data/spec/punchblock/translator/asterisk/component/record_spec.rb +17 -8
  124. data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +2 -2
  125. data/spec/punchblock/translator/asterisk/component_spec.rb +3 -7
  126. data/spec/punchblock/translator/asterisk_spec.rb +20 -24
  127. data/spec/punchblock/translator/freeswitch/call_spec.rb +103 -99
  128. data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +17 -8
  129. data/spec/punchblock/translator/freeswitch/component/input_spec.rb +26 -14
  130. data/spec/punchblock/translator/freeswitch/component/output_spec.rb +30 -52
  131. data/spec/punchblock/translator/freeswitch/component/record_spec.rb +23 -19
  132. data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +18 -8
  133. data/spec/punchblock/translator/freeswitch/component_spec.rb +4 -8
  134. data/spec/punchblock/translator/freeswitch_spec.rb +11 -14
  135. data/spec/punchblock/uri_list_spec.rb +49 -0
  136. data/spec/punchblock_spec.rb +11 -1
  137. data/spec/spec_helper.rb +7 -11
  138. data/spec/support/mock_connection_with_event_handler.rb +1 -1
  139. metadata +104 -24
  140. data/lib/punchblock/header.rb +0 -9
  141. data/lib/punchblock/key_value_pair_node.rb +0 -51
  142. data/spec/punchblock/header_spec.rb +0 -11
@@ -6,29 +6,28 @@ module Punchblock
6
6
  class Event
7
7
  describe DTMF do
8
8
  it 'registers itself' do
9
- RayoNode.class_from_registration(:dtmf, 'urn:xmpp:rayo:1').should be == DTMF
9
+ RayoNode.class_from_registration(:dtmf, 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
13
13
  let(:stanza) { "<dtmf xmlns='urn:xmpp:rayo:1' signal='#' />" }
14
14
 
15
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
15
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
16
16
 
17
- it { should be_instance_of DTMF }
17
+ it { should be_instance_of described_class }
18
18
 
19
19
  it_should_behave_like 'event'
20
20
 
21
21
  its(:signal) { should be == '#' }
22
- its(:xmlns) { should be == 'urn:xmpp:rayo:1' }
23
22
  end
24
23
 
25
24
  describe "when setting options in initializer" do
26
25
  subject do
27
- DTMF.new :signal => '#'
26
+ described_class.new :signal => '#'
28
27
  end
29
28
 
30
29
  its(:signal) { should be == '#' }
31
30
  end
32
31
  end
33
32
  end
34
- end # Punchblock
33
+ end
@@ -6,14 +6,14 @@ module Punchblock
6
6
  class Event
7
7
  describe End do
8
8
  it 'registers itself' do
9
- RayoNode.class_from_registration(:end, 'urn:xmpp:rayo:1').should be == End
9
+ RayoNode.class_from_registration(:end, 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
13
13
  let :stanza do
14
14
  <<-MESSAGE
15
15
  <end xmlns="urn:xmpp:rayo:1">
16
- <timeout />
16
+ <timeout platform-code="18" />
17
17
  <!-- Signaling (e.g. SIP) Headers -->
18
18
  <header name="X-skill" value="agent" />
19
19
  <header name="X-customer-id" value="8877" />
@@ -21,26 +21,36 @@ module Punchblock
21
21
  MESSAGE
22
22
  end
23
23
 
24
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
24
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
25
25
 
26
- it { should be_instance_of End }
26
+ it { should be_instance_of described_class }
27
27
 
28
28
  it_should_behave_like 'event'
29
- it_should_behave_like 'event_headers'
30
29
 
31
30
  its(:reason) { should be == :timeout }
32
- its(:xmlns) { should be == 'urn:xmpp:rayo:1' }
31
+ its(:platform_code) { should be == '18' }
32
+ its(:headers) { should == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
33
+
34
+ context "with no headers or reason provided" do
35
+ let(:stanza) { '<end xmlns="urn:xmpp:rayo:1"/>' }
36
+
37
+ its(:reason) { should be_nil}
38
+ its(:platform_code) { should be_nil }
39
+ its(:headers) { should == {} }
40
+ end
33
41
  end
34
42
 
35
43
  describe "when setting options in initializer" do
36
44
  subject do
37
- End.new :reason => :hangup,
38
- :headers => { :x_skill => "agent", :x_customer_id => "8877" }
45
+ described_class.new reason: :hangup,
46
+ platform_code: 18,
47
+ headers: { 'X-skill' => 'agent', 'X-customer-id' => '8877' }
39
48
  end
40
49
 
41
50
  its(:reason) { should be == :hangup }
42
- it_should_behave_like 'command_headers'
51
+ its(:platform_code) { should be == '18' }
52
+ its(:headers) { should be == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
43
53
  end
44
54
  end
45
55
  end
46
- end # Punchblock
56
+ end
@@ -6,29 +6,30 @@ module Punchblock
6
6
  class Event
7
7
  describe Joined do
8
8
  it 'registers itself' do
9
- RayoNode.class_from_registration(:joined, 'urn:xmpp:rayo:1').should be == Joined
9
+ RayoNode.class_from_registration(:joined, 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
13
- let(:stanza) { '<joined xmlns="urn:xmpp:rayo:1" call-id="b" mixer-name="m" />' }
13
+ let(:stanza) { '<joined xmlns="urn:xmpp:rayo:1" call-uri="b" mixer-name="m" />' }
14
14
 
15
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
15
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
16
16
 
17
- it { should be_instance_of Joined }
17
+ it { should be_instance_of described_class }
18
18
 
19
19
  it_should_behave_like 'event'
20
20
 
21
+ its(:call_uri) { should be == 'b' }
21
22
  its(:call_id) { should be == 'b' }
22
23
  its(:mixer_name) { should be == 'm' }
23
- its(:xmlns) { should be == 'urn:xmpp:rayo:1' }
24
24
  end
25
25
 
26
26
  describe "when setting options in initializer" do
27
- subject { Joined.new :call_id => 'abc123', :mixer_name => 'blah' }
27
+ subject { described_class.new :call_uri => 'abc123', :mixer_name => 'blah' }
28
28
 
29
+ its(:call_uri) { should be == 'abc123' }
29
30
  its(:call_id) { should be == 'abc123' }
30
31
  its(:mixer_name) { should be == 'blah' }
31
32
  end
32
33
  end
33
34
  end
34
- end # Punchblock
35
+ end
@@ -6,7 +6,7 @@ module Punchblock
6
6
  class Event
7
7
  describe Offer do
8
8
  it 'registers itself' do
9
- RayoNode.class_from_registration(:offer, 'urn:xmpp:rayo:1').should be == Offer
9
+ RayoNode.class_from_registration(:offer, 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
@@ -22,29 +22,58 @@ module Punchblock
22
22
  MESSAGE
23
23
  end
24
24
 
25
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
25
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
26
26
 
27
- it { should be_instance_of Offer }
27
+ it { should be_instance_of described_class }
28
28
 
29
29
  it_should_behave_like 'event'
30
- it_should_behave_like 'event_headers'
31
30
 
32
- its(:to) { should be == 'tel:+18003211212' }
33
- its(:from) { should be == 'tel:+13058881212' }
31
+ its(:to) { should be == 'tel:+18003211212' }
32
+ its(:from) { should be == 'tel:+13058881212' }
33
+ its(:headers) { should == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
34
+
35
+ context "with no headers provided" do
36
+ let(:stanza) { '<offer xmlns="urn:xmpp:rayo:1"/>' }
37
+
38
+ its(:headers) { should == {} }
39
+ end
40
+
41
+ context "with multiple headers of the same name" do
42
+ let :stanza do
43
+ <<-MESSAGE
44
+ <offer xmlns='urn:xmpp:rayo:1'
45
+ to='tel:+18003211212'
46
+ from='tel:+13058881212'>
47
+ <!-- Signaling (e.g. SIP) Headers -->
48
+ <header name="X-skill" value="sales" />
49
+ <header name="X-skill" value="complaints" />
50
+ </offer>
51
+ MESSAGE
52
+ end
53
+
54
+ its(:headers) { should == {'X-skill' => ['sales', 'complaints']} }
55
+ end
34
56
  end
35
57
 
36
58
  describe "when setting options in initializer" do
37
59
  subject do
38
- Offer.new :to => 'tel:+18003211212',
39
- :from => 'tel:+13058881212',
40
- :headers => { :x_skill => "agent", :x_customer_id => "8877" }
60
+ described_class.new to: 'tel:+18003211212',
61
+ from: 'tel:+13058881212',
62
+ headers: { 'X-skill' => 'agent', 'X-customer-id' => '8877' }
41
63
  end
42
64
 
43
- it_should_behave_like 'command_headers'
44
-
45
65
  its(:to) { should be == 'tel:+18003211212' }
46
66
  its(:from) { should be == 'tel:+13058881212' }
67
+ its(:headers) { should == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
68
+
69
+ context "with headers set to nil" do
70
+ subject do
71
+ described_class.new headers: nil
72
+ end
73
+
74
+ its(:headers) { should == {} }
75
+ end
47
76
  end
48
77
  end
49
78
  end
50
- end # Punchblock
79
+ end
@@ -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').should be == Ringing
9
+ RayoNode.class_from_registration(:ringing, 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
@@ -20,23 +20,25 @@ module Punchblock
20
20
  MESSAGE
21
21
  end
22
22
 
23
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
23
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
24
24
 
25
- it { should be_instance_of Ringing }
25
+ it { should be_instance_of described_class }
26
26
 
27
27
  it_should_behave_like 'event'
28
- it_should_behave_like 'event_headers'
28
+ its(:headers) { should == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
29
29
 
30
- its(:xmlns) { should be == 'urn:xmpp:rayo:1' }
30
+ context "with no headers provided" do
31
+ let(:stanza) { '<ringing xmlns="urn:xmpp:rayo:1"/>' }
32
+
33
+ its(:headers) { should == {} }
34
+ end
31
35
  end
32
36
 
33
37
  describe "when setting options in initializer" do
34
- subject do
35
- Ringing.new :headers => { :x_skill => "agent", :x_customer_id => "8877" }
36
- end
38
+ subject { described_class.new headers: { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
37
39
 
38
- it_should_behave_like 'command_headers'
40
+ its(:headers) { should == { 'X-skill' => 'agent', 'X-customer-id' => '8877' } }
39
41
  end
40
42
  end
41
43
  end
42
- end # Punchblock
44
+ 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').should be == StartedSpeaking
9
+ RayoNode.class_from_registration(:'started-speaking', 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
@@ -14,23 +14,22 @@ module Punchblock
14
14
  '<started-speaking xmlns="urn:xmpp:rayo:1" call-id="x0yz4ye-lx7-6ai9njwvw8nsb"/>'
15
15
  end
16
16
 
17
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
17
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
18
18
 
19
- it { should be_instance_of StartedSpeaking }
19
+ it { should be_instance_of described_class }
20
20
 
21
21
  it_should_behave_like 'event'
22
22
 
23
23
  its(:call_id) { should be == "x0yz4ye-lx7-6ai9njwvw8nsb" }
24
- its(:xmlns) { should be == 'urn:xmpp:rayo:1' }
25
24
  end
26
25
 
27
26
  describe "when setting options in initializer" do
28
27
  subject do
29
- StartedSpeaking.new :call_id => 'abc123'
28
+ described_class.new :call_id => 'abc123'
30
29
  end
31
30
 
32
31
  its(:call_id) { should be == 'abc123' }
33
32
  end
34
33
  end
35
34
  end
36
- end # Punchblock
35
+ 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').should be == StoppedSpeaking
9
+ RayoNode.class_from_registration(:'stopped-speaking', 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
@@ -14,23 +14,22 @@ module Punchblock
14
14
  '<stopped-speaking xmlns="urn:xmpp:rayo:1" call-id="x0yz4ye-lx7-6ai9njwvw8nsb"/>'
15
15
  end
16
16
 
17
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
17
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
18
18
 
19
- it { should be_instance_of StoppedSpeaking }
19
+ it { should be_instance_of described_class }
20
20
 
21
21
  it_should_behave_like 'event'
22
22
 
23
23
  its(:call_id) { should be == "x0yz4ye-lx7-6ai9njwvw8nsb" }
24
- its(:xmlns) { should be == 'urn:xmpp:rayo:1' }
25
24
  end
26
25
 
27
26
  describe "when setting options in initializer" do
28
27
  subject do
29
- StoppedSpeaking.new :call_id => 'abc123'
28
+ described_class.new :call_id => 'abc123'
30
29
  end
31
30
 
32
31
  its(:call_id) { should be == 'abc123' }
33
32
  end
34
33
  end
35
34
  end
36
- end # Punchblock
35
+ end
@@ -6,29 +6,29 @@ 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').should be == Unjoined
9
+ RayoNode.class_from_registration(:unjoined, 'urn:xmpp:rayo:1').should be == described_class
10
10
  end
11
11
 
12
12
  describe "from a stanza" do
13
- let(:stanza) { '<unjoined xmlns="urn:xmpp:rayo:1" call-id="b" mixer-name="m" />' }
13
+ let(:stanza) { '<unjoined xmlns="urn:xmpp:rayo:1" call-uri="b" mixer-name="m" />' }
14
14
 
15
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
15
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
16
16
 
17
- it { should be_instance_of Unjoined }
17
+ it { should be_instance_of described_class }
18
18
 
19
19
  it_should_behave_like 'event'
20
20
 
21
+ its(:call_uri) { should be == 'b' }
21
22
  its(:call_id) { should be == 'b' }
22
23
  its(:mixer_name) { should be == 'm' }
23
- its(:xmlns) { should be == 'urn:xmpp:rayo:1' }
24
24
  end
25
25
 
26
26
  describe "when setting options in initializer" do
27
- subject { Unjoined.new :call_id => 'abc123', :mixer_name => 'blah' }
27
+ subject { described_class.new :call_uri => 'abc123', :mixer_name => 'blah' }
28
28
 
29
29
  its(:call_id) { should be == 'abc123' }
30
30
  its(:mixer_name) { should be == 'blah' }
31
31
  end
32
32
  end
33
33
  end
34
- end # Punchblock
34
+ end
@@ -5,25 +5,102 @@ 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').should be == Ref
8
+ RayoNode.class_from_registration(:ref, 'urn:xmpp:rayo:1').should be == described_class
9
9
  end
10
10
 
11
11
  describe "from a stanza" do
12
- let(:stanza) { "<ref id='fgh4590' xmlns='urn:xmpp:rayo:1' />" }
12
+ let(:uri) { 'some_uri' }
13
+ let(:stanza) { "<ref uri='#{uri}' xmlns='urn:xmpp:rayo:1' />" }
13
14
 
14
- subject { RayoNode.import parse_stanza(stanza).root, '9f00061', '1' }
15
+ subject { RayoNode.from_xml parse_stanza(stanza).root, '9f00061', '1' }
15
16
 
16
- it { should be_instance_of Ref }
17
+ it { should be_instance_of described_class }
18
+ its(:target_call_id) { should be == '9f00061' }
17
19
 
18
- it_should_behave_like 'event'
20
+ context "when the URI isn't actually a URI" do
21
+ let(:uri) { 'fgh4590' }
19
22
 
20
- its(:id) { should be == 'fgh4590' }
23
+ its(:uri) { should be == URI('fgh4590') }
24
+ its(:scheme) { should be == nil }
25
+ its(:call_id) { should be == 'fgh4590' }
26
+ its(:domain) { should be == nil }
27
+ its(:component_id) { should be == 'fgh4590' }
28
+ end
29
+
30
+ context "when the URI is an XMPP JID" do
31
+ let(:uri) { 'xmpp:fgh4590@rayo.net/abc123' }
32
+
33
+ its(:uri) { should be == URI('xmpp:fgh4590@rayo.net/abc123') }
34
+ its(:scheme) { should be == 'xmpp' }
35
+ its(:call_id) { should be == 'fgh4590' }
36
+ its(:domain) { should be == 'rayo.net' }
37
+ its(:component_id) { should be == 'abc123' }
38
+ end
39
+
40
+ context "when the URI is an asterisk UUID" do
41
+ let(:uri) { 'asterisk:fgh4590' }
42
+
43
+ its(:uri) { should be == URI('asterisk:fgh4590') }
44
+ its(:scheme) { should be == 'asterisk' }
45
+ its(:call_id) { should be == 'fgh4590' }
46
+ its(:domain) { should be == nil }
47
+ its(:component_id) { should be == 'fgh4590' }
48
+ end
21
49
  end
22
50
 
23
51
  describe "when setting options in initializer" do
24
- subject { Ref.new :id => 'foo' }
52
+ subject { Ref.new uri: uri }
53
+ let(:uri) { 'xmpp:fgh4590@rayo.net/abc123' }
54
+
55
+ its(:uri) { should be == URI('xmpp:fgh4590@rayo.net/abc123') }
56
+
57
+ describe "exporting to Rayo" do
58
+ context "when the URI isn't actually a URI" do
59
+ let(:uri) { 'fgh4590' }
60
+
61
+ it "should export to XML that can be understood by its parser" do
62
+ new_instance = RayoNode.from_xml subject.to_rayo
63
+ new_instance.should be_instance_of described_class
64
+ new_instance.uri.should == URI('fgh4590')
65
+ end
66
+ end
67
+
68
+ context "when the URI is an XMPP JID" do
69
+ let(:uri) { 'xmpp:fgh4590@rayo.net' }
70
+
71
+ it "should export to XML that can be understood by its parser" do
72
+ new_instance = RayoNode.from_xml subject.to_rayo
73
+ new_instance.should be_instance_of described_class
74
+ new_instance.uri.should == URI('xmpp:fgh4590@rayo.net')
75
+ end
76
+ end
77
+
78
+ context "when the URI is an asterisk UUID" do
79
+ let(:uri) { 'asterisk:fgh4590' }
80
+
81
+ it "should export to XML that can be understood by its parser" do
82
+ new_instance = RayoNode.from_xml subject.to_rayo
83
+ new_instance.should be_instance_of described_class
84
+ new_instance.uri.should == URI('asterisk:fgh4590')
85
+ end
86
+ end
87
+
88
+ it "should render to a parent node if supplied" do
89
+ doc = Nokogiri::XML::Document.new
90
+ parent = Nokogiri::XML::Node.new 'foo', doc
91
+ doc.root = parent
92
+ rayo_doc = subject.to_rayo(parent)
93
+ rayo_doc.should == parent
94
+ end
95
+
96
+ context "when attributes are not set" do
97
+ subject { described_class.new }
25
98
 
26
- its(:id) { should be == 'foo' }
99
+ it "should not include them in the XML representation" do
100
+ subject.to_rayo['uri'].should be_nil
101
+ end
102
+ end
103
+ end
27
104
  end
28
105
  end
29
- end # Punchblock
106
+ end