adhearsion 1.2.6 → 2.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (236) hide show
  1. data/.gitignore +17 -10
  2. data/CHANGELOG.md +273 -0
  3. data/Gemfile +1 -1
  4. data/Guardfile +17 -0
  5. data/README.markdown +61 -9
  6. data/Rakefile +16 -48
  7. data/adhearsion.gemspec +21 -7
  8. data/bin/ahn +3 -1
  9. data/cucumber.yml +4 -0
  10. data/features/app_generator.feature +42 -0
  11. data/features/cli.feature +108 -0
  12. data/features/step_definitions/app_generator_steps.rb +6 -0
  13. data/features/step_definitions/cli_steps.rb +74 -0
  14. data/features/support/aruba_helper.rb +22 -0
  15. data/features/support/env.rb +37 -0
  16. data/features/support/utils.rb +8 -0
  17. data/lib/adhearsion.rb +85 -41
  18. data/lib/adhearsion/call.rb +176 -0
  19. data/lib/adhearsion/call_controller.rb +134 -0
  20. data/lib/adhearsion/call_controller/dial.rb +70 -0
  21. data/lib/adhearsion/call_controller/input.rb +173 -0
  22. data/lib/adhearsion/call_controller/menu.rb +124 -0
  23. data/lib/adhearsion/call_controller/output.rb +267 -0
  24. data/lib/adhearsion/call_controller/record.rb +42 -0
  25. data/lib/adhearsion/call_controller/utility.rb +60 -0
  26. data/lib/adhearsion/calls.rb +81 -0
  27. data/lib/adhearsion/cli.rb +1 -3
  28. data/lib/adhearsion/cli_commands.rb +142 -0
  29. data/lib/adhearsion/configuration.rb +149 -0
  30. data/lib/adhearsion/console.rb +19 -8
  31. data/lib/adhearsion/dialplan_controller.rb +9 -0
  32. data/lib/adhearsion/events.rb +84 -0
  33. data/lib/adhearsion/foundation/all.rb +0 -7
  34. data/lib/adhearsion/foundation/custom_daemonizer.rb +4 -6
  35. data/lib/adhearsion/foundation/exception_handler.rb +9 -0
  36. data/lib/adhearsion/foundation/object.rb +26 -8
  37. data/lib/adhearsion/foundation/synchronized_hash.rb +3 -6
  38. data/lib/adhearsion/foundation/thread_safety.rb +17 -1
  39. data/lib/adhearsion/generators/app/app_generator.rb +4 -13
  40. data/lib/adhearsion/generators/app/templates/Gemfile +10 -5
  41. data/lib/adhearsion/generators/app/templates/Procfile +1 -0
  42. data/lib/adhearsion/generators/app/templates/README.md +28 -0
  43. data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +41 -0
  44. data/lib/adhearsion/generators/app/templates/{components/simon_game → lib}/simon_game.rb +6 -18
  45. data/lib/adhearsion/generators/app/templates/script/ahn +2 -2
  46. data/lib/adhearsion/initializer.rb +151 -293
  47. data/lib/adhearsion/initializer/logging.rb +33 -0
  48. data/lib/adhearsion/logging.rb +65 -69
  49. data/lib/adhearsion/menu_dsl.rb +15 -0
  50. data/lib/adhearsion/menu_dsl/calculated_match.rb +39 -0
  51. data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +41 -0
  52. data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +18 -0
  53. data/lib/adhearsion/menu_dsl/match_calculator.rb +36 -0
  54. data/lib/adhearsion/{voip/menu_state_machine/menu_class.rb → menu_dsl/menu.rb} +38 -40
  55. data/lib/adhearsion/menu_dsl/menu_builder.rb +69 -0
  56. data/lib/adhearsion/menu_dsl/range_match_calculator.rb +55 -0
  57. data/lib/adhearsion/menu_dsl/string_match_calculator.rb +21 -0
  58. data/lib/adhearsion/outbound_call.rb +64 -0
  59. data/lib/adhearsion/plugin.rb +319 -0
  60. data/lib/adhearsion/plugin/collection.rb +19 -0
  61. data/lib/adhearsion/plugin/initializer.rb +37 -0
  62. data/lib/adhearsion/plugin/methods_container.rb +6 -0
  63. data/lib/adhearsion/process.rb +94 -0
  64. data/lib/adhearsion/punchblock_plugin.rb +29 -0
  65. data/lib/adhearsion/punchblock_plugin/initializer.rb +137 -0
  66. data/lib/adhearsion/router.rb +30 -0
  67. data/lib/adhearsion/router/route.rb +42 -0
  68. data/lib/adhearsion/script_ahn_loader.rb +2 -2
  69. data/lib/adhearsion/tasks.rb +14 -9
  70. data/lib/adhearsion/tasks/configuration.rb +26 -0
  71. data/lib/adhearsion/tasks/plugins.rb +17 -0
  72. data/lib/adhearsion/version.rb +8 -14
  73. data/spec/adhearsion/call_controller/dial_spec.rb +138 -0
  74. data/spec/adhearsion/call_controller/input_spec.rb +278 -0
  75. data/spec/adhearsion/call_controller/menu_spec.rb +120 -0
  76. data/spec/adhearsion/call_controller/output_spec.rb +466 -0
  77. data/spec/adhearsion/call_controller/record_spec.rb +125 -0
  78. data/spec/adhearsion/call_controller_spec.rb +395 -0
  79. data/spec/adhearsion/call_spec.rb +438 -0
  80. data/spec/adhearsion/calls_spec.rb +47 -0
  81. data/spec/adhearsion/configuration_spec.rb +308 -0
  82. data/spec/adhearsion/dialplan_controller_spec.rb +26 -0
  83. data/spec/adhearsion/events_spec.rb +112 -0
  84. data/spec/adhearsion/initializer/logging_spec.rb +58 -0
  85. data/spec/adhearsion/initializer_spec.rb +209 -122
  86. data/spec/adhearsion/logging_spec.rb +58 -47
  87. data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +56 -0
  88. data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +57 -0
  89. data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +33 -0
  90. data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +13 -0
  91. data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +118 -0
  92. data/spec/adhearsion/menu_dsl/menu_spec.rb +210 -0
  93. data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +28 -0
  94. data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +36 -0
  95. data/spec/adhearsion/menu_dsl_spec.rb +12 -0
  96. data/spec/adhearsion/outbound_call_spec.rb +174 -0
  97. data/spec/adhearsion/plugin_spec.rb +489 -0
  98. data/spec/adhearsion/process_spec.rb +34 -0
  99. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +294 -0
  100. data/spec/adhearsion/router/route_spec.rb +99 -0
  101. data/spec/adhearsion/router_spec.rb +106 -0
  102. data/spec/adhearsion_spec.rb +46 -0
  103. data/spec/spec_helper.rb +14 -14
  104. data/spec/support/call_controller_test_helpers.rb +48 -0
  105. data/spec/support/initializer_stubs.rb +8 -13
  106. data/spec/support/punchblock_mocks.rb +6 -0
  107. metadata +255 -253
  108. data/CHANGELOG +0 -174
  109. data/bin/ahnctl +0 -68
  110. data/bin/jahn +0 -43
  111. data/examples/asterisk_manager_interface/standalone.rb +0 -51
  112. data/lib/adhearsion/commands.rb +0 -302
  113. data/lib/adhearsion/component_manager.rb +0 -278
  114. data/lib/adhearsion/component_manager/component_tester.rb +0 -54
  115. data/lib/adhearsion/component_manager/spec_framework.rb +0 -18
  116. data/lib/adhearsion/events_support.rb +0 -65
  117. data/lib/adhearsion/foundation/blank_slate.rb +0 -3
  118. data/lib/adhearsion/foundation/event_socket.rb +0 -205
  119. data/lib/adhearsion/foundation/future_resource.rb +0 -36
  120. data/lib/adhearsion/foundation/metaprogramming.rb +0 -17
  121. data/lib/adhearsion/foundation/numeric.rb +0 -13
  122. data/lib/adhearsion/foundation/pseudo_guid.rb +0 -10
  123. data/lib/adhearsion/foundation/relationship_properties.rb +0 -42
  124. data/lib/adhearsion/foundation/string.rb +0 -26
  125. data/lib/adhearsion/generators/app/templates/.ahnrc +0 -34
  126. data/lib/adhearsion/generators/app/templates/README +0 -8
  127. data/lib/adhearsion/generators/app/templates/components/ami_remote/ami_remote.rb +0 -15
  128. data/lib/adhearsion/generators/app/templates/components/disabled/HOW_TO_ENABLE +0 -7
  129. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/README.markdown +0 -47
  130. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.rb +0 -34
  131. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.yml +0 -12
  132. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/README.markdown +0 -3
  133. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +0 -11
  134. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
  135. data/lib/adhearsion/generators/app/templates/config/startup.rb +0 -81
  136. data/lib/adhearsion/generators/app/templates/dialplan.rb +0 -3
  137. data/lib/adhearsion/generators/app/templates/events.rb +0 -33
  138. data/lib/adhearsion/host_definitions.rb +0 -67
  139. data/lib/adhearsion/initializer/asterisk.rb +0 -86
  140. data/lib/adhearsion/initializer/configuration.rb +0 -324
  141. data/lib/adhearsion/initializer/database.rb +0 -60
  142. data/lib/adhearsion/initializer/drb.rb +0 -31
  143. data/lib/adhearsion/initializer/freeswitch.rb +0 -22
  144. data/lib/adhearsion/initializer/ldap.rb +0 -57
  145. data/lib/adhearsion/initializer/rails.rb +0 -41
  146. data/lib/adhearsion/initializer/xmpp.rb +0 -42
  147. data/lib/adhearsion/tasks/components.rb +0 -32
  148. data/lib/adhearsion/tasks/database.rb +0 -5
  149. data/lib/adhearsion/tasks/deprecations.rb +0 -59
  150. data/lib/adhearsion/tasks/generating.rb +0 -20
  151. data/lib/adhearsion/tasks/lint.rb +0 -4
  152. data/lib/adhearsion/voip/asterisk.rb +0 -4
  153. data/lib/adhearsion/voip/asterisk/agi_server.rb +0 -121
  154. data/lib/adhearsion/voip/asterisk/commands.rb +0 -1966
  155. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +0 -140
  156. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +0 -102
  157. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +0 -250
  158. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +0 -240
  159. data/lib/adhearsion/voip/asterisk/config_manager.rb +0 -64
  160. data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -697
  161. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +0 -1681
  162. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +0 -341
  163. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +0 -78
  164. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +0 -87
  165. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +0 -80
  166. data/lib/adhearsion/voip/call.rb +0 -521
  167. data/lib/adhearsion/voip/call_routing.rb +0 -64
  168. data/lib/adhearsion/voip/commands.rb +0 -17
  169. data/lib/adhearsion/voip/constants.rb +0 -39
  170. data/lib/adhearsion/voip/conveniences.rb +0 -18
  171. data/lib/adhearsion/voip/dial_plan.rb +0 -252
  172. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +0 -151
  173. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +0 -37
  174. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +0 -27
  175. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +0 -124
  176. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +0 -69
  177. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +0 -16
  178. data/lib/adhearsion/voip/dsl/numerical_string.rb +0 -128
  179. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +0 -48
  180. data/lib/adhearsion/voip/freeswitch/event_handler.rb +0 -58
  181. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +0 -129
  182. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +0 -38
  183. data/lib/adhearsion/voip/freeswitch/oes_server.rb +0 -195
  184. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +0 -80
  185. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +0 -123
  186. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +0 -57
  187. data/lib/adhearsion/xmpp/connection.rb +0 -61
  188. data/lib/theatre.rb +0 -147
  189. data/lib/theatre/README.markdown +0 -64
  190. data/lib/theatre/callback_definition_loader.rb +0 -86
  191. data/lib/theatre/guid.rb +0 -23
  192. data/lib/theatre/invocation.rb +0 -131
  193. data/lib/theatre/namespace_manager.rb +0 -153
  194. data/lib/theatre/version.rb +0 -2
  195. data/spec/adhearsion/cli_spec.rb +0 -306
  196. data/spec/adhearsion/component_manager_spec.rb +0 -292
  197. data/spec/adhearsion/constants_spec.rb +0 -8
  198. data/spec/adhearsion/drb_spec.rb +0 -65
  199. data/spec/adhearsion/fixtures/dialplan.rb +0 -3
  200. data/spec/adhearsion/foundation/event_socket_spec.rb +0 -168
  201. data/spec/adhearsion/host_definitions_spec.rb +0 -79
  202. data/spec/adhearsion/initializer/configuration_spec.rb +0 -291
  203. data/spec/adhearsion/initializer/loading_spec.rb +0 -154
  204. data/spec/adhearsion/initializer/paths_spec.rb +0 -74
  205. data/spec/adhearsion/relationship_properties_spec.rb +0 -54
  206. data/spec/adhearsion/voip/asterisk/agi_server_spec.rb +0 -473
  207. data/spec/adhearsion/voip/asterisk/ami/ami_spec.rb +0 -550
  208. data/spec/adhearsion/voip/asterisk/ami/lexer/ami_fixtures.yml +0 -30
  209. data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story +0 -291
  210. data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story.rb +0 -241
  211. data/spec/adhearsion/voip/asterisk/ami/lexer/story_helper.rb +0 -124
  212. data/spec/adhearsion/voip/asterisk/commands_spec.rb +0 -3241
  213. data/spec/adhearsion/voip/asterisk/config_file_generators/agents_spec.rb +0 -251
  214. data/spec/adhearsion/voip/asterisk/config_file_generators/queues_spec.rb +0 -323
  215. data/spec/adhearsion/voip/asterisk/config_file_generators/voicemail_spec.rb +0 -306
  216. data/spec/adhearsion/voip/asterisk/config_manager_spec.rb +0 -127
  217. data/spec/adhearsion/voip/asterisk/menu_command/calculated_match_spec.rb +0 -109
  218. data/spec/adhearsion/voip/asterisk/menu_command/matchers_spec.rb +0 -97
  219. data/spec/adhearsion/voip/call_routing_spec.rb +0 -125
  220. data/spec/adhearsion/voip/dialplan_manager_spec.rb +0 -468
  221. data/spec/adhearsion/voip/dsl/dialing_dsl_spec.rb +0 -270
  222. data/spec/adhearsion/voip/dsl/dispatcher_spec.rb +0 -82
  223. data/spec/adhearsion/voip/dsl/dispatcher_spec_helper.rb +0 -45
  224. data/spec/adhearsion/voip/dsl/parser_spec.rb +0 -69
  225. data/spec/adhearsion/voip/freeswitch/basic_connection_manager_spec.rb +0 -39
  226. data/spec/adhearsion/voip/freeswitch/inbound_connection_manager_spec.rb +0 -39
  227. data/spec/adhearsion/voip/freeswitch/oes_server_spec.rb +0 -9
  228. data/spec/adhearsion/voip/numerical_string_spec.rb +0 -61
  229. data/spec/adhearsion/voip/phone_number_spec.rb +0 -45
  230. data/spec/support/the_following_code.rb +0 -3
  231. data/spec/theatre/dsl_examples/simple_before_call.rb +0 -7
  232. data/spec/theatre/dsl_spec.rb +0 -69
  233. data/spec/theatre/invocation_spec.rb +0 -182
  234. data/spec/theatre/namespace_spec.rb +0 -125
  235. data/spec/theatre/spec_helper_spec.rb +0 -28
  236. data/spec/theatre/theatre_class_spec.rb +0 -148
