adhearsion 2.6.4 → 3.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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -9
  3. data/CHANGELOG.md +22 -7
  4. data/Gemfile +2 -0
  5. data/README.markdown +4 -5
  6. data/Rakefile +1 -2
  7. data/adhearsion.gemspec +19 -8
  8. data/features/cli_create.feature +19 -3
  9. data/features/step_definitions/cli_steps.rb +0 -11
  10. data/features/support/env.rb +3 -4
  11. data/lib/adhearsion.rb +48 -27
  12. data/lib/adhearsion/call.rb +34 -50
  13. data/lib/adhearsion/call_controller.rb +6 -12
  14. data/lib/adhearsion/call_controller/dial.rb +15 -53
  15. data/lib/adhearsion/call_controller/input.rb +39 -162
  16. data/lib/adhearsion/call_controller/input/ask_grammar_builder.rb +44 -0
  17. data/lib/adhearsion/call_controller/input/menu_builder.rb +136 -0
  18. data/lib/adhearsion/call_controller/input/prompt_builder.rb +78 -0
  19. data/lib/adhearsion/call_controller/input/result.rb +46 -0
  20. data/lib/adhearsion/call_controller/output.rb +48 -67
  21. data/lib/adhearsion/call_controller/output/abstract_player.rb +3 -3
  22. data/lib/adhearsion/call_controller/output/async_player.rb +3 -3
  23. data/lib/adhearsion/call_controller/output/player.rb +1 -1
  24. data/lib/adhearsion/call_controller/record.rb +23 -8
  25. data/lib/adhearsion/calls.rb +1 -1
  26. data/lib/adhearsion/cli_commands/ahn_command.rb +2 -65
  27. data/lib/adhearsion/cli_commands/thor_errors.rb +0 -6
  28. data/lib/adhearsion/configuration.rb +91 -39
  29. data/lib/adhearsion/core_ext/blather/stanza.rb +41 -0
  30. data/lib/adhearsion/core_ext/blather/stanza/presence.rb +13 -0
  31. data/lib/adhearsion/error.rb +5 -0
  32. data/lib/adhearsion/event.rb +21 -0
  33. data/lib/adhearsion/event/active_speaker.rb +11 -0
  34. data/lib/adhearsion/event/answered.rb +11 -0
  35. data/lib/adhearsion/event/asterisk.rb +10 -0
  36. data/lib/adhearsion/event/asterisk/ami.rb +34 -0
  37. data/lib/adhearsion/event/complete.rb +75 -0
  38. data/lib/adhearsion/event/dtmf.rb +11 -0
  39. data/lib/adhearsion/event/end.rb +22 -0
  40. data/lib/adhearsion/event/input_timers_started.rb +9 -0
  41. data/lib/adhearsion/event/joined.rb +17 -0
  42. data/lib/adhearsion/event/offer.rb +14 -0
  43. data/lib/adhearsion/event/ringing.rb +11 -0
  44. data/lib/adhearsion/event/started_speaking.rb +13 -0
  45. data/lib/adhearsion/event/stopped_speaking.rb +13 -0
  46. data/lib/adhearsion/event/unjoined.rb +17 -0
  47. data/lib/adhearsion/events.rb +47 -66
  48. data/lib/adhearsion/foundation.rb +0 -1
  49. data/lib/adhearsion/foundation/object.rb +0 -5
  50. data/lib/adhearsion/generators/app/app_generator.rb +4 -1
  51. data/lib/adhearsion/generators/app/templates/Gemfile.erb +2 -10
  52. data/lib/adhearsion/generators/app/templates/adhearsion.erb +9 -9
  53. data/lib/adhearsion/generators/app/templates/config.ru +7 -0
  54. data/lib/adhearsion/generators/app/templates/en.yml +4 -0
  55. data/lib/adhearsion/generators/app/templates/events.erb +2 -2
  56. data/lib/adhearsion/generators/app/templates/hello_world.wav +0 -0
  57. data/lib/adhearsion/generators/app/templates/simon_game.rb +2 -1
  58. data/lib/adhearsion/generators/app/templates/simon_game_spec.rb +2 -2
  59. data/lib/adhearsion/has_headers.rb +34 -0
  60. data/lib/adhearsion/http_server.rb +37 -0
  61. data/lib/adhearsion/initializer.rb +19 -153
  62. data/lib/adhearsion/logging.rb +6 -25
  63. data/lib/adhearsion/outbound_call.rb +5 -5
  64. data/lib/adhearsion/plugin.rb +1 -0
  65. data/lib/adhearsion/protocol_error.rb +26 -0
  66. data/lib/adhearsion/rayo.rb +30 -0
  67. data/lib/adhearsion/rayo/client.rb +62 -0
  68. data/lib/adhearsion/rayo/client/component_registry.rb +33 -0
  69. data/lib/adhearsion/rayo/command.rb +21 -0
  70. data/lib/adhearsion/rayo/command/accept.rb +16 -0
  71. data/lib/adhearsion/rayo/command/answer.rb +16 -0
  72. data/lib/adhearsion/rayo/command/dial.rb +57 -0
  73. data/lib/adhearsion/rayo/command/hangup.rb +16 -0
  74. data/lib/adhearsion/rayo/command/join.rb +43 -0
  75. data/lib/adhearsion/rayo/command/mute.rb +13 -0
  76. data/lib/adhearsion/rayo/command/redirect.rb +23 -0
  77. data/lib/adhearsion/rayo/command/reject.rb +40 -0
  78. data/lib/adhearsion/rayo/command/unjoin.rb +24 -0
  79. data/lib/adhearsion/rayo/command/unmute.rb +13 -0
  80. data/lib/adhearsion/rayo/command_node.rb +47 -0
  81. data/lib/adhearsion/rayo/component.rb +21 -0
  82. data/lib/adhearsion/rayo/component/asterisk.rb +13 -0
  83. data/lib/adhearsion/rayo/component/asterisk/agi.rb +14 -0
  84. data/lib/adhearsion/rayo/component/asterisk/agi/command.rb +46 -0
  85. data/lib/adhearsion/rayo/component/asterisk/ami.rb +14 -0
  86. data/lib/adhearsion/rayo/component/asterisk/ami/action.rb +61 -0
  87. data/lib/adhearsion/rayo/component/component_node.rb +90 -0
  88. data/lib/adhearsion/rayo/component/input.rb +186 -0
  89. data/lib/adhearsion/rayo/component/output.rb +471 -0
  90. data/lib/adhearsion/rayo/component/prompt.rb +53 -0
  91. data/lib/adhearsion/rayo/component/receive_fax.rb +26 -0
  92. data/lib/adhearsion/rayo/component/record.rb +165 -0
  93. data/lib/adhearsion/rayo/component/send_fax.rb +64 -0
  94. data/lib/adhearsion/rayo/component/stop.rb +11 -0
  95. data/lib/adhearsion/rayo/connection.rb +12 -0
  96. data/lib/adhearsion/rayo/connection/asterisk.rb +74 -0
  97. data/lib/adhearsion/rayo/connection/connected.rb +22 -0
  98. data/lib/adhearsion/rayo/connection/generic_connection.rb +22 -0
  99. data/lib/adhearsion/rayo/connection/xmpp.rb +198 -0
  100. data/lib/adhearsion/rayo/disconnected_error.rb +22 -0
  101. data/lib/adhearsion/{punchblock_plugin → rayo}/initializer.rb +19 -19
  102. data/lib/adhearsion/rayo/rayo_node.rb +127 -0
  103. data/lib/adhearsion/rayo/ref.rb +57 -0
  104. data/lib/adhearsion/statistics.rb +1 -1
  105. data/lib/adhearsion/tasks.rb +1 -2
  106. data/lib/adhearsion/tasks/configuration.rb +1 -1
  107. data/lib/adhearsion/tasks/environment.rb +0 -2
  108. data/lib/adhearsion/tasks/i18n.rb +49 -0
  109. data/lib/adhearsion/translator.rb +11 -0
  110. data/lib/adhearsion/translator/asterisk.rb +234 -0
  111. data/lib/adhearsion/translator/asterisk/agi_app.rb +17 -0
  112. data/lib/adhearsion/translator/asterisk/agi_command.rb +45 -0
  113. data/lib/adhearsion/translator/asterisk/ami_error_converter.rb +20 -0
  114. data/lib/adhearsion/translator/asterisk/call.rb +416 -0
  115. data/lib/adhearsion/translator/asterisk/channel.rb +43 -0
  116. data/lib/adhearsion/translator/asterisk/component.rb +88 -0
  117. data/lib/adhearsion/translator/asterisk/component/asterisk.rb +15 -0
  118. data/lib/adhearsion/translator/asterisk/component/asterisk/agi_command.rb +42 -0
  119. data/lib/adhearsion/translator/asterisk/component/asterisk/ami_action.rb +68 -0
  120. data/lib/adhearsion/translator/asterisk/component/composed_prompt.rb +76 -0
  121. data/lib/adhearsion/translator/asterisk/component/dtmf_recognizer.rb +137 -0
  122. data/lib/adhearsion/translator/asterisk/component/input.rb +34 -0
  123. data/lib/adhearsion/translator/asterisk/component/input_component.rb +90 -0
  124. data/lib/adhearsion/translator/asterisk/component/mrcp_native_prompt.rb +71 -0
  125. data/lib/adhearsion/translator/asterisk/component/mrcp_prompt.rb +55 -0
  126. data/lib/adhearsion/translator/asterisk/component/mrcp_recog_prompt.rb +165 -0
  127. data/lib/adhearsion/translator/asterisk/component/output.rb +233 -0
  128. data/lib/adhearsion/translator/asterisk/component/record.rb +101 -0
  129. data/lib/adhearsion/translator/asterisk/component/stop_by_redirect.rb +30 -0
  130. data/lib/adhearsion/translator/asterisk/unimrcp_app.rb +28 -0
  131. data/lib/adhearsion/uri_list.rb +21 -0
  132. data/lib/adhearsion/version.rb +1 -1
  133. data/spec/adhearsion/call_controller/dial_spec.rb +79 -1420
  134. data/spec/adhearsion/call_controller/input_spec.rb +1141 -237
  135. data/spec/adhearsion/call_controller/output/async_player_spec.rb +10 -10
  136. data/spec/adhearsion/call_controller/output/player_spec.rb +8 -8
  137. data/spec/adhearsion/call_controller/output_spec.rb +162 -215
  138. data/spec/adhearsion/call_controller/record_spec.rb +15 -16
  139. data/spec/adhearsion/call_controller_spec.rb +23 -40
  140. data/spec/adhearsion/call_spec.rb +123 -129
  141. data/spec/adhearsion/calls_spec.rb +3 -3
  142. data/spec/adhearsion/configuration_spec.rb +94 -108
  143. data/spec/adhearsion/event/answered_spec.rb +50 -0
  144. data/spec/adhearsion/event/asterisk/Find Results +402 -0
  145. data/spec/adhearsion/event/asterisk/ami_spec.rb +81 -0
  146. data/spec/adhearsion/event/complete_spec.rb +176 -0
  147. data/spec/adhearsion/event/dtmf_spec.rb +35 -0
  148. data/spec/adhearsion/event/end_spec.rb +85 -0
  149. data/spec/adhearsion/event/input_timers_started_spec.rb +19 -0
  150. data/spec/adhearsion/event/joined_spec.rb +53 -0
  151. data/spec/adhearsion/event/offer_spec.rb +106 -0
  152. data/spec/adhearsion/event/ringing_spec.rb +50 -0
  153. data/spec/adhearsion/event/started_speaking_spec.rb +37 -0
  154. data/spec/adhearsion/event/stopped_speaking_spec.rb +37 -0
  155. data/spec/adhearsion/event/unjoined_spec.rb +48 -0
  156. data/spec/adhearsion/event/untitled +0 -0
  157. data/spec/adhearsion/events_spec.rb +19 -45
  158. data/spec/adhearsion/initializer_spec.rb +12 -184
  159. data/spec/adhearsion/logging_spec.rb +5 -20
  160. data/spec/adhearsion/outbound_call_spec.rb +13 -13
  161. data/spec/adhearsion/plugin_spec.rb +3 -4
  162. data/spec/adhearsion/protocol_error_spec.rb +91 -0
  163. data/spec/adhearsion/rayo/client/component_registry_spec.rb +26 -0
  164. data/spec/adhearsion/rayo/client_spec.rb +134 -0
  165. data/spec/adhearsion/rayo/command/accept_spec.rb +63 -0
  166. data/spec/adhearsion/rayo/command/answer_spec.rb +73 -0
  167. data/spec/adhearsion/rayo/command/dial_spec.rb +156 -0
  168. data/spec/adhearsion/rayo/command/hangup_spec.rb +63 -0
  169. data/spec/adhearsion/rayo/command/join_spec.rb +158 -0
  170. data/spec/adhearsion/rayo/command/mute_spec.rb +32 -0
  171. data/spec/adhearsion/rayo/command/redirect_spec.rb +89 -0
  172. data/spec/adhearsion/rayo/command/reject_spec.rb +117 -0
  173. data/spec/adhearsion/rayo/command/unjoin_spec.rb +82 -0
  174. data/spec/adhearsion/rayo/command/unmute_spec.rb +32 -0
  175. data/spec/adhearsion/rayo/command_node_spec.rb +101 -0
  176. data/spec/adhearsion/rayo/component/asterisk/agi/command_spec.rb +111 -0
  177. data/spec/adhearsion/rayo/component/asterisk/ami/action_spec.rb +173 -0
  178. data/spec/adhearsion/rayo/component/component_node_spec.rb +110 -0
  179. data/spec/adhearsion/rayo/component/input_spec.rb +715 -0
  180. data/spec/adhearsion/rayo/component/output_spec.rb +1030 -0
  181. data/spec/adhearsion/rayo/component/prompt_spec.rb +171 -0
  182. data/spec/adhearsion/rayo/component/receive_fax_spec.rb +136 -0
  183. data/spec/adhearsion/rayo/component/record_spec.rb +497 -0
  184. data/spec/adhearsion/rayo/component/send_fax_spec.rb +144 -0
  185. data/spec/adhearsion/rayo/connection/asterisk_spec.rb +118 -0
  186. data/spec/adhearsion/rayo/connection/xmpp_spec.rb +449 -0
  187. data/spec/adhearsion/rayo/initializer_spec.rb +353 -0
  188. data/spec/adhearsion/rayo/ref_spec.rb +168 -0
  189. data/spec/adhearsion/rayo_spec.rb +7 -0
  190. data/spec/adhearsion/router/route_spec.rb +1 -1
  191. data/spec/adhearsion/statistics_spec.rb +2 -5
  192. data/spec/adhearsion/translator/asterisk/call_spec.rb +2047 -0
  193. data/spec/adhearsion/translator/asterisk/component/asterisk/agi_command_spec.rb +256 -0
  194. data/spec/adhearsion/translator/asterisk/component/asterisk/ami_action_spec.rb +151 -0
  195. data/spec/adhearsion/translator/asterisk/component/composed_prompt_spec.rb +257 -0
  196. data/spec/adhearsion/translator/asterisk/component/input_spec.rb +571 -0
  197. data/spec/adhearsion/translator/asterisk/component/mrcp_native_prompt_spec.rb +774 -0
  198. data/spec/adhearsion/translator/asterisk/component/mrcp_prompt_spec.rb +1244 -0
  199. data/spec/adhearsion/translator/asterisk/component/output_spec.rb +1850 -0
  200. data/spec/adhearsion/translator/asterisk/component/record_spec.rb +426 -0
  201. data/spec/adhearsion/translator/asterisk/component/stop_by_redirect_spec.rb +62 -0
  202. data/spec/adhearsion/translator/asterisk/component_spec.rb +83 -0
  203. data/spec/adhearsion/translator/asterisk_spec.rb +685 -0
  204. data/spec/adhearsion/uri_list_spec.rb +88 -0
  205. data/spec/adhearsion_spec.rb +89 -14
  206. data/spec/fixtures/locale/en.yml +13 -0
  207. data/spec/fixtures/locale/it.yml +13 -0
  208. data/spec/spec_helper.rb +18 -5
  209. data/spec/support/call_controller_test_helpers.rb +3 -2
  210. data/spec/support/initializer_stubs.rb +3 -1
  211. data/spec/support/punchblock_examples.rb +65 -0
  212. data/spec/support/punchblock_mocks.rb +12 -0
  213. metadata +412 -70
  214. data/features/cli_daemon.feature +0 -20
  215. data/features/cli_restart.feature +0 -52
  216. data/features/cli_stop.feature +0 -50
  217. data/lib/adhearsion/call_controller/menu_dsl.rb +0 -21
  218. data/lib/adhearsion/call_controller/menu_dsl/array_match_calculator.rb +0 -26
  219. data/lib/adhearsion/call_controller/menu_dsl/calculated_match.rb +0 -43
  220. data/lib/adhearsion/call_controller/menu_dsl/calculated_match_collection.rb +0 -45
  221. data/lib/adhearsion/call_controller/menu_dsl/fixnum_match_calculator.rb +0 -11
  222. data/lib/adhearsion/call_controller/menu_dsl/match_calculator.rb +0 -40
  223. data/lib/adhearsion/call_controller/menu_dsl/menu.rb +0 -207
  224. data/lib/adhearsion/call_controller/menu_dsl/menu_builder.rb +0 -92
  225. data/lib/adhearsion/call_controller/menu_dsl/range_match_calculator.rb +0 -60
  226. data/lib/adhearsion/call_controller/menu_dsl/string_match_calculator.rb +0 -25
  227. data/lib/adhearsion/call_controller/utility.rb +0 -77
  228. data/lib/adhearsion/foundation/custom_daemonizer.rb +0 -52
  229. data/lib/adhearsion/punchblock_plugin.rb +0 -63
  230. data/scripts/cloc-1.64.pl +0 -10483
  231. data/spec/adhearsion/call_controller/menu_dsl/array_match_calculator_spec.rb +0 -76
  232. data/spec/adhearsion/call_controller/menu_dsl/calculated_match_collection_spec.rb +0 -60
  233. data/spec/adhearsion/call_controller/menu_dsl/calculated_match_spec.rb +0 -61
  234. data/spec/adhearsion/call_controller/menu_dsl/fixnum_match_calculator_spec.rb +0 -39
  235. data/spec/adhearsion/call_controller/menu_dsl/match_calculator_spec.rb +0 -17
  236. data/spec/adhearsion/call_controller/menu_dsl/menu_builder_spec.rb +0 -165
  237. data/spec/adhearsion/call_controller/menu_dsl/menu_spec.rb +0 -420
  238. data/spec/adhearsion/call_controller/menu_dsl/range_match_calculator_spec.rb +0 -32
  239. data/spec/adhearsion/call_controller/menu_dsl/string_match_calculator_spec.rb +0 -40
  240. data/spec/adhearsion/call_controller/utility_spec.rb +0 -90
  241. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +0 -356
  242. data/spec/adhearsion/punchblock_plugin_spec.rb +0 -59
