adhearsion 1.2.6 → 2.0.0.alpha1

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 (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,550 +0,0 @@
1
- require 'spec_helper'
2
- require 'adhearsion'
3
- require 'adhearsion/voip/asterisk/manager_interface'
4
-
5
- module ManagerInterfaceTestHelper
6
-
7
- def mocked_queue
8
- # This mock queue receives a ManagerInterfaceAction with <<(). Within the semantics of the OO design, this should be
9
- # immediately picked up by the writer queue. The writer queue calls to_s on each object and passes that string to the
10
- # event socket, blocking if it's an event with causal events.
11
- write_queue_mock = TestableQueueMock.new
12
- flexmock(Queue).should_receive(:new).once.and_return write_queue_mock
13
- write_queue_mock
14
- end
15
-
16
- def ami_packets
17
- OpenStruct.new.tap do |struct|
18
- struct.fresh_socket_connection = "Asterisk Call Manager/1.0\r\nResponse: Success\r\n"+
19
- "Message: Authentication accepted\r\n\r\n"
20
-
21
- struct.reload_event = %{Event: ChannelReload\r\nPrivilege: system,all\r\nChannel: SIP\r\n} +
22
- %{ReloadReason: RELOAD (Channel module reload)\r\nRegistry_Count: 1\r\nPeer_Count: 2\r\nUser_Count: 1\r\n\r\n}
23
-
24
- struct.authentication_failed = %{Asterisk Call Manager/1.0\r\nResponse: Error\r\nMessage: Authentication failed\r\nActionID: %s\r\n\r\n}
25
-
26
- struct.unknown_command_error = "Response: Error\r\nActionID: 2123123\r\nMessage: Invalid/unknown command\r\n\r\n"
27
-
28
- struct.pong = "Response: Pong\r\nActionID: %s\r\n\r\n"
29
- end
30
- end
31
-
32
- def new_manager_with_events
33
- @Manager::ManagerInterface.new :host => @host, :port => @port, :events => true, :auto_reconnect => false
34
- end
35
-
36
- def new_manager_without_events
37
- @Manager::ManagerInterface.new :host => @host, :port => @port, :events => false, :auto_reconnect => false
38
- end
39
-
40
- def new_blank_ami_response
41
- @Manager::ManagerInterfaceResponse.new
42
- end
43
-
44
- def mock_for_next_created_socket
45
- flexmock("TCPSocket").tap do |mock|
46
- flexmock(TCPSocket).should_receive(:new).once.and_return mock
47
- end
48
- end
49
-
50
- end
51
-
52
-
53
- ##
54
- # Had to implement this class to make the Thread-based testing simpler.
55
- #
56
- class TestableQueueMock
57
-
58
- attr_accessor :manager
59
- def initialize
60
- @shifted = []
61
- @unshifted = []
62
- end
63
-
64
- def actions
65
- @shifted + @unshifted
66
- end
67
-
68
- def <<(action)
69
- @unshifted << action
70
- @on_push.call(action) if @on_push
71
- end
72
-
73
- def on_push(&block)
74
- @on_push = block
75
- self
76
- end
77
-
78
- def shift
79
- return :STOP! if actions.empty?
80
- next_action = @unshifted.shift
81
- @shifted << next_action
82
- next_action
83
- end
84
-
85
- def received_action?(action)
86
- actions.include?(action)
87
- end
88
-
89
- end
90
-
91
- describe "ManagerInterface" do
92
-
93
- include ManagerInterfaceTestHelper
94
-
95
- before :each do
96
- @Manager = Adhearsion::VoIP::Asterisk::Manager
97
- @host, @port = "foobar", 9999
98
- end
99
-
100
- it "should receive data and not die" do
101
- flexmock(@Manager::ManagerInterface::ManagerInterfaceAction).new_instances.should_receive(:response).once.and_return new_blank_ami_response
102
-
103
- mocked_queue
104
-
105
- manager = new_manager_without_events
106
-
107
- t = flexmock('Thread')
108
- t.should_receive(:join)
109
- flexmock(Thread).should_receive(:new).twice.and_yield.and_return(t)
110
- mock_em_connection = mock_for_next_created_socket
111
-
112
- mock_em_connection.should_receive(:readpartial).once.and_return ami_packets.fresh_socket_connection
113
- mock_em_connection.should_receive(:readpartial).once.and_raise EOFError
114
-
115
- flexmock(manager).should_receive(:action_message_received).once.with(@Manager::ManagerInterfaceResponse)
116
- manager.connect!
117
- end
118
-
119
- it "should use the defaults specified in DEFAULT_SETTINGS when no overrides are given" do
120
- manager = @Manager::ManagerInterface.new
121
- %w[host port username password events].each do |property|
122
- manager.send(property).should ==@Manager::ManagerInterface::DEFAULT_SETTINGS[property.to_sym]
123
- end
124
- end
125
-
126
- it "should override the DEFAULT_SETTINGS settings with overrides given to the constructor" do
127
- overrides = {
128
- :host => "yayiamahost",
129
- :port => 1337,
130
- :username => "root",
131
- :password => "toor",
132
- :events => false
133
- }
134
- manager = @Manager::ManagerInterface.new overrides
135
- %w[host port username password events].each do |property|
136
- manager.send(property).should ==overrides[property.to_sym]
137
- end
138
- end
139
-
140
- it "should raise an ArgumentError when it's instantiated with an unrecognized named argument" do
141
- the_following_code {
142
- @Manager::ManagerInterface.new :ifeelsopretty => "OH SO PRETTY!"
143
- }.should raise_error ArgumentError
144
- end
145
-
146
- it "a received message that matches an action ID for which we're waiting" do
147
- action_id = "OHAILOLZ"
148
-
149
- manager = new_manager_without_events
150
-
151
- flexmock(@Manager::ManagerInterface::ManagerInterfaceAction).new_instances.should_receive(:action_id).once.and_return action_id
152
- flexmock(manager).should_receive(:login_actions).once.and_return
153
-
154
- mock_em_connection = mock_for_next_created_socket
155
-
156
- manager.connect!
157
-
158
- flexmock(FutureResource).new_instances.should_receive(:resource).once.and_return :THREAD_WAITING_MOCKED_OUT
159
- flexmock(FutureResource).new_instances.should_receive(:resource=).once.with(@Manager::ManagerInterfaceResponse)
160
-
161
- manager.send_action("ping").should be :THREAD_WAITING_MOCKED_OUT
162
-
163
- # Avoid race where message may not yet be in the sent_messages queue
164
- sleep(0.1)
165
- manager.send(:instance_variable_get, :@sent_messages).has_key?(action_id).should be true
166
-
167
- manager.send(:instance_variable_get, :@actions_connection).
168
- send(:instance_variable_get, :@handler).
169
- receive_data("Response: Pong\r\nActionID: #{action_id}\r\n\r\n")
170
-
171
- manager.send(:instance_variable_get, :@sent_messages).has_key?(action_id).should be false
172
- end
173
-
174
- it "a received event is received by Theatre" do
175
- flexmock(Adhearsion::Events).should_receive(:trigger).once.with(%w[asterisk manager_interface], @Manager::ManagerInterfaceEvent)
176
-
177
- manager = new_manager_with_events
178
- flexmock(manager).should_receive(:login_actions).once.and_return
179
- flexmock(manager).should_receive(:login_events).once.and_return
180
-
181
- mock_actions_connection = mock_for_next_created_socket
182
- mock_events_connection = mock_for_next_created_socket
183
-
184
- manager.connect!
185
-
186
- manager.send(:instance_variable_get, :@events_connection).
187
- send(:instance_variable_get, :@handler).
188
- receive_data ami_packets.reload_event
189
- end
190
-
191
- it "an ManagerInterfaceError should be raised when the action's FutureResource is set to an ManagerInterfaceError instance" do
192
-
193
- flexmock(FutureResource).new_instances.should_receive(:resource).once.and_return @Manager::ManagerInterfaceError.new
194
-
195
- manager = new_manager_without_events
196
- actions_connection = mock_for_next_created_socket
197
- flexmock(manager).should_receive(:login_actions).once.and_return
198
-
199
- manager.connect!
200
-
201
- the_following_code {
202
- manager.send_action "Foobar"
203
- }.should raise_error @Manager::ManagerInterfaceError
204
-
205
- end
206
-
207
- it "an AuthenticationFailedException should be raised when the action's FutureResource is set to an ManagerInterfaceError instance" do
208
- flexmock(FutureResource).new_instances.should_receive(:resource).once.and_return @Manager::ManagerInterfaceError.new
209
-
210
- manager = new_manager_without_events
211
- actions_connection = mock_for_next_created_socket
212
-
213
- the_following_code {
214
- manager.connect!
215
- }.should raise_error @Manager::ManagerInterface::AuthenticationFailedException
216
-
217
- end
218
-
219
- # FIXME: Fix this it or nuke it.
220
- # it "THIS TEST IS AN EXPERIMENT TO START FROM SCRATCH AND TEST WRITES GOING THROUGH THE WRITE QUEUE!" do
221
- # # Note: this it will be cleaned up and used a reference for refactoring the other failing tests in this file.
222
- # response = new_blank_ami_response
223
- # flexmock(@Manager::ManagerInterface::ManagerInterfaceAction).new_instances.should_receive(:response).once.and_return response
224
- #
225
- # flexmock(TCPSocket).should_receive(:new).once.and_return StringIO.new
226
- #
227
- # write_queue_mock = mocked_queue
228
- #
229
- # manager = new_manager_without_events
230
- # write_queue_mock.manager = manager
231
- #
232
- # manager.connect!
233
- #
234
- # manager.send_action "Ping"
235
- #
236
- # write_queue_mock.actions.size.should be 2
237
- # write_queue_mock.actions.first.name.should =="login"
238
- # write_queue_mock.actions.last.name.should =="ping"
239
- # end
240
-
241
- it "after calling connect!() with events enabled, both connections perform a login" do
242
- response = new_blank_ami_response
243
-
244
- flexstub(@Manager::ManagerInterface::ManagerInterfaceAction).new_instances.should_receive(:response).and_return response
245
-
246
- # FIXME: It would be better if actions_socket blocked like the real thing...
247
- actions_socket = StringIO.new
248
- events_socket = StringIO.new
249
-
250
- flexmock(TCPSocket).should_receive(:new).twice.and_return actions_socket, events_socket
251
-
252
- write_queue_mock = mocked_queue
253
-
254
- manager = new_manager_with_events
255
- flexmock(manager).should_receive(:start_actions_writer_loop).and_return true
256
- manager.connect!
257
-
258
- write_queue_mock.actions.first.name.should == "login"
259
- write_queue_mock.actions.first.headers['Events'].should == "Off"
260
- end
261
-
262
- it "a failed login on the actions socket raises an AuthenticationFailedException" do
263
- manager = new_manager_with_events
264
-
265
- mock_socket = flexmock("mock TCPSocket")
266
-
267
- # By saying this should happen only once, we're also asserting that the events thread never does a login.
268
- flexmock(EventSocket).should_receive(:connect).once.and_return mock_socket
269
-
270
- login_error = @Manager::ManagerInterfaceError.new
271
- login_error.message = "Authentication failed"
272
-
273
- action = @Manager::ManagerInterface::ManagerInterfaceAction.new "Login", "Username" => "therestdoesntmatter"
274
- flexmock(action).should_receive(:response).once.and_return login_error
275
-
276
- flexmock(@Manager::ManagerInterface::ManagerInterfaceAction).should_receive(:new).once.and_return action
277
-
278
- the_following_code {
279
- manager.connect!
280
- }.should raise_error @Manager::ManagerInterface::AuthenticationFailedException
281
-
282
- end
283
-
284
- # it "should raise an error if trying to send an action before connecting" do
285
- # the_following_code {
286
- # new_manager_without_events.send_action "foo"
287
- # }.should raise_error( @Manager::ManagerInterface::NotConnectedError)
288
- # end
289
-
290
- it "sending an Action on the ManagerInterface should be received by the EventSocket" do
291
- name, headers = "foobar", {"BLAH" => 1226534602.32764}
292
-
293
- response = @Manager::ManagerInterfaceResponse.new
294
-
295
- mock_connection = flexmock "EventSocket"
296
- flexmock(EventSocket).should_receive(:connect).once.and_return mock_connection
297
-
298
- action = @Manager::ManagerInterface::ManagerInterfaceAction.new(name, headers)
299
- action.future_resource.resource = response
300
-
301
- flexmock(@Manager::ManagerInterface::ManagerInterfaceAction).should_receive(:new).once.with(name, headers).and_return action
302
-
303
- write_queue_mock = mocked_queue
304
-
305
- manager = new_manager_without_events
306
- flexmock(manager).should_receive(:login_actions).once.and_return
307
-
308
- manager.connect!
309
- manager.send_action(name, headers)
310
-
311
- write_queue_mock.actions.size.should be 1
312
- end
313
-
314
- it 'ManagerInterface#action_error_received' do
315
- action_id = "foobar"
316
-
317
- error = @Manager::ManagerInterfaceError.new
318
- error["ActionID"] = action_id
319
-
320
- action = @Manager::ManagerInterface::ManagerInterfaceAction.new "Blah"
321
- flexmock(action).should_receive(:action_id).and_return action_id
322
- flexmock(action.future_resource).should_receive(:resource=).once.with(error)
323
- manager = new_manager_without_events
324
-
325
- flexmock(manager).should_receive(:data_for_message_received_with_action_id).once.with(action_id).and_return action
326
-
327
- manager.action_error_received error
328
- end
329
-
330
- it "unsupported actions" do
331
- @Manager::ManagerInterface::UnsupportedActionName::UNSUPPORTED_ACTION_NAMES.empty?.should_not be true
332
- @Manager::ManagerInterface::UnsupportedActionName::UNSUPPORTED_ACTION_NAMES.each do |action_name|
333
- manager = new_manager_without_events
334
- the_following_code {
335
- manager.send_action action_name
336
- }.should raise_error @Manager::ManagerInterface::UnsupportedActionName
337
- end
338
- end
339
- # FIXME: Fix this it or nuke it.
340
- # it "normal use of Action:SIPPeers (which has causal events)" do
341
- #
342
- # raise "TODO"
343
- #
344
- # response = @Manager::ManagerInterfaceResponse.new
345
- # response["Message"] = "Peer status list will follow"
346
- #
347
- # first_peer_entry = @Manager::ManagerInterfaceEvent.new "PeerEntry"
348
- # { "Channeltype" => "SIP", "ObjectName" => "softphone", "ChanObjectType" => "peer", "IPaddress" => "-none-",
349
- # "IPport" => "0", "Dynamic" => "yes", "Natsupport" => "no", "VideoSupport" => "no", "ACL" => "no",
350
- # "Status" => "Unmonitored", "RealtimeDevice" => "no" }.each_pair do |key,value|
351
- # first_peer_entry[key] = value
352
- # end
353
- #
354
- # second_peer_entry = @Manager::ManagerInterfaceEvent.new "PeerEntry"
355
- # { "Channeltype" => "SIP", "ObjectName" => "teliax", "ChanObjectType" => "peer", "IPaddress" => "74.201.8.23",
356
- # "IPport" => "5060", "Dynamic" => "no", "Natsupport" => "yes", "VideoSupport" => "no", "ACL" => "no",
357
- # "Status" => "OK (24 ms)", "RealtimeDevice" => "no" }.each_pair do |key, value|
358
- # second_peer_entry[key] = value
359
- # end
360
- #
361
- # ender = @Manager::ManagerInterfaceEvent.new "PeerlistComplete"
362
- # ender["ListItems"] = "2"
363
- #
364
- # # flexmock(@Manager::ManagerInterface).new_instances.should_receive(:actions_connection_established).once.and_return
365
- # # flexmock(@Manager::ManagerInterface).new_instances.should_receive(:write_loop).once.and_return
366
- #
367
- # manager = new_manager_without_events
368
- #
369
- # class << manager
370
- # undef write_loop
371
- # end
372
- # action = manager.send_action "SIPPeers"
373
- #
374
- # manager.send(:action_message_received, response)
375
- # manager.send(:action_message_received, first_peer_entry)
376
- # manager.send(:action_message_received, second_peer_entry)
377
- # manager.send(:action_message_received, ender)
378
- #
379
- # action.response.should be_a_kind_of Array
380
- # action.response.size.should be 2
381
- #
382
- # first, second = response.response
383
- #
384
- # first["ObjectName"].should =="softphone"
385
- # last["ObjectName"].should =="teliax"
386
- # end
387
- #
388
- # FIXME: Fix this it or nuke it.
389
- # it "use of Action:SIPPeers (which has causal events) which causes an error" do
390
- #
391
- # end
392
-
393
- # TODO: Create the abstraction layer atop AMI with separate tests and it harness.
394
-
395
- # TODO: Add tests which cause actions that don't reply with an action ID to raise an exception when sent
396
-
397
- end
398
-
399
- describe "ManagerInterface#write_loop" do
400
-
401
- include ManagerInterfaceTestHelper
402
-
403
- before :each do
404
- @Manager = Adhearsion::VoIP::Asterisk::Manager
405
- end
406
-
407
- it "should stop when the stop instruction is sent to the write queue and return :stopped" do
408
- flexmock(TCPSocket).should_receive(:new).once.and_return StringIO.new
409
- flexmock(FutureResource).new_instances.should_receive(:resource).once.and_return new_blank_ami_response
410
-
411
- mock_queue = flexmock "a mock write-Queue"
412
-
413
- mock_queue.should_receive(:shift).once.and_return :STOP!
414
- mock_queue.should_receive(:<<).and_return nil
415
-
416
- flexmock(Queue).should_receive(:new).once.and_return mock_queue
417
-
418
- manager = new_manager_without_events
419
- manager.connect!
420
- manager.disconnect!
421
- end
422
-
423
- end
424
-
425
- describe "Class methods of ManagerInterface" do
426
-
427
- before(:each) do
428
- @ManagerInterface = Adhearsion::VoIP::Asterisk::Manager::ManagerInterface
429
- end
430
-
431
- it "the SIPPeers actions should be a causal event" do
432
- @ManagerInterface.has_causal_events?("SIPPeers").should be true
433
- end
434
-
435
- it "the Queues action should not respond with an action id" do
436
- @ManagerInterface.replies_with_action_id?("Queues").should == false
437
- end
438
-
439
- it "the IAXPeers action should not respond with an action id" do
440
- # FIXME: This test relies on the side effect that earlier tests have run
441
- # and initialized the UnsupportedActionName::UNSUPPORTED_ACTION_NAMES
442
- # constant for an "unknown" version of Asterisk. This should be fixed
443
- # to be more specific about which version of Asterisk is under test.
444
- # IAXPeers is supported (with Action IDs!) since Asterisk 1.8
445
- @ManagerInterface.replies_with_action_id?("IAXPeers").should == false
446
- end
447
-
448
- it "the ParkedCalls terminator event" do
449
- @ManagerInterface.causal_event_terminator_name_for("ParkedCalls").should =="parkedcallscomplete"
450
- @ManagerInterface.causal_event_terminator_name_for("parkedcalls").should =="parkedcallscomplete"
451
- end
452
-
453
- end
454
-
455
- describe "ManagerInterfaceAction" do
456
-
457
- before :each do
458
- @ManagerInterface = Adhearsion::VoIP::Asterisk::Manager::ManagerInterface
459
- end
460
-
461
- it "should simply proxy the replies_with_action_id?() method" do
462
- name, headers = "foobar", {"foo" => "bar"}
463
- flexmock(@ManagerInterface).should_receive(:replies_with_action_id?).once.and_return
464
- @ManagerInterface::ManagerInterfaceAction.new(name, headers).replies_with_action_id?
465
- end
466
-
467
- it "should simply proxy the has_causal_events?() method" do
468
- name, headers = "foobar", {"foo" => "bar"}
469
- action = @ManagerInterface::ManagerInterfaceAction.new(name, headers)
470
- flexmock(@ManagerInterface).should_receive(:has_causal_events?).once.with(name, headers).and_return :foo
471
- action.has_causal_events?.should be :foo
472
- end
473
-
474
- it "should properly convert itself into a String when additional headers are given" do
475
- name, headers = "Hawtsawce", {"Monkey" => "Zoo"}
476
- string = @ManagerInterface::ManagerInterfaceAction.new(name, headers).to_s
477
- string.should =~ /^Action: Hawtsawce\r\n/i
478
- string.should =~ /[^\n]\r\n\r\n$/
479
- string.should =~ /^(\w+:\s*[\w-]+\r\n){3}\r\n$/
480
- end
481
-
482
- it "should properly convert itself into a String when no additional headers are given" do
483
- string = @ManagerInterface::ManagerInterfaceAction.new("Ping").to_s
484
- string.should =~ /^Action: Ping\r\nActionID: [\w-]+\r\n\r\n$/i
485
-
486
- string = @ManagerInterface::ManagerInterfaceAction.new("ParkedCalls").to_s
487
- string.should =~ /^Action: ParkedCalls\r\nActionID: [\w-]+\r\n\r\n$/i
488
- end
489
-
490
- end
491
-
492
- describe "DelegatingAsteriskManagerInterfaceLexer" do
493
- it "should translate the :syntax_error_encountered method call when a method_delegation_map is given" do
494
- official_method, new_method = :syntax_error_encountered, :ohai_syntax_error!
495
- method_argument = :testing123
496
- mock_manager_interface = flexmock "ManagerInterface which receives callbacks"
497
- mock_manager_interface.should_receive(new_method).once.with(method_argument).and_return
498
- parser = Adhearsion::VoIP::Asterisk::Manager::DelegatingAsteriskManagerInterfaceLexer.new mock_manager_interface,
499
- official_method => new_method
500
- parser.send official_method, method_argument
501
- end
502
- it "should translate the :message_received method call when a method_delegation_map is given" do
503
- official_method, new_method = :message_received, :wuzup_new_message_YO!
504
- method_argument = :message_message_message_message
505
- mock_manager_interface = flexmock "ManagerInterface which receives callbacks"
506
- mock_manager_interface.should_receive(new_method).once.with(method_argument).and_return
507
- parser = Adhearsion::VoIP::Asterisk::Manager::DelegatingAsteriskManagerInterfaceLexer.new mock_manager_interface,
508
- official_method => new_method
509
- parser.send official_method, method_argument
510
- end
511
- it "should translate the :syntax_error_encountered method call when a method_delegation_map is given" do
512
- official_method, new_method = :error_received, :zomgs_ERROR!
513
- method_argument = :errrrrrr
514
- mock_manager_interface = flexmock "ManagerInterface which receives callbacks"
515
- mock_manager_interface.should_receive(new_method).once.with(method_argument).and_return
516
- parser = Adhearsion::VoIP::Asterisk::Manager::DelegatingAsteriskManagerInterfaceLexer.new mock_manager_interface,
517
- official_method => new_method
518
- parser.send official_method, method_argument
519
- end
520
-
521
- it "should translate all method calls when a comprehensive method_delegation_map is given" do
522
- method_delegation_map = {
523
- :error_received => :here_is_an_error,
524
- :message_received => :here_is_a_message,
525
- :syntax_error_encountered => :here_is_a_syntax_error
526
- }
527
- mock_manager_interface = flexmock "ManagerInterface which receives callbacks"
528
- method_delegation_map.each_pair do |old_method,new_method|
529
- mock_manager_interface.should_receive(new_method).once.with(old_method).and_return
530
- end
531
- parser = Adhearsion::VoIP::Asterisk::Manager::DelegatingAsteriskManagerInterfaceLexer.new mock_manager_interface, method_delegation_map
532
- method_delegation_map.each_pair do |old_method, new_method|
533
- parser.send(old_method, old_method)
534
- end
535
- end
536
- end
537
-
538
- describe "ActionManagerInterfaceConnection" do
539
- it "should notify its associated ManagerInterface when a new message is received"
540
- it "should notify its associated ManagerInterface when a new event is received"
541
- it "should notify its associated ManagerInterface when a new error is received"
542
- end
543
-
544
- describe "EventManagerInterfaceConnection" do
545
- it "should notify its associated ManagerInterface when a new message is received"
546
- it "should notify its associated ManagerInterface when a new event is received"
547
- it "should notify its associated ManagerInterface when a new error is received"
548
- it "should stop gracefully by allowing the Queue to finish writing to the Theatre"
549
- it "should stop forcefully by not allowing the Queue to finish writing to the Theatre"
550
- end