@@ -1,97 +0,0 @@
1
- require 'spec_helper'
2
- require 'adhearsion/voip/menu_state_machine/menu_builder'
3
- require 'adhearsion/voip/menu_state_machine/matchers'
4
-
5
- describe "MatchCalculator" do
6
- it "the build_with_pattern() method should return an appropriate subclass instance based on the pattern's class" do
7
- Adhearsion::VoIP::MatchCalculator.build_with_pattern(1..2, :main).should be_an_instance_of Adhearsion::VoIP::RangeMatchCalculator
8
- end
9
-
10
- end
11
-
12
- describe "The RangeMatchCalculator" do
13
-
14
- it "matching with a Range should handle the case of two potential matches in the range" do
15
- digits_that_begin_with_eleven = [110..119, 1100..1111].map { |x| Array(x) }.flatten
16
-
17
- calculator = Adhearsion::VoIP::RangeMatchCalculator.new 11..1111, :match_payload_doesnt_matter
18
- match = calculator.match 11
19
- match.exact_matches.should == [11]
20
- match.potential_matches.should == digits_that_begin_with_eleven
21
- end
22
-
23
- it 'return values of #match should be an instance of CalculatedMatch' do
24
- calculator = Adhearsion::VoIP::RangeMatchCalculator.new 1..9, :match_payload_doesnt_matter
25
- calculator.match(0).should be_an_instance_of Adhearsion::VoIP::CalculatedMatch
26
- calculator.match(1000).should be_an_instance_of Adhearsion::VoIP::CalculatedMatch
27
- end
28
-
29
- end
30
-
31
- describe "FixnumMatchCalculator" do
32
- attr_reader :match_payload
33
- before(:each) do
34
- @match_payload = :main
35
- end
36
-
37
- it "a potential match scenario" do
38
- calculator = Adhearsion::VoIP::FixnumMatchCalculator.new(444, match_payload)
39
- match = calculator.match 4
40
- match.potential_match?.should be true
41
- match.exact_match?.should_not be true
42
- match.potential_matches.should == [444]
43
- end
44
-
45
- it 'a multi-digit exact match scenario' do
46
- calculator = Adhearsion::VoIP::FixnumMatchCalculator.new(5555, match_payload)
47
- calculator.match(5555).exact_match?.should be true
48
- end
49
-
50
- it 'a single-digit exact match scenario' do
51
- calculator = Adhearsion::VoIP::FixnumMatchCalculator.new(1, match_payload)
52
- calculator.match(1).exact_match?.should be true
53
- end
54
-
55
- it 'the context name given to the calculator should be passed on to the CalculatedMatch' do
56
- match_payload = :icanhascheezburger
57
- calculator = Adhearsion::VoIP::FixnumMatchCalculator.new(1337, match_payload)
58
- calculator.match(1337).match_payload.should be match_payload
59
- end
60
-
61
- end
62
-
63
- describe "StringMatchCalculator" do
64
-
65
- attr_reader :match_payload
66
- before(:each) do
67
- @match_payload = :doesnt_matter
68
- end
69
-
70
- it "numerical digits mixed with special digits" do
71
-
72
- %w[5*11#3 5*** ###].each do |str|
73
- calculator = Adhearsion::VoIP::StringMatchCalculator.new(str, match_payload)
74
-
75
- match_case = calculator.match str[0,2]
76
- match_case.exact_match?.should_not be true
77
- match_case.potential_match?.should be true
78
- match_case.potential_matches.should == [str]
79
-
80
- match_case = calculator.match str
81
- match_case.exact_match?.should be true
82
- match_case.potential_match?.should_not be true
83
- match_case.exact_matches.should == [str]
84
- end
85
- end
86
-
87
- it "matching the special DTMF characters such as * and #" do
88
- %w[* #].each do |special_digit|
89
- calculator = Adhearsion::VoIP::StringMatchCalculator.new(special_digit, match_payload)
90
- match_case = calculator.match special_digit
91
- match_case.potential_match?.should_not be true
92
- match_case.exact_match?.should be true
93
- match_case.exact_matches.first.should == special_digit
94
- end
95
- end
96
-
97
- end
@@ -1,125 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CallRoutingTestHelper
4
- private
5
- def route(*args, &block)
6
- Adhearsion::VoIP::CallRouting::Rule.new(*args, &block)
7
- end
8
-
9
- def provider_named(name)
10
- Adhearsion::VoIP::DSL::DialingDSL::ProviderDefinition.new(name)
11
- end
12
-
13
- def define_rules(&block)
14
- Adhearsion::VoIP::CallRouting::Router.define(&block)
15
- end
16
-
17
- def calculate_route_for(end_point)
18
- Adhearsion::VoIP::CallRouting::Router.calculate_route_for(end_point)
19
- end
20
-
21
- def rules
22
- Adhearsion::VoIP::CallRouting::Router.rules
23
- end
24
- end
25
-
26
- describe "Call routing rule generation" do
27
- include CallRoutingTestHelper
28
-
29
- attr_reader :provider_one, :provider_two, :patterns
30
-
31
- before(:each) do
32
- @provider_one = provider_named(:one)
33
- @provider_two = provider_named(:two)
34
- @patterns = [/pattern/, /does not/, /matter/]
35
- end
36
-
37
- it "specifying a single pattern routed to a single provider properly stores that pattern and its provider in the generated route rule" do
38
- pattern = %r(does not matter)
39
- rule = route(pattern, :to => provider_one)
40
- rule.patterns.should == [pattern]
41
- rule.providers.should == [provider_one]
42
- end
43
-
44
- it "specifying multiple patterns routed to a single provider stores all of them in the generated route rule" do
45
- first, second, third = patterns
46
- rule = route(first, second, third, :to => provider_one)
47
- rule.patterns.should == [*patterns]
48
- rule.providers.should == [provider_one]
49
- end
50
-
51
- it "specifying multiple patterns routed to multiple providers stores all of them in the generated route rule, listing providers in the ordered specified" do
52
- first, second, third = patterns
53
- rule = route(first, second, third, :to => [provider_one, provider_two])
54
- rule.patterns.should == [*patterns]
55
- rule.providers.should == [provider_one, provider_two]
56
- end
57
- end
58
-
59
- describe "Route calculation" do
60
- include CallRoutingTestHelper
61
- attr_reader :provider_one, :provider_two
62
-
63
- before(:each) do
64
- rules.clear
65
- @provider_one = provider_named(:one)
66
- @provider_two = provider_named(:two)
67
- end
68
-
69
- it "Defining a rule adds it to the router rules" do
70
- provider = provider_one
71
- pattern = /123/
72
- define_rules do
73
- route pattern, :to => provider
74
- end
75
- rules.size.should be 1
76
- rule = rules.first
77
- rule.providers.should == [provider]
78
- rule.patterns.should == [pattern]
79
- end
80
-
81
- it "Definiting multiple rules adds them to the router rules" do
82
- provider_for_rule_1 = provider_one
83
- provider_for_rule_2 = provider_two
84
- pattern_for_rule_1 = /123/
85
- pattern_for_rule_2 = /987/
86
-
87
- define_rules do
88
- route pattern_for_rule_1, :to => provider_for_rule_1
89
- route pattern_for_rule_2, :to => provider_for_rule_2
90
- end
91
-
92
- rules.size.should be 2
93
-
94
- rule_1 = rules.first
95
- rule_1.providers.should == [provider_for_rule_1]
96
- rule_1.patterns.should == [pattern_for_rule_1]
97
-
98
- rule_2 = rules.last
99
- rule_2.providers.should == [provider_for_rule_2]
100
- rule_2.patterns.should == [pattern_for_rule_2]
101
- end
102
-
103
- it "Provider is found in the simplest case of having only one pattern and one provider" do
104
- target_provider = provider_one
105
- define_rules do
106
- route /123/, :to => target_provider
107
- end
108
- calculate_route_for(1234).should == [target_provider]
109
- end
110
-
111
- it "Provider is found when the specified pattern matches a rule that is not the first rule" do
112
- provider_for_rule_1 = provider_one
113
- provider_for_rule_2 = provider_two
114
- pattern_for_rule_1 = /123/
115
- pattern_for_rule_2 = /987/
116
-
117
- define_rules do
118
- route pattern_for_rule_1, :to => provider_for_rule_1
119
- route pattern_for_rule_2, :to => provider_for_rule_2
120
- end
121
-
122
- target_provider = provider_for_rule_2
123
- calculate_route_for(9876).should == [target_provider]
124
- end
125
- end
@@ -1,468 +0,0 @@
1
- require 'spec_helper'
2
- require 'adhearsion/voip/dsl/dialplan/parser'
3
-
4
- module DialplanTestingHelper
5
-
6
- def load(dial_plan_as_string)
7
- Adhearsion::DialPlan::Loader.load(dial_plan_as_string)
8
- end
9
-
10
- def mock_dialplan_with(string)
11
- string_io = StringIO.new(string)
12
- def string_io.path
13
- "dialplan.rb"
14
- end
15
- flexstub(Adhearsion::AHN_CONFIG).should_receive(:files_from_setting).with("paths", "dialplan").and_return ["dialplan.rb"]
16
- flexstub(File).should_receive(:new).with("dialplan.rb").and_return string_io
17
- flexstub(File).should_receive(:read).with('dialplan.rb').and_return string
18
- end
19
-
20
- def new_manager_with_entry_points_loaded_from_dialplan_contexts
21
- Adhearsion::DialPlan::Manager.new.tap do |manager|
22
- manager.dial_plan.entry_points = manager.dial_plan.loader.load_dialplans.contexts
23
- end
24
- end
25
-
26
- def executing_dialplan(options)
27
- call = options.delete(:call)
28
- context_name = options.keys.first
29
- dialplan = options[context_name]
30
- call ||= new_call_for_context context_name
31
-
32
- mock_dialplan_with dialplan
33
-
34
- lambda do
35
- Adhearsion::DialPlan::Manager.new.handle call
36
- end
37
- end
38
-
39
- def new_call_for_context(context)
40
- Adhearsion::Call.new(StringIO.new, :context => context)
41
- end
42
- end
43
-
44
- describe "Dialplan::Manager handling" do
45
-
46
- include DialplanTestingHelper
47
-
48
- attr_accessor :manager, :call, :context_name, :mock_context
49
-
50
- before :each do
51
- @context_name = :some_context_name
52
- @mock_context = flexmock('a context')
53
-
54
- mock_dial_plan_lookup_for_context_name
55
-
56
- flexmock(Adhearsion::DialPlan::Loader).should_receive(:load_dialplans).and_return {
57
- flexmock("loaded contexts", :contexts => nil)
58
- }
59
- @manager = Adhearsion::DialPlan::Manager.new
60
- @call = new_call_for_context context_name
61
-
62
- # Sanity check context name being set
63
- call.context.should be context_name
64
- end
65
-
66
- it "Given a Call, the manager finds the call's desired entry point based on the originating context" do
67
- manager.entry_point_for(call).should be mock_context
68
- end
69
-
70
- it "The manager handles a call by executing the proper context" do
71
- flexmock(Adhearsion::DialPlan::ExecutionEnvironment).new_instances.should_receive(:run).once
72
- manager.handle(call)
73
- end
74
-
75
- it "should raise a NoContextError exception if the targeted context is not found" do
76
- the_following_code {
77
- flexmock(manager).should_receive(:entry_point_for).and_return nil
78
- manager.handle call
79
- }.should raise_error(Adhearsion::DialPlan::Manager::NoContextError)
80
- end
81
-
82
- it 'should send :answer to the execution environment if Adhearsion::AHN_CONFIG.automatically_answer_incoming_calls is set' do
83
- flexmock(Adhearsion::DialPlan::ExecutionEnvironment).new_instances.should_receive(:answer).once.and_throw :answered_call!
84
- Adhearsion::Configuration.configure do |config|
85
- config.automatically_answer_incoming_calls = true
86
- end
87
- the_following_code {
88
- manager.handle call
89
- }.should throw_symbol :answered_call!
90
- end
91
-
92
- it 'should NOT send :answer to the execution environment if Adhearsion::AHN_CONFIG.automatically_answer_incoming_calls is NOT set' do
93
- Adhearsion::Configuration.configure do |config|
94
- config.automatically_answer_incoming_calls = false
95
- end
96
-
97
- entry_point = Adhearsion::DialPlan::DialplanContextProc.new(:does_not_matter) { "Do nothing" }
98
- flexmock(manager).should_receive(:entry_point_for).once.with(call).and_return(entry_point)
99
-
100
- execution_env = Adhearsion::DialPlan::ExecutionEnvironment.create(call, nil)
101
- flexmock(execution_env).should_receive(:entry_point).and_return entry_point
102
- flexmock(execution_env).should_receive(:answer).never
103
-
104
- flexmock(Adhearsion::DialPlan::ExecutionEnvironment).should_receive(:new).once.and_return execution_env
105
-
106
- Adhearsion::Configuration.configure
107
- manager.handle call
108
- end
109
-
110
- private
111
-
112
- def mock_dial_plan_lookup_for_context_name
113
- flexstub(Adhearsion::DialPlan).new_instances.should_receive(:lookup).with(context_name).and_return(mock_context)
114
- end
115
-
116
- end
117
-
118
- describe "DialPlan::Manager's handling a failed call" do
119
-
120
- include DialplanTestingHelper
121
-
122
- it 'should check if the call has failed and then instruct it to extract the reason from the environment' do
123
- flexmock(Adhearsion::DialPlan::ExecutionEnvironment).new_instances.should_receive(:variable).with("REASON").once.and_return '3'
124
- call = Adhearsion::Call.new(nil, {'extension' => "failed"})
125
- call.failed_call?.should be true
126
- flexmock(Adhearsion::DialPlan).should_receive(:new).once.and_return flexmock("bogus DialPlan which should never be used")
127
- begin
128
- Adhearsion::DialPlan::Manager.handle(call)
129
- rescue Adhearsion::FailedExtensionCallException => error
130
- error.call.failed_reason.should == Adhearsion::Call::ASTERISK_FRAME_STATES[3]
131
- end
132
- end
133
- end
134
-
135
- describe "Call tagging" do
136
-
137
- include DialplanTestingHelper
138
-
139
- after :all do
140
- Adhearsion.active_calls.clear!
141
- end
142
-
143
- it 'tagging a call with a single Symbol' do
144
- the_following_code {
145
- call = new_call_for_context "roflcopter"
146
- call.tag :moderator
147
- }.should_not raise_error
148
- end
149
-
150
- it 'tagging a call with multiple Symbols' do
151
- the_following_code {
152
- call = new_call_for_context "roflcopter"
153
- call.tag :moderator
154
- call.tag :female
155
- }.should_not raise_error
156
- end
157
-
158
- it 'Call#tagged_with? with one tag' do
159
- call = new_call_for_context "roflcopter"
160
- call.tag :guest
161
- call.tagged_with?(:guest).should be true
162
- call.tagged_with?(:authorized).should be false
163
- end
164
-
165
- it "Call#remove_tag" do
166
- call = new_call_for_context "roflcopter"
167
- call.tag :moderator
168
- call.tag :female
169
- call.remove_tag :female
170
- call.tag :male
171
- call.tags.should == [:moderator, :male]
172
- end
173
-
174
- it 'Call#tagged_with? with many tags' do
175
- call = new_call_for_context "roflcopter"
176
- call.tag :customer
177
- call.tag :authorized
178
- call.tagged_with?(:customer).should be true
179
- call.tagged_with?(:authorized).should be true
180
- end
181
-
182
- it 'tagging a call with a non-Symbol, non-String object' do
183
- bad_objects = [123, Object.new, 888.88, nil, true, false, StringIO.new]
184
- bad_objects.each do |bad_object|
185
- the_following_code {
186
- new_call_for_context("roflcopter").tag bad_object
187
- }.should raise_error ArgumentError
188
- end
189
- end
190
-
191
- it "finding calls by a tag" do
192
- Adhearsion.active_calls.clear!
193
-
194
- calls = Array.new(5) { new_call_for_context "roflcopter" }
195
- calls.each { |call| Adhearsion.active_calls << call }
196
-
197
- tagged_call = calls.last
198
- tagged_call.tag :moderator
199
-
200
- Adhearsion.active_calls.with_tag(:moderator).should == [tagged_call]
201
- end
202
-
203
- end
204
-
205
- describe "DialPlan::Manager's handling a hungup call" do
206
-
207
- include DialplanTestingHelper
208
-
209
- it 'should check if the call was a hangup meta-AGI call and then raise a HangupExtensionCallException' do
210
- call = Adhearsion::Call.new(nil, {'extension' => "h"})
211
- call.hungup_call?.should be true
212
- flexmock(Adhearsion::DialPlan).should_receive(:new).once.and_return flexmock("bogus DialPlan which should never be used")
213
- the_following_code {
214
- Adhearsion::DialPlan::Manager.handle(call)
215
- }.should raise_error Adhearsion::HungupExtensionCallException
216
- end
217
-
218
- end
219
-
220
- describe "DialPlan" do
221
-
222
- attr_accessor :loader, :loader_instance, :dial_plan
223
-
224
- before do
225
- @loader = Adhearsion::DialPlan::Loader
226
- @loader_instance = @loader.new
227
- flexmock(Adhearsion::DialPlan::Loader).should_receive(:load_dialplans).once.and_return(@loader_instance)
228
- @dial_plan = Adhearsion::DialPlan.new(@loader)
229
- end
230
-
231
- it "When a dial plan is instantiated, the dialplans are loaded and stored for lookup" do
232
- dial_plan.instance_variable_get("@entry_points").should_not be nil
233
- end
234
-
235
- it "Can look up an entry point from a dial plan" do
236
- context_name = 'this_context_is_better_than_your_context'
237
- loader_instance.contexts[context_name] = lambda { puts "o hai" }
238
- dial_plan.lookup(context_name).should_not be nil
239
- end
240
- end
241
-
242
- describe "DialPlan loader" do
243
-
244
- include DialplanTestingHelper
245
-
246
- it "loading a single context" do
247
- loader = load(<<-DIAL_PLAN)
248
- one {
249
- raise 'this block should not be evaluated'
250
- }
251
- DIAL_PLAN
252
-
253
- loader.contexts.keys.size.should be 1
254
- loader.contexts.keys.first.should be :one
255
- end
256
-
257
- it "loading multiple contexts loads all contexts" do
258
- loader = load(<<-DIAL_PLAN)
259
- one {
260
- raise 'this block should not be evaluated'
261
- }
262
-
263
- two {
264
- raise 'this other block should not be evaluated either'
265
- }
266
- DIAL_PLAN
267
-
268
- loader.contexts.keys.size.should be 2
269
- loader.contexts.keys.map(&:to_s).sort.should == %w(one two)
270
- end
271
-
272
- it 'loading a dialplan with a syntax error' do
273
- the_following_code {
274
- load "foo { &@(*!&(*@*!@^!^%@%^! }"
275
- }.should raise_error SyntaxError
276
- end
277
-
278
- it "loading a dial plan from a file" do
279
- loader = nil
280
- Adhearsion::AHN_CONFIG.ahnrc = {"paths" => {"dialplan" => "dialplan.rb"}}
281
- the_following_code {
282
- AHN_ROOT.using_base_path(File.expand_path(File.dirname(__FILE__) + '/../fixtures')) do
283
- loader = Adhearsion::DialPlan::Loader.load_dialplans
284
- end
285
- }.should_not raise_error
286
-
287
- loader.contexts.keys.size.should be 1
288
- loader.contexts.keys.first.should be :sample_context
289
- end
290
-
291
- end
292
-
293
- describe "The inbox-related dialplan methods" do
294
-
295
- include DialplanTestingHelper
296
-
297
- it "with_next_message should execute its block with the message from the inbox" do
298
- mock_call = new_call_for_context :entrance
299
- [:one, :two, :three].each { |message| mock_call.inbox << message }
300
-
301
- dialplan = %{ entrance { with_next_message { |message| throw message } } }
302
- executing_dialplan(:entrance => dialplan, :call => mock_call).should throw_symbol :one
303
- end
304
-
305
- it "messages_waiting? should return false if the inbox is empty" do
306
- mock_call = new_call_for_context :entrance
307
- dialplan = %{ entrance { throw messages_waiting? ? :yes : :no } }
308
- executing_dialplan(:entrance => dialplan, :call => mock_call).should throw_symbol :no
309
- end
310
-
311
- it "messages_waiting? should return false if the inbox is not empty" do
312
- mock_call = new_call_for_context :entrance
313
- mock_call.inbox << Object.new
314
- dialplan = %{ entrance { throw messages_waiting? ? :yes : :no } }
315
- executing_dialplan(:entrance => dialplan, :call => mock_call).should throw_symbol :yes
316
- end
317
-
318
- end
319
-
320
-
321
- describe "ExecutionEnvironment" do
322
-
323
- attr_accessor :call, :entry_point
324
-
325
- include DialplanTestingHelper
326
-
327
- before do
328
- variables = { :context => "zomgzlols", :caller_id => "Ponce de Leon" }
329
- @call = Adhearsion::Call.new(nil, variables)
330
- @entry_point = lambda {}
331
- end
332
-
333
- it "On initialization, ExecutionEnvironments extend themselves with behavior specific to the voip platform which originated the call" do
334
- Adhearsion::DialPlan::ExecutionEnvironment.included_modules.should_not include(Adhearsion::VoIP::Asterisk::Commands)
335
- execution_environent = Adhearsion::DialPlan::ExecutionEnvironment.create(call, entry_point)
336
- execution_environent.metaclass.included_modules.should include(Adhearsion::VoIP::Asterisk::Commands)
337
- end
338
-
339
- it "An executed context should raise a NameError error when a missing constant is referenced" do
340
- the_following_code do
341
- flexmock(Adhearsion::AHN_CONFIG).should_receive(:automatically_answer_incoming_calls).and_return false
342
- context = :context_with_missing_constant
343
- call = new_call_for_context context
344
- mock_dialplan_with "#{context} { ThisConstantDoesntExist }"
345
- Adhearsion::DialPlan::Manager.new.handle call
346
- end.should raise_error NameError
347
-
348
- end
349
-
350
- it "should define variables accessors within itself" do
351
- environment = Adhearsion::DialPlan::ExecutionEnvironment.create(@call, entry_point)
352
- call.variables.empty?.should be false
353
- call.variables.each do |key, value|
354
- environment.send(key).should be value
355
- end
356
- end
357
-
358
- it "should define accessors for other contexts in the dialplan" do
359
- call = new_call_for_context :am_not_for_kokoa!
360
- bogus_dialplan = <<-DIALPLAN
361
- am_not_for_kokoa! {}
362
- icanhascheezburger? {}
363
- these_context_names_do_not_really_matter {}
364
- DIALPLAN
365
-
366
- mock_dialplan_with bogus_dialplan
367
-
368
- manager = Adhearsion::DialPlan::Manager.new
369
- manager.dial_plan.entry_points.empty?.should_not be true
370
-
371
- manager.handle call
372
-
373
- %w(these_context_names_do_not_really_matter icanhascheezburger? am_not_for_kokoa!).each do |context_name|
374
- manager.context.respond_to?(context_name).should be true
375
- end
376
-
377
- end
378
-
379
- end
380
-
381
- describe "Dialplan control statements" do
382
-
383
- include DialplanTestingHelper
384
-
385
- it "Manager should catch ControlPassingExceptions" do
386
- flexmock(Adhearsion::AHN_CONFIG).should_receive(:automatically_answer_incoming_calls).and_return false
387
- dialplan = %{
388
- foo { raise Adhearsion::VoIP::DSL::Dialplan::ControlPassingException.new(bar) }
389
- bar {}
390
- }
391
- executing_dialplan(:foo => dialplan).should_not raise_error
392
- end
393
-
394
- it "All dialplan contexts should be available at context execution time" do
395
- dialplan = %{
396
- context_defined_first {
397
- throw :i_see_it if context_defined_second
398
- }
399
- context_defined_second {}
400
- }
401
- executing_dialplan(:context_defined_first => dialplan).should throw_symbol :i_see_it
402
- end
403
-
404
- test_dialplan_inclusions = true
405
- if Object.const_defined?("JRUBY_VERSION")
406
- require 'adhearsion/version'
407
- curver = Adhearsion::PkgVersion.new(JRUBY_VERSION)
408
- minver = Adhearsion::PkgVersion.new("1.6.0")
409
- if curver < minver
410
- # JRuby contains a bug that breaks some of the menu functionality
411
- # See: https://adhearsion.lighthouseapp.com/projects/5871/tickets/92-menu-method-under-jruby-does-not-appear-to-work
412
- test_dialplan_inclusions = false
413
- end
414
- end
415
-
416
- if test_dialplan_inclusions
417
- it "Proc#+@ should execute the other context" do
418
- dialplan = %{
419
- eins {
420
- +zwei
421
- throw :eins
422
- }
423
- zwei {
424
- throw :zwei
425
- }
426
- }
427
- executing_dialplan(:eins => dialplan).should throw_symbol :zwei
428
- end
429
-
430
- it "Proc#+@ should not return to its originating context" do
431
- dialplan = %{
432
- andere {}
433
- zuerst {
434
- +andere
435
- throw :after_control_statement
436
- }
437
- }
438
- executing_dialplan(:zuerst => dialplan).should_not raise_error
439
- end
440
- end
441
-
442
-
443
- it "new constants should still be accessible within the dialplan" do
444
- flexmock(Adhearsion::AHN_CONFIG).should_receive(:automatically_answer_incoming_calls).and_return false
445
- ::Jicksta = :Jicksta
446
- dialplan = %{
447
- constant_test {
448
- Jicksta.should == :Jicksta
449
- }
450
- }
451
- executing_dialplan(:constant_test => dialplan).should_not raise_error
452
- end
453
-
454
- end
455
-
456
- describe "VoIP platform operations" do
457
- it "can map a platform name to a module which holds its platform-specific operations" do
458
- Adhearsion::VoIP::Commands.for(:asterisk).should == Adhearsion::VoIP::Asterisk::Commands
459
- end
460
- end
461
-
462
- describe 'DialPlan::Loader' do
463
- it '::build should raise a SyntaxError when the dialplan String contains one' do
464
- the_following_code {
465
- Adhearsion::DialPlan::Loader.load "foo { ((((( *@!^*@&*^!^@ }"
466
- }.should raise_error SyntaxError
467
- end
468
- end