@@ -1,32 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- module Adhearsion
6
- class CallController
7
- module MenuDSL
8
-
9
- describe RangeMatchCalculator do
10
- it "matching with a Range should handle the case of two potential matches in the range" do
11
- digits_that_begin_with_eleven = [110..119, 1100..1111].map { |x| Array(x) }.flatten
12
- calculator = RangeMatchCalculator.new 11..1111, :match_payload_doesnt_matter
13
- match = calculator.match '11'
14
- expect(match.exact_matches).to eq(['11'])
15
- expect(match.potential_matches).to eq(digits_that_begin_with_eleven)
16
- end
17
-
18
- it "return values of #match should be an instance of CalculatedMatch" do
19
- calculator = RangeMatchCalculator.new 1..9, :match_payload_doesnt_matter
20
- expect(calculator.match('0')).to be_an_instance_of CalculatedMatch
21
- expect(calculator.match('1000')).to be_an_instance_of CalculatedMatch
22
- end
23
-
24
- it "returns a failed match if the query is not numeric or coercible to numeric" do
25
- calculator = RangeMatchCalculator.new 1..9, :match_payload_doesnt_matter
26
- expect(calculator.match("ABC")).to be_an_instance_of CalculatedMatch
27
- end
28
- end
29
-
30
- end
31
- end
32
- end
@@ -1,40 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- module Adhearsion
6
- class CallController
7
- module MenuDSL
8
- describe StringMatchCalculator do
9
-
10
- let(:match_payload) { :doesnt_matter }
11
-
12
- it "numerical digits mixed with special digits" do
13
- %w[5*11#3 5*** ###].each do |str|
14
- calculator = StringMatchCalculator.new str, match_payload
15
-
16
- match_case = calculator.match str[0,2]
17
- expect(match_case).not_to be_exact_match
18
- expect(match_case).to be_potential_match
19
- expect(match_case.potential_matches).to eq([str])
20
-
21
- match_case = calculator.match str
22
- expect(match_case).to be_exact_match
23
- expect(match_case).not_to be_potential_match
24
- expect(match_case.exact_matches).to eq([str])
25
- end
26
- end
27
-
28
- it "matching the special DTMF characters such as * and #" do
29
- %w[* #].each do |special_digit|
30
- calculator = StringMatchCalculator.new(special_digit, match_payload)
31
- match_case = calculator.match special_digit
32
- expect(match_case.exact_matches.first).to eq(special_digit)
33
- expect(match_case).to be_exact_match
34
- expect(match_case).not_to be_potential_match
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,90 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
- require 'ruby_speech'
5
-
6
- module Adhearsion
7
- class CallController
8
- describe Utility do
9
- include CallControllerTestHelpers
10
-
11
- describe "#grammar_digits" do
12
- let(:grxml) {
13
- RubySpeech::GRXML.draw :mode => 'dtmf', :root => 'inputdigits' do
14
- rule id: 'inputdigits', scope: 'public' do
15
- item repeat: '2' do
16
- one_of do
17
- 0.upto(9) { |d| item { d.to_s } }
18
- end
19
- end
20
- end
21
- end
22
- }
23
-
24
- it 'generates the correct GRXML grammar' do
25
- expect(subject.grammar_digits(2).to_s).to eq(grxml.to_s)
26
- end
27
-
28
- end # describe #grammar_digits
29
-
30
- describe "#grammar_accept" do
31
- let(:grxml) {
32
- RubySpeech::GRXML.draw :mode => 'dtmf', :root => 'inputdigits' do
33
- rule id: 'inputdigits', scope: 'public' do
34
- one_of do
35
- item { '3' }
36
- item { '5' }
37
- end
38
- end
39
- end
40
- }
41
-
42
- it 'generates the correct GRXML grammar' do
43
- expect(subject.grammar_accept('35').to_s).to eq(grxml.to_s)
44
- end
45
-
46
- it 'filters meaningless characters out' do
47
- expect(subject.grammar_accept('3+5').to_s).to eq(grxml.to_s)
48
- end
49
- end # grammar_accept
50
-
51
- describe "#parse_dtmf" do
52
- context "with a single digit" do
53
- it "correctly returns the parsed input" do
54
- expect(subject.parse_dtmf("dtmf-3")).to eq('3')
55
- end
56
-
57
- it "correctly returns star as *" do
58
- expect(subject.parse_dtmf("dtmf-star")).to eq('*')
59
- end
60
-
61
- it "correctly returns * as *" do
62
- expect(subject.parse_dtmf("*")).to eq('*')
63
- end
64
-
65
- it "correctly returns pound as #" do
66
- expect(subject.parse_dtmf("dtmf-pound")).to eq('#')
67
- end
68
-
69
- it "correctly returns # as #" do
70
- expect(subject.parse_dtmf("#")).to eq('#')
71
- end
72
-
73
- it "correctly parses digits without the dtmf- prefix" do
74
- expect(subject.parse_dtmf('1')).to eq('1')
75
- end
76
-
77
- it "correctly returns nil when input is nil" do
78
- expect(subject.parse_dtmf(nil)).to eq(nil)
79
- end
80
- end
81
-
82
- context "with multiple digits separated by spaces" do
83
- it "returns the digits without space separation" do
84
- expect(subject.parse_dtmf('1 dtmf-5 dtmf-star # 2')).to eq('15*#2')
85
- end
86
- end
87
- end # describe #grammar_accept
88
- end
89
- end
90
- end
@@ -1,356 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- module Adhearsion
6
- class PunchblockPlugin
7
- describe Initializer do
8
-
9
- def reset_default_config
10
- Adhearsion.config.punchblock do |config|
11
- config.platform = :xmpp
12
- config.username = "usera@127.0.0.1"
13
- config.password = "1"
14
- config.host = nil
15
- config.port = nil
16
- config.certs_directory = nil
17
- config.root_domain = nil
18
- config.connection_timeout = 60
19
- config.reconnect_attempts = 1.0/0.0
20
- config.reconnect_timer = 5
21
- end
22
- end
23
-
24
- def initialize_punchblock(options = {})
25
- reset_default_config
26
- allow(Initializer).to receive(:connect)
27
- Adhearsion.config.punchblock do |config|
28
- config.platform = options[:platform] if options.has_key?(:platform)
29
- config.username = options[:username] if options.has_key?(:username)
30
- config.password = options[:password] if options.has_key?(:password)
31
- config.host = options[:host] if options.has_key?(:host)
32
- config.port = options[:port] if options.has_key?(:port)
33
- config.certs_directory = options[:certs_directory] if options.has_key?(:certs_directory)
34
- config.root_domain = options[:root_domain] if options.has_key?(:root_domain)
35
- config.connection_timeout = options[:connection_timeout] if options.has_key?(:connection_timeout)
36
- config.reconnect_attempts = options[:reconnect_attempts] if options.has_key?(:reconnect_attempts)
37
- config.reconnect_timer = options[:reconnect_timer] if options.has_key?(:reconnect_timer)
38
- end
39
-
40
- Initializer.init
41
- Adhearsion.config[:punchblock]
42
- end
43
-
44
- let(:call_id) { rand }
45
- let(:offer) { Punchblock::Event::Offer.new :target_call_id => call_id }
46
- let(:mock_call) { Call.new }
47
- let(:mock_client) { double 'Client' }
48
-
49
- before do
50
- allow(mock_call).to receive_messages :id => call_id
51
- mock_client.as_null_object
52
- allow(mock_client).to receive_messages :event_handler= => true
53
- Events.refresh!
54
- allow(Adhearsion::Process).to receive_messages :fqdn => 'hostname'
55
- allow(::Process).to receive_messages :pid => 1234
56
- end
57
-
58
- describe "starts the client with the default values" do
59
- subject { initialize_punchblock }
60
-
61
- it "should set properly the username value" do
62
- expect(subject.username).to eq('usera@127.0.0.1')
63
- end
64
-
65
- it "should set properly the password value" do
66
- expect(subject.password).to eq('1')
67
- end
68
-
69
- it "should set properly the host value" do
70
- expect(subject.host).to be_nil
71
- end
72
-
73
- it "should set properly the port value" do
74
- expect(subject.port).to be_nil
75
- end
76
-
77
- it "should set properly the certs_directory value" do
78
- expect(subject.certs_directory).to be_nil
79
- end
80
-
81
- it "should set properly the root_domain value" do
82
- expect(subject.root_domain).to be_nil
83
- end
84
-
85
- it "should properly set the reconnect_attempts value" do
86
- expect(subject.reconnect_attempts).to eq(1.0/0.0)
87
- end
88
-
89
- it "should properly set the reconnect_timer value" do
90
- expect(subject.reconnect_timer).to eq(5)
91
- end
92
- end
93
-
94
- it "starts the client with the correct resource" do
95
- username = "usera@127.0.0.1/hostname-1234"
96
-
97
- expect(Punchblock::Connection::XMPP).to receive(:new).once.with(hash_including :username => username).and_return mock_client
98
- initialize_punchblock
99
- end
100
-
101
- context "when the fqdn is not available" do
102
- it "should use the local hostname instead" do
103
- allow(Adhearsion::Process).to receive(:fqdn).and_raise SocketError
104
- allow(Socket).to receive(:gethostname).and_return 'local_hostname'
105
-
106
- username = "usera@127.0.0.1/local_hostname-1234"
107
-
108
- expect(Punchblock::Connection::XMPP).to receive(:new).once.with(hash_including :username => username).and_return mock_client
109
- initialize_punchblock
110
- end
111
- end
112
-
113
- it "starts the client with any overridden settings" do
114
- expect(Punchblock::Connection::XMPP).to receive(:new).once.with(username: 'userb@127.0.0.1/foo', password: '123', host: 'foo.bar.com', port: 200, certs: '/foo/bar', connection_timeout: 20, root_domain: 'foo.com').and_return mock_client
115
- initialize_punchblock username: 'userb@127.0.0.1/foo', password: '123', host: 'foo.bar.com', port: 200, certs_directory: '/foo/bar', connection_timeout: 20, root_domain: 'foo.com'
116
- end
117
-
118
- describe "#connect" do
119
- it 'should block until the connection is established' do
120
- reset_default_config
121
- mock_connection = double :mock_connection
122
- expect(mock_connection).to receive(:register_event_handler).once
123
- expect(Punchblock::Client).to receive(:new).once.and_return mock_connection
124
- expect(mock_connection).to receive(:run).once
125
- t = Thread.new { Initializer.init; Initializer.run }
126
- t.join 5
127
- expect(t.status).to eq("sleep")
128
- Events.trigger_immediately :punchblock, Punchblock::Connection::Connected.new
129
- t.join
130
- end
131
- end
132
-
133
- describe '#connect_to_server' do
134
- before :each do
135
- Adhearsion::Process.reset
136
- Initializer.config = reset_default_config
137
- Initializer.config.reconnect_attempts = 1
138
- expect(Adhearsion::Logging.get_logger(Initializer)).to receive(:fatal).at_most(:once)
139
- allow(Initializer).to receive(:client).and_return mock_client
140
- end
141
-
142
- after :each do
143
- Adhearsion::Process.reset
144
- end
145
-
146
- it 'should reset the Adhearsion process state to "booting"' do
147
- Adhearsion::Process.booted
148
- expect(Adhearsion::Process.state_name).to eq(:running)
149
- allow(mock_client).to receive(:run).and_raise Punchblock::DisconnectedError
150
- expect(Adhearsion::Process).to receive(:reset).at_least(:once)
151
- Initializer.connect_to_server
152
- end
153
-
154
- it 'should retry the connection the specified number of times' do
155
- Initializer.config.reconnect_attempts = 3
156
- allow(mock_client).to receive(:run).and_raise Punchblock::DisconnectedError
157
- Initializer.connect_to_server
158
- expect(Initializer.attempts).to eq(3)
159
- end
160
-
161
- it 'should preserve a Punchblock::ProtocolError exception and give up' do
162
- allow(mock_client).to receive(:run).and_raise Punchblock::ProtocolError
163
- expect { Initializer.connect_to_server }.to raise_error Punchblock::ProtocolError
164
- end
165
-
166
- it 'should not attempt to reconnect if Adhearsion is shutting down' do
167
- Adhearsion::Process.booted
168
- Adhearsion::Process.shutdown
169
- allow(mock_client).to receive(:run).and_raise Punchblock::DisconnectedError
170
- expect { Initializer.connect_to_server }.not_to raise_error
171
- end
172
- end
173
-
174
- describe 'using Asterisk' do
175
- let(:overrides) { {:username => 'test', :password => '123', :host => 'foo.bar.com', :port => 200, :certs => nil, :connection_timeout => 20, :root_domain => 'foo.com'} }
176
-
177
- it 'should start an Asterisk PB connection' do
178
- expect(Punchblock::Connection::Asterisk).to receive(:new).once.with(overrides).and_return mock_client
179
- initialize_punchblock overrides.merge(:platform => :asterisk)
180
- end
181
- end
182
-
183
- describe 'using FreeSWITCH' do
184
- let(:overrides) { {:username => 'test', :password => '123', :host => 'foo.bar.com', :port => 200, :certs => nil, :connection_timeout => 20, :root_domain => 'foo.com'} }
185
-
186
- it 'should start a FreeSWITCH PB connection' do
187
- expect(Punchblock::Connection::Freeswitch).to receive(:new).once.with(overrides).and_return mock_client
188
- initialize_punchblock overrides.merge(:platform => :freeswitch)
189
- end
190
- end
191
-
192
- it 'should place events from Punchblock into the event handler' do
193
- expect(Events.instance).to receive(:trigger).once.with(:punchblock, offer)
194
- initialize_punchblock
195
- Initializer.client.handle_event offer
196
- end
197
-
198
- describe "dispatching an offer" do
199
- before do
200
- initialize_punchblock
201
- expect(Adhearsion::Process).to receive(:state_name).once.and_return process_state
202
- expect(Adhearsion::Call).to receive(:new).once.and_return mock_call
203
- end
204
-
205
- context "when the Adhearsion::Process is :booting" do
206
- let(:process_state) { :booting }
207
-
208
- it 'should reject a call with cause :declined' do
209
- expect(mock_call).to receive(:reject).once.with(:decline)
210
- end
211
- end
212
-
213
- [ :running, :stopping ].each do |state|
214
- context "when when Adhearsion::Process is in :#{state}" do
215
- let(:process_state) { state }
216
-
217
- it "should dispatch via the router" do
218
- Adhearsion.router do
219
- route 'foobar', Class.new
220
- end
221
- expect(Adhearsion.router).to receive(:handle).once.with mock_call
222
- end
223
- end
224
- end
225
-
226
- context "when when Adhearsion::Process is in :rejecting" do
227
- let(:process_state) { :rejecting }
228
-
229
- it 'should reject a call with cause :declined' do
230
- expect(mock_call).to receive(:reject).once.with(:decline)
231
- end
232
- end
233
-
234
- context "when when Adhearsion::Process is not :running, :stopping or :rejecting" do
235
- let(:process_state) { :foobar }
236
-
237
- it 'should reject a call with cause :error' do
238
- expect(mock_call).to receive(:reject).once.with(:error)
239
- end
240
- end
241
-
242
- after { Events.trigger_immediately :punchblock, offer }
243
- end
244
-
245
- describe "dispatching a component event" do
246
- let(:component) { double 'ComponentNode' }
247
- let(:mock_event) { double 'Event' }
248
-
249
- before { allow(mock_event).to receive_messages target_call_id: call_id, source: component }
250
-
251
- before do
252
- initialize_punchblock
253
- end
254
-
255
- it "should place the event in the call's inbox" do
256
- expect(component).to receive(:trigger_event_handler).once.with mock_event
257
- Events.trigger_immediately :punchblock, mock_event
258
- end
259
- end
260
-
261
- describe "dispatching a call event" do
262
- let(:mock_event) { double 'Event' }
263
-
264
- before { allow(mock_event).to receive_messages target_call_id: call_id }
265
-
266
- describe "with an active call" do
267
- before do
268
- initialize_punchblock
269
- Adhearsion.active_calls << mock_call
270
- end
271
-
272
- it "should forward the event to the call actor" do
273
- events = []
274
- mock_call.register_event_handler do |event|
275
- events << event
276
- end
277
- Initializer.dispatch_call_event mock_event
278
- sleep 0.5
279
- expect(events).to eql([mock_event])
280
- end
281
-
282
- it "should not block on the call handling the event" do
283
-
284
- mock_call.register_event_handler do |event|
285
- sleep 5
286
- end
287
- start_time = Time.now
288
- Initializer.dispatch_call_event mock_event
289
- sleep 0.5
290
- expect(Time.now - start_time).to be < 1
291
- end
292
- end
293
-
294
- describe "with an inactive call" do
295
- it "should log a warning" do
296
- expect(Adhearsion::Logging.get_logger(Initializer)).to receive(:warn).once.with("Event received for inactive call #{call_id}: #{mock_event.inspect}")
297
- Initializer.dispatch_call_event mock_event
298
- end
299
- end
300
-
301
- describe "when the registry contains a dead call" do
302
- before do
303
- mock_call.terminate
304
- Adhearsion.active_calls[mock_call.id] = mock_call
305
- end
306
-
307
- it "should log a warning" do
308
- expect(Adhearsion::Logging.get_logger(Initializer)).to receive(:warn).once.with("Event received for inactive call #{call_id}: #{mock_event.inspect}")
309
- Initializer.dispatch_call_event mock_event
310
- end
311
- end
312
- end
313
-
314
- context "Punchblock configuration" do
315
- describe "with config specified" do
316
- before do
317
- Adhearsion.config.punchblock do |config|
318
- config.username = 'userb@127.0.0.1'
319
- config.password = 'abc123'
320
- end
321
- end
322
-
323
- subject do
324
- Adhearsion.config[:punchblock]
325
- end
326
-
327
- it "should set properly the username value" do
328
- expect(subject.username).to eq('userb@127.0.0.1')
329
- end
330
-
331
- it "should set properly the password value" do
332
- expect(subject.password).to eq('abc123')
333
- end
334
- end
335
- end
336
-
337
- it "should allow easily registering handlers for AMI events" do
338
- result = nil
339
- ami_event = Punchblock::Event::Asterisk::AMI::Event.new :name => 'foobar'
340
- latch = CountDownLatch.new 1
341
-
342
- Events.draw do
343
- ami :name => 'foobar' do |event|
344
- result = event
345
- latch.countdown!
346
- end
347
- end
348
-
349
- Initializer.handle_event ami_event
350
-
351
- expect(latch.wait(1)).to be true
352
- expect(result).to be ami_event
353
- end
354
- end
355
- end
356
- end