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.
- data/.gitignore +17 -10
- data/CHANGELOG.md +273 -0
- data/Gemfile +1 -1
- data/Guardfile +17 -0
- data/README.markdown +61 -9
- data/Rakefile +16 -48
- data/adhearsion.gemspec +21 -7
- data/bin/ahn +3 -1
- data/cucumber.yml +4 -0
- data/features/app_generator.feature +42 -0
- data/features/cli.feature +108 -0
- data/features/step_definitions/app_generator_steps.rb +6 -0
- data/features/step_definitions/cli_steps.rb +74 -0
- data/features/support/aruba_helper.rb +22 -0
- data/features/support/env.rb +37 -0
- data/features/support/utils.rb +8 -0
- data/lib/adhearsion.rb +85 -41
- data/lib/adhearsion/call.rb +176 -0
- data/lib/adhearsion/call_controller.rb +134 -0
- data/lib/adhearsion/call_controller/dial.rb +70 -0
- data/lib/adhearsion/call_controller/input.rb +173 -0
- data/lib/adhearsion/call_controller/menu.rb +124 -0
- data/lib/adhearsion/call_controller/output.rb +267 -0
- data/lib/adhearsion/call_controller/record.rb +42 -0
- data/lib/adhearsion/call_controller/utility.rb +60 -0
- data/lib/adhearsion/calls.rb +81 -0
- data/lib/adhearsion/cli.rb +1 -3
- data/lib/adhearsion/cli_commands.rb +142 -0
- data/lib/adhearsion/configuration.rb +149 -0
- data/lib/adhearsion/console.rb +19 -8
- data/lib/adhearsion/dialplan_controller.rb +9 -0
- data/lib/adhearsion/events.rb +84 -0
- data/lib/adhearsion/foundation/all.rb +0 -7
- data/lib/adhearsion/foundation/custom_daemonizer.rb +4 -6
- data/lib/adhearsion/foundation/exception_handler.rb +9 -0
- data/lib/adhearsion/foundation/object.rb +26 -8
- data/lib/adhearsion/foundation/synchronized_hash.rb +3 -6
- data/lib/adhearsion/foundation/thread_safety.rb +17 -1
- data/lib/adhearsion/generators/app/app_generator.rb +4 -13
- data/lib/adhearsion/generators/app/templates/Gemfile +10 -5
- data/lib/adhearsion/generators/app/templates/Procfile +1 -0
- data/lib/adhearsion/generators/app/templates/README.md +28 -0
- data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +41 -0
- data/lib/adhearsion/generators/app/templates/{components/simon_game → lib}/simon_game.rb +6 -18
- data/lib/adhearsion/generators/app/templates/script/ahn +2 -2
- data/lib/adhearsion/initializer.rb +151 -293
- data/lib/adhearsion/initializer/logging.rb +33 -0
- data/lib/adhearsion/logging.rb +65 -69
- data/lib/adhearsion/menu_dsl.rb +15 -0
- data/lib/adhearsion/menu_dsl/calculated_match.rb +39 -0
- data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +41 -0
- data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +18 -0
- data/lib/adhearsion/menu_dsl/match_calculator.rb +36 -0
- data/lib/adhearsion/{voip/menu_state_machine/menu_class.rb → menu_dsl/menu.rb} +38 -40
- data/lib/adhearsion/menu_dsl/menu_builder.rb +69 -0
- data/lib/adhearsion/menu_dsl/range_match_calculator.rb +55 -0
- data/lib/adhearsion/menu_dsl/string_match_calculator.rb +21 -0
- data/lib/adhearsion/outbound_call.rb +64 -0
- data/lib/adhearsion/plugin.rb +319 -0
- data/lib/adhearsion/plugin/collection.rb +19 -0
- data/lib/adhearsion/plugin/initializer.rb +37 -0
- data/lib/adhearsion/plugin/methods_container.rb +6 -0
- data/lib/adhearsion/process.rb +94 -0
- data/lib/adhearsion/punchblock_plugin.rb +29 -0
- data/lib/adhearsion/punchblock_plugin/initializer.rb +137 -0
- data/lib/adhearsion/router.rb +30 -0
- data/lib/adhearsion/router/route.rb +42 -0
- data/lib/adhearsion/script_ahn_loader.rb +2 -2
- data/lib/adhearsion/tasks.rb +14 -9
- data/lib/adhearsion/tasks/configuration.rb +26 -0
- data/lib/adhearsion/tasks/plugins.rb +17 -0
- data/lib/adhearsion/version.rb +8 -14
- data/spec/adhearsion/call_controller/dial_spec.rb +138 -0
- data/spec/adhearsion/call_controller/input_spec.rb +278 -0
- data/spec/adhearsion/call_controller/menu_spec.rb +120 -0
- data/spec/adhearsion/call_controller/output_spec.rb +466 -0
- data/spec/adhearsion/call_controller/record_spec.rb +125 -0
- data/spec/adhearsion/call_controller_spec.rb +395 -0
- data/spec/adhearsion/call_spec.rb +438 -0
- data/spec/adhearsion/calls_spec.rb +47 -0
- data/spec/adhearsion/configuration_spec.rb +308 -0
- data/spec/adhearsion/dialplan_controller_spec.rb +26 -0
- data/spec/adhearsion/events_spec.rb +112 -0
- data/spec/adhearsion/initializer/logging_spec.rb +58 -0
- data/spec/adhearsion/initializer_spec.rb +209 -122
- data/spec/adhearsion/logging_spec.rb +58 -47
- data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +56 -0
- data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +57 -0
- data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +33 -0
- data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +13 -0
- data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +118 -0
- data/spec/adhearsion/menu_dsl/menu_spec.rb +210 -0
- data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +28 -0
- data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +36 -0
- data/spec/adhearsion/menu_dsl_spec.rb +12 -0
- data/spec/adhearsion/outbound_call_spec.rb +174 -0
- data/spec/adhearsion/plugin_spec.rb +489 -0
- data/spec/adhearsion/process_spec.rb +34 -0
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +294 -0
- data/spec/adhearsion/router/route_spec.rb +99 -0
- data/spec/adhearsion/router_spec.rb +106 -0
- data/spec/adhearsion_spec.rb +46 -0
- data/spec/spec_helper.rb +14 -14
- data/spec/support/call_controller_test_helpers.rb +48 -0
- data/spec/support/initializer_stubs.rb +8 -13
- data/spec/support/punchblock_mocks.rb +6 -0
- metadata +255 -253
- data/CHANGELOG +0 -174
- data/bin/ahnctl +0 -68
- data/bin/jahn +0 -43
- data/examples/asterisk_manager_interface/standalone.rb +0 -51
- data/lib/adhearsion/commands.rb +0 -302
- data/lib/adhearsion/component_manager.rb +0 -278
- data/lib/adhearsion/component_manager/component_tester.rb +0 -54
- data/lib/adhearsion/component_manager/spec_framework.rb +0 -18
- data/lib/adhearsion/events_support.rb +0 -65
- data/lib/adhearsion/foundation/blank_slate.rb +0 -3
- data/lib/adhearsion/foundation/event_socket.rb +0 -205
- data/lib/adhearsion/foundation/future_resource.rb +0 -36
- data/lib/adhearsion/foundation/metaprogramming.rb +0 -17
- data/lib/adhearsion/foundation/numeric.rb +0 -13
- data/lib/adhearsion/foundation/pseudo_guid.rb +0 -10
- data/lib/adhearsion/foundation/relationship_properties.rb +0 -42
- data/lib/adhearsion/foundation/string.rb +0 -26
- data/lib/adhearsion/generators/app/templates/.ahnrc +0 -34
- data/lib/adhearsion/generators/app/templates/README +0 -8
- data/lib/adhearsion/generators/app/templates/components/ami_remote/ami_remote.rb +0 -15
- data/lib/adhearsion/generators/app/templates/components/disabled/HOW_TO_ENABLE +0 -7
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/README.markdown +0 -47
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.rb +0 -34
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.yml +0 -12
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/README.markdown +0 -3
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +0 -11
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
- data/lib/adhearsion/generators/app/templates/config/startup.rb +0 -81
- data/lib/adhearsion/generators/app/templates/dialplan.rb +0 -3
- data/lib/adhearsion/generators/app/templates/events.rb +0 -33
- data/lib/adhearsion/host_definitions.rb +0 -67
- data/lib/adhearsion/initializer/asterisk.rb +0 -86
- data/lib/adhearsion/initializer/configuration.rb +0 -324
- data/lib/adhearsion/initializer/database.rb +0 -60
- data/lib/adhearsion/initializer/drb.rb +0 -31
- data/lib/adhearsion/initializer/freeswitch.rb +0 -22
- data/lib/adhearsion/initializer/ldap.rb +0 -57
- data/lib/adhearsion/initializer/rails.rb +0 -41
- data/lib/adhearsion/initializer/xmpp.rb +0 -42
- data/lib/adhearsion/tasks/components.rb +0 -32
- data/lib/adhearsion/tasks/database.rb +0 -5
- data/lib/adhearsion/tasks/deprecations.rb +0 -59
- data/lib/adhearsion/tasks/generating.rb +0 -20
- data/lib/adhearsion/tasks/lint.rb +0 -4
- data/lib/adhearsion/voip/asterisk.rb +0 -4
- data/lib/adhearsion/voip/asterisk/agi_server.rb +0 -121
- data/lib/adhearsion/voip/asterisk/commands.rb +0 -1966
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +0 -140
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +0 -102
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +0 -250
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +0 -240
- data/lib/adhearsion/voip/asterisk/config_manager.rb +0 -64
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -697
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +0 -1681
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +0 -341
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +0 -78
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +0 -87
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +0 -80
- data/lib/adhearsion/voip/call.rb +0 -521
- data/lib/adhearsion/voip/call_routing.rb +0 -64
- data/lib/adhearsion/voip/commands.rb +0 -17
- data/lib/adhearsion/voip/constants.rb +0 -39
- data/lib/adhearsion/voip/conveniences.rb +0 -18
- data/lib/adhearsion/voip/dial_plan.rb +0 -252
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +0 -151
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +0 -37
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +0 -27
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +0 -124
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +0 -69
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +0 -16
- data/lib/adhearsion/voip/dsl/numerical_string.rb +0 -128
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +0 -48
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +0 -58
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +0 -129
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +0 -38
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +0 -195
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +0 -80
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +0 -123
- data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +0 -57
- data/lib/adhearsion/xmpp/connection.rb +0 -61
- data/lib/theatre.rb +0 -147
- data/lib/theatre/README.markdown +0 -64
- data/lib/theatre/callback_definition_loader.rb +0 -86
- data/lib/theatre/guid.rb +0 -23
- data/lib/theatre/invocation.rb +0 -131
- data/lib/theatre/namespace_manager.rb +0 -153
- data/lib/theatre/version.rb +0 -2
- data/spec/adhearsion/cli_spec.rb +0 -306
- data/spec/adhearsion/component_manager_spec.rb +0 -292
- data/spec/adhearsion/constants_spec.rb +0 -8
- data/spec/adhearsion/drb_spec.rb +0 -65
- data/spec/adhearsion/fixtures/dialplan.rb +0 -3
- data/spec/adhearsion/foundation/event_socket_spec.rb +0 -168
- data/spec/adhearsion/host_definitions_spec.rb +0 -79
- data/spec/adhearsion/initializer/configuration_spec.rb +0 -291
- data/spec/adhearsion/initializer/loading_spec.rb +0 -154
- data/spec/adhearsion/initializer/paths_spec.rb +0 -74
- data/spec/adhearsion/relationship_properties_spec.rb +0 -54
- data/spec/adhearsion/voip/asterisk/agi_server_spec.rb +0 -473
- data/spec/adhearsion/voip/asterisk/ami/ami_spec.rb +0 -550
- data/spec/adhearsion/voip/asterisk/ami/lexer/ami_fixtures.yml +0 -30
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story +0 -291
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story.rb +0 -241
- data/spec/adhearsion/voip/asterisk/ami/lexer/story_helper.rb +0 -124
- data/spec/adhearsion/voip/asterisk/commands_spec.rb +0 -3241
- data/spec/adhearsion/voip/asterisk/config_file_generators/agents_spec.rb +0 -251
- data/spec/adhearsion/voip/asterisk/config_file_generators/queues_spec.rb +0 -323
- data/spec/adhearsion/voip/asterisk/config_file_generators/voicemail_spec.rb +0 -306
- data/spec/adhearsion/voip/asterisk/config_manager_spec.rb +0 -127
- data/spec/adhearsion/voip/asterisk/menu_command/calculated_match_spec.rb +0 -109
- data/spec/adhearsion/voip/asterisk/menu_command/matchers_spec.rb +0 -97
- data/spec/adhearsion/voip/call_routing_spec.rb +0 -125
- data/spec/adhearsion/voip/dialplan_manager_spec.rb +0 -468
- data/spec/adhearsion/voip/dsl/dialing_dsl_spec.rb +0 -270
- data/spec/adhearsion/voip/dsl/dispatcher_spec.rb +0 -82
- data/spec/adhearsion/voip/dsl/dispatcher_spec_helper.rb +0 -45
- data/spec/adhearsion/voip/dsl/parser_spec.rb +0 -69
- data/spec/adhearsion/voip/freeswitch/basic_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/inbound_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/oes_server_spec.rb +0 -9
- data/spec/adhearsion/voip/numerical_string_spec.rb +0 -61
- data/spec/adhearsion/voip/phone_number_spec.rb +0 -45
- data/spec/support/the_following_code.rb +0 -3
- data/spec/theatre/dsl_examples/simple_before_call.rb +0 -7
- data/spec/theatre/dsl_spec.rb +0 -69
- data/spec/theatre/invocation_spec.rb +0 -182
- data/spec/theatre/namespace_spec.rb +0 -125
- data/spec/theatre/spec_helper_spec.rb +0 -28
- data/spec/theatre/theatre_class_spec.rb +0 -148
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Adhearsion::Process do
|
|
4
|
+
before :each do
|
|
5
|
+
Adhearsion::Process.reset
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'should trigger :stop_requested events on #shutdown' do
|
|
9
|
+
flexmock(Adhearsion::Events).should_receive(:trigger_immediately).once.with(:stop_requested)
|
|
10
|
+
Adhearsion::Process.booted
|
|
11
|
+
Adhearsion::Process.shutdown
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it '#stop_when_zero_calls should wait until the list of active calls reaches 0' do
|
|
15
|
+
pending
|
|
16
|
+
calls = ThreadSafeArray.new
|
|
17
|
+
3.times do
|
|
18
|
+
fake_call = Object.new
|
|
19
|
+
flexmock(fake_call).should_receive(:hangup).once
|
|
20
|
+
calls << fake_call
|
|
21
|
+
end
|
|
22
|
+
flexmock(Adhearsion).should_receive(:active_calls).and_return calls
|
|
23
|
+
flexmock(Adhearsion::Process.instance).should_receive(:final_shutdown).once
|
|
24
|
+
calls = []
|
|
25
|
+
3.times { calls << Thread.new { sleep 1; calls.pop } }
|
|
26
|
+
Adhearsion::Process.stop_when_zero_calls
|
|
27
|
+
calls.each { |thread| thread.join }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should terminate the process immediately on #force_stop' do
|
|
31
|
+
flexmock(::Process).should_receive(:exit).with(1).once.and_return true
|
|
32
|
+
Adhearsion::Process.force_stop
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
class PunchblockPlugin
|
|
5
|
+
describe Initializer do
|
|
6
|
+
|
|
7
|
+
def reset_default_config
|
|
8
|
+
Adhearsion.config.punchblock do |config|
|
|
9
|
+
config.platform = :xmpp
|
|
10
|
+
config.username = "usera@127.0.0.1"
|
|
11
|
+
config.password = "1"
|
|
12
|
+
config.host = nil
|
|
13
|
+
config.port = nil
|
|
14
|
+
config.root_domain = nil
|
|
15
|
+
config.calls_domain = nil
|
|
16
|
+
config.mixers_domain = nil
|
|
17
|
+
config.connection_timeout = 60
|
|
18
|
+
config.reconnect_attempts = 1.0/0.0
|
|
19
|
+
config.reconnect_timer = 5
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize_punchblock(options = {})
|
|
24
|
+
reset_default_config
|
|
25
|
+
flexmock(Initializer).should_receive(:connect)
|
|
26
|
+
Adhearsion.config.punchblock do |config|
|
|
27
|
+
config.platform = options[:platform] if options.has_key?(:platform)
|
|
28
|
+
config.username = options[:username] if options.has_key?(:username)
|
|
29
|
+
config.password = options[:password] if options.has_key?(:password)
|
|
30
|
+
config.host = options[:host] if options.has_key?(:host)
|
|
31
|
+
config.port = options[:port] if options.has_key?(:port)
|
|
32
|
+
config.root_domain = options[:root_domain] if options.has_key?(:root_domain)
|
|
33
|
+
config.calls_domain = options[:calls_domain] if options.has_key?(:calls_domain)
|
|
34
|
+
config.mixers_domain = options[:mixers_domain] if options.has_key?(:mixers_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.start
|
|
41
|
+
Adhearsion.config[:punchblock]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
before do
|
|
45
|
+
Events.refresh!
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let(:call_id) { rand }
|
|
49
|
+
let(:offer) { ::Punchblock::Event::Offer.new.tap { |o| o.call_id = call_id } }
|
|
50
|
+
let(:mock_call) { flexmock('Call', :id => call_id).tap { |call| call.should_ignore_missing } }
|
|
51
|
+
let(:mock_manager) { flexmock 'a mock dialplan manager' }
|
|
52
|
+
|
|
53
|
+
describe "starts the client with the default values" do
|
|
54
|
+
subject { initialize_punchblock }
|
|
55
|
+
|
|
56
|
+
it "should set properly the username value" do
|
|
57
|
+
subject.username.should == 'usera@127.0.0.1'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should set properly the password value" do
|
|
61
|
+
subject.password.should == '1'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should set properly the host value" do
|
|
65
|
+
subject.host.should be_nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should set properly the port value" do
|
|
69
|
+
subject.port.should be_nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should set properly the root_domain value" do
|
|
73
|
+
subject.root_domain.should be_nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should set properly the calls_domain value" do
|
|
77
|
+
subject.calls_domain.should be_nil
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should set properly the mixers_domain value" do
|
|
81
|
+
subject.mixers_domain.should be_nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should properly set the reconnect_attempts value" do
|
|
85
|
+
subject.reconnect_attempts.should == 1.0/0.0
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should properly set the reconnect_timer value" do
|
|
89
|
+
subject.reconnect_timer.should == 5
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "starts the client with any overridden settings" do
|
|
94
|
+
overrides = {:username => 'userb@127.0.0.1', :password => '123', :host => 'foo.bar.com', :port => 200, :connection_timeout => 20, :root_domain => 'foo.com', :calls_domain => 'call.foo.com', :mixers_domain => 'mixer.foo.com'}
|
|
95
|
+
|
|
96
|
+
flexmock(::Punchblock::Connection::XMPP).should_receive(:new).once.with(overrides).and_return do
|
|
97
|
+
flexmock 'Client', :event_handler= => true
|
|
98
|
+
end
|
|
99
|
+
initialize_punchblock overrides
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe "#connect" do
|
|
103
|
+
it 'should block until the connection is established' do
|
|
104
|
+
reset_default_config
|
|
105
|
+
mock_connection = flexmock :mock_connection
|
|
106
|
+
mock_connection.should_receive(:register_event_handler).once
|
|
107
|
+
flexmock(::Punchblock::Client).should_receive(:new).once.and_return mock_connection
|
|
108
|
+
flexmock(mock_connection).should_receive(:run).once
|
|
109
|
+
t = Thread.new { Initializer.start }
|
|
110
|
+
t.join 5
|
|
111
|
+
t.status.should == "sleep"
|
|
112
|
+
Events.trigger_immediately :punchblock, ::Punchblock::Connection::Connected.new
|
|
113
|
+
t.join
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe '#connect_to_server' do
|
|
118
|
+
let(:mock_client) { flexmock :client }
|
|
119
|
+
|
|
120
|
+
before :each do
|
|
121
|
+
Adhearsion::Process.reset
|
|
122
|
+
Initializer.config = reset_default_config
|
|
123
|
+
Initializer.config.reconnect_attempts = 1
|
|
124
|
+
flexmock(Adhearsion::Logging.get_logger(Initializer)).should_receive(:fatal).at_most.once
|
|
125
|
+
flexmock(Initializer).should_receive(:client).and_return mock_client
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
after :each do
|
|
129
|
+
Adhearsion::Process.reset
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it 'should reset the Adhearsion process state to "booting"' do
|
|
133
|
+
Adhearsion::Process.booted
|
|
134
|
+
Adhearsion::Process.state_name.should == :running
|
|
135
|
+
mock_client.should_receive(:run).and_raise ::Punchblock::DisconnectedError
|
|
136
|
+
expect { Initializer.connect_to_server }.should raise_error ::Punchblock::DisconnectedError
|
|
137
|
+
Adhearsion::Process.state_name.should == :booting
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'should retry the connection the specified number of times' do
|
|
141
|
+
Initializer.config.reconnect_attempts = 3
|
|
142
|
+
mock_client.should_receive(:run).and_raise ::Punchblock::DisconnectedError
|
|
143
|
+
expect { Initializer.connect_to_server }.should raise_error ::Punchblock::DisconnectedError
|
|
144
|
+
Initializer.attempts.should == 3
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it 'should preserve a Punchblock::ProtocolError exception and give up' do
|
|
148
|
+
mock_client.should_receive(:run).and_raise ::Punchblock::ProtocolError
|
|
149
|
+
expect { Initializer.connect_to_server }.should raise_error ::Punchblock::ProtocolError
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'should not attempt to reconnect if Adhearsion is shutting down' do
|
|
153
|
+
Adhearsion::Process.booted
|
|
154
|
+
Adhearsion::Process.shutdown
|
|
155
|
+
mock_client.should_receive(:run).and_raise ::Punchblock::DisconnectedError
|
|
156
|
+
Initializer.should_not raise_error ::Punchblock::DisconnectedError
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
describe 'using Asterisk' do
|
|
161
|
+
let(:overrides) { {:username => 'test', :password => '123', :host => 'foo.bar.com', :port => 200, :connection_timeout => 20, :root_domain => 'foo.com', :calls_domain => 'call.foo.com', :mixers_domain => 'mixer.foo.com'} }
|
|
162
|
+
|
|
163
|
+
it 'should start an Asterisk PB connection' do
|
|
164
|
+
flexmock(::Punchblock::Connection::Asterisk).should_receive(:new).once.with(overrides).and_return do
|
|
165
|
+
flexmock 'Client', :event_handler= => true
|
|
166
|
+
end
|
|
167
|
+
initialize_punchblock overrides.merge(:platform => :asterisk)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'should place events from Punchblock into the event handler' do
|
|
172
|
+
flexmock(Events.instance).should_receive(:trigger).once.with(:punchblock, offer)
|
|
173
|
+
initialize_punchblock
|
|
174
|
+
Initializer.client.handle_event offer
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe "dispatching an offer" do
|
|
178
|
+
before do
|
|
179
|
+
initialize_punchblock
|
|
180
|
+
flexmock(Adhearsion::Process).should_receive(:state_name).once.and_return process_state
|
|
181
|
+
flexmock(Adhearsion.active_calls).should_receive(:from_offer).once.and_return mock_call
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
context "when the Adhearsion::Process is :booting" do
|
|
185
|
+
let(:process_state) { :booting }
|
|
186
|
+
|
|
187
|
+
it 'should reject a call with cause :declined' do
|
|
188
|
+
mock_call.should_receive(:reject).once.with(:decline)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
context "when when Adhearsion::Process is in :running" do
|
|
193
|
+
let(:process_state) { :running }
|
|
194
|
+
|
|
195
|
+
it "should execute the dispatcher provided by the router" do
|
|
196
|
+
controller = Class.new
|
|
197
|
+
Adhearsion.router do
|
|
198
|
+
route 'foobar', controller
|
|
199
|
+
end
|
|
200
|
+
first_route = Adhearsion.router.routes.first
|
|
201
|
+
flexmock(first_route.dispatcher).should_receive(:call).once.with mock_call
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context "when when Adhearsion::Process is in :rejecting" do
|
|
206
|
+
let(:process_state) { :rejecting }
|
|
207
|
+
|
|
208
|
+
it 'should reject a call with cause :declined' do
|
|
209
|
+
mock_call.should_receive(:reject).once.with(:decline)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context "when when Adhearsion::Process is not :running, :stopping or :rejecting" do
|
|
214
|
+
let(:process_state) { :foobar }
|
|
215
|
+
|
|
216
|
+
it 'should reject a call with cause :error' do
|
|
217
|
+
mock_call.should_receive(:reject).once.with(:error)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
after { Events.trigger_immediately :punchblock, offer }
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
describe "dispatching a component event" do
|
|
225
|
+
let(:component) { flexmock 'ComponentNode' }
|
|
226
|
+
let(:mock_event) { flexmock 'Event', :call_id => call_id, :source => component }
|
|
227
|
+
|
|
228
|
+
before do
|
|
229
|
+
initialize_punchblock
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it "should place the event in the call's inbox" do
|
|
233
|
+
component.should_receive(:trigger_event_handler).once.with mock_event
|
|
234
|
+
Events.trigger_immediately :punchblock, mock_event
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
describe "dispatching a call event" do
|
|
239
|
+
let(:mock_event) { flexmock 'Event', :call_id => call_id }
|
|
240
|
+
let(:latch) { CountDownLatch.new 1 }
|
|
241
|
+
|
|
242
|
+
describe "with an active call" do
|
|
243
|
+
before do
|
|
244
|
+
initialize_punchblock
|
|
245
|
+
Adhearsion.active_calls << mock_call
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should log an error" do
|
|
249
|
+
flexmock(Adhearsion::Logging.get_logger(Initializer)).should_receive(:debug).once.with("Event received for call #{call_id}: #{mock_event.inspect}")
|
|
250
|
+
Events.trigger_immediately :punchblock, mock_event
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "should place the event in the call's inbox" do
|
|
254
|
+
mock_call.should_receive(:<<).once.with(mock_event)
|
|
255
|
+
Initializer.dispatch_call_event mock_event, latch
|
|
256
|
+
latch.wait(10).should be_true
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
describe "with an inactive call" do
|
|
261
|
+
let(:mock_event) { flexmock 'Event', :call_id => call_id }
|
|
262
|
+
|
|
263
|
+
it "should log an error" do
|
|
264
|
+
flexmock(Adhearsion::Logging.get_logger(Initializer)).should_receive(:error).once.with("Event received for inactive call #{call_id}: #{mock_event.inspect}")
|
|
265
|
+
Initializer.dispatch_call_event mock_event
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
context "Punchblock configuration" do
|
|
271
|
+
describe "with config specified" do
|
|
272
|
+
before do
|
|
273
|
+
Adhearsion.config.punchblock do |config|
|
|
274
|
+
config.username = 'userb@127.0.0.1'
|
|
275
|
+
config.password = 'abc123'
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
subject do
|
|
280
|
+
Adhearsion.config[:punchblock]
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
it "should set properly the username value" do
|
|
284
|
+
subject.username.should == 'userb@127.0.0.1'
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "should set properly the password value" do
|
|
288
|
+
subject.password.should == 'abc123'
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
class Router
|
|
5
|
+
describe Route do
|
|
6
|
+
describe 'a new route' do
|
|
7
|
+
let(:name) { 'catchall' }
|
|
8
|
+
let(:guards) do
|
|
9
|
+
[
|
|
10
|
+
{:to => /foobar/},
|
|
11
|
+
[{:from => 'fred'}, {:from => 'paul'}]
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "with a class target and guards" do
|
|
16
|
+
let(:target) { CallController }
|
|
17
|
+
|
|
18
|
+
subject { Route.new name, target, *guards }
|
|
19
|
+
|
|
20
|
+
its(:name) { should == name }
|
|
21
|
+
its(:target) { should == target }
|
|
22
|
+
its(:guards) { should == guards }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "with a block target and guards" do
|
|
26
|
+
subject { Route.new(name, *guards) { :foo } }
|
|
27
|
+
|
|
28
|
+
its(:name) { should == name }
|
|
29
|
+
its(:target) { should be_a Proc }
|
|
30
|
+
its(:guards) { should == guards }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "a guarded route" do
|
|
35
|
+
subject { Route.new 'foobar', CallController, *guards }
|
|
36
|
+
|
|
37
|
+
def should_match_the_call
|
|
38
|
+
subject.match?(call).should be true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def should_not_match_the_call
|
|
42
|
+
subject.match?(call).should be false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe "matching calls from fred to paul" do
|
|
46
|
+
let :guards do
|
|
47
|
+
[
|
|
48
|
+
{:from => 'fred', :to => 'paul'}
|
|
49
|
+
]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "with a call from fred to paul" do
|
|
53
|
+
let(:call) { flexmock 'Adhearsion::Call', :from => 'fred', :to => 'paul' }
|
|
54
|
+
it { should_match_the_call }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "with a call from fred to frank" do
|
|
58
|
+
let(:call) { flexmock 'Adhearsion::Call', :from => 'fred', :to => 'frank' }
|
|
59
|
+
it { should_not_match_the_call }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "with a call from frank to paul" do
|
|
63
|
+
let(:call) { flexmock 'Adhearsion::Call', :from => 'frank', :to => 'paul' }
|
|
64
|
+
it { should_not_match_the_call }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe "dispatching a call" do
|
|
70
|
+
let(:call) { Call.new }
|
|
71
|
+
|
|
72
|
+
context "via a call controller" do
|
|
73
|
+
let(:controller) { CallController }
|
|
74
|
+
let(:route) { Route.new 'foobar', controller }
|
|
75
|
+
|
|
76
|
+
it "should instruct the call to use an instance of the controller" do
|
|
77
|
+
flexmock(call).should_receive(:execute_controller).once.with controller
|
|
78
|
+
route.dispatcher.call call
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "via a block" do
|
|
83
|
+
let :route do
|
|
84
|
+
Route.new 'foobar' do
|
|
85
|
+
:foobar
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should instruct the call to use an instance of DialplanController with the correct block" do
|
|
90
|
+
flexmock(call).should_receive(:execute_controller).once.with(DialplanController).and_return do |controller|
|
|
91
|
+
controller.dialplan.call.should == :foobar
|
|
92
|
+
end
|
|
93
|
+
route.dispatcher.call call
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
FooBarController = Class.new
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
describe Router do
|
|
7
|
+
describe 'a new router' do
|
|
8
|
+
subject { Router.new {} }
|
|
9
|
+
|
|
10
|
+
it "should make the router available to the block" do
|
|
11
|
+
foo = nil
|
|
12
|
+
Router.new do
|
|
13
|
+
foo = self
|
|
14
|
+
end
|
|
15
|
+
foo.should be_a Router
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "defining routes in the block" do
|
|
19
|
+
let(:router) do
|
|
20
|
+
Router.new do
|
|
21
|
+
route 'calls from fred', FooBarController, :from => 'fred'
|
|
22
|
+
route 'calls from paul', :from => 'paul' do
|
|
23
|
+
:bar
|
|
24
|
+
end
|
|
25
|
+
route 'catchall' do
|
|
26
|
+
:foo
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
subject { router.routes }
|
|
32
|
+
|
|
33
|
+
it { should have(3).elements }
|
|
34
|
+
|
|
35
|
+
it "should contain Routes" do
|
|
36
|
+
subject.each do |route|
|
|
37
|
+
route.should be_a Router::Route
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should build up the routes with the correct data" do
|
|
42
|
+
subject[0].name.should == 'calls from fred'
|
|
43
|
+
subject[0].guards.should == [{:from => 'fred'}]
|
|
44
|
+
subject[0].target.should == FooBarController
|
|
45
|
+
|
|
46
|
+
subject[1].name.should == 'calls from paul'
|
|
47
|
+
subject[1].guards.should == [{:from => 'paul'}]
|
|
48
|
+
subject[1].target.should be_a Proc
|
|
49
|
+
|
|
50
|
+
subject[2].name.should == 'catchall'
|
|
51
|
+
subject[2].guards.should == []
|
|
52
|
+
subject[2].target.should be_a Proc
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "matching a call" do
|
|
57
|
+
let(:router) do
|
|
58
|
+
Router.new do
|
|
59
|
+
route 'calls from fred', FooBarController, :from => 'fred'
|
|
60
|
+
route 'calls from fred2', :from => 'fred' do
|
|
61
|
+
:car
|
|
62
|
+
end
|
|
63
|
+
route 'calls from paul', :from => 'paul' do
|
|
64
|
+
:bar
|
|
65
|
+
end
|
|
66
|
+
route 'catchall' do
|
|
67
|
+
:foo
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
subject { router.match call }
|
|
73
|
+
|
|
74
|
+
context 'with a call from fred' do
|
|
75
|
+
let(:call) { flexmock 'Adhearsion::Call', :from => 'fred' }
|
|
76
|
+
its(:name) { should == 'calls from fred' }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context 'with a call from paul' do
|
|
80
|
+
let(:call) { flexmock 'Adhearsion::Call', :from => 'paul' }
|
|
81
|
+
its(:name) { should == 'calls from paul' }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context 'with a call from frank' do
|
|
85
|
+
let(:call) { flexmock 'Adhearsion::Call', :from => 'frank' }
|
|
86
|
+
its(:name) { should == 'catchall' }
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "handling a call" do
|
|
91
|
+
subject do
|
|
92
|
+
Router.new do
|
|
93
|
+
route 'catchall', FooBarController
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
let(:call) { flexmock 'Adhearsion::Call', :id => 'abc123' }
|
|
98
|
+
let(:route) { subject.routes.first }
|
|
99
|
+
|
|
100
|
+
it "should return the route's dispatcher" do
|
|
101
|
+
subject.handle(call).should be route.dispatcher
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|