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,438 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
describe Call do
|
|
5
|
+
let(:headers) { nil }
|
|
6
|
+
let(:offer) { mock_offer nil, headers }
|
|
7
|
+
subject { Adhearsion::Call.new offer }
|
|
8
|
+
|
|
9
|
+
after do
|
|
10
|
+
Adhearsion.active_calls.clear!
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it { should respond_to :<< }
|
|
14
|
+
|
|
15
|
+
its(:end_reason) { should == nil }
|
|
16
|
+
it { should be_active }
|
|
17
|
+
|
|
18
|
+
its(:commands) { should be_a Call::CommandRegistry }
|
|
19
|
+
its(:commands) { should be_empty }
|
|
20
|
+
|
|
21
|
+
describe "its variables" do
|
|
22
|
+
context "with an offer with headers" do
|
|
23
|
+
let(:headers) { {:x_foo => 'bar'} }
|
|
24
|
+
its(:variables) { should == headers }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "with an offer without headers" do
|
|
28
|
+
let(:headers) { nil }
|
|
29
|
+
its(:variables) { should == {} }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "without an offer" do
|
|
33
|
+
let(:offer) { nil }
|
|
34
|
+
its(:variables) { should == {} }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it '#id should return the ID from the Offer' do
|
|
39
|
+
offer = mock_offer
|
|
40
|
+
Adhearsion::Call.new(offer).id.should == offer.call_id
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'should store the original offer' do
|
|
44
|
+
offer = mock_offer
|
|
45
|
+
Adhearsion::Call.new(offer).offer.should == offer
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe 'without an offer' do
|
|
49
|
+
it 'should not raise an exception' do
|
|
50
|
+
lambda { Adhearsion::Call.new }.should_not raise_error
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should store the Punchblock client from the Offer" do
|
|
55
|
+
offer = mock_offer
|
|
56
|
+
client = flexmock('Client')
|
|
57
|
+
offer.should_receive(:client).once.and_return(client)
|
|
58
|
+
Adhearsion::Call.new(offer).client.should == client
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'a hungup call removes itself from the active calls' do
|
|
62
|
+
size_before = Adhearsion.active_calls.size
|
|
63
|
+
|
|
64
|
+
call = Adhearsion.active_calls.from_offer mock_offer
|
|
65
|
+
Adhearsion.active_calls.size.should > size_before
|
|
66
|
+
call.hangup
|
|
67
|
+
Adhearsion.active_calls.size.should == size_before
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'allows the registration of event handlers which are called when messages are delivered' do
|
|
71
|
+
event = flexmock 'Event'
|
|
72
|
+
event.should_receive(:foo?).and_return true
|
|
73
|
+
response = flexmock 'Response'
|
|
74
|
+
response.should_receive(:call).once
|
|
75
|
+
subject.register_event_handler(:foo?) { response.call }
|
|
76
|
+
subject << event
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe "event handlers" do
|
|
80
|
+
let(:response) { flexmock 'Response' }
|
|
81
|
+
|
|
82
|
+
describe "for end events" do
|
|
83
|
+
let :event do
|
|
84
|
+
Punchblock::Event::End.new.tap do |e|
|
|
85
|
+
flexmock e, :reason => :hangup
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should trigger any on_end callbacks set" do
|
|
90
|
+
response.should_receive(:call).once.with(event)
|
|
91
|
+
subject.on_end { |event| response.call event }
|
|
92
|
+
subject << event
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe "#<<" do
|
|
98
|
+
describe "with a Punchblock End" do
|
|
99
|
+
let :end_event do
|
|
100
|
+
Punchblock::Event::End.new.tap do |e|
|
|
101
|
+
flexmock e, :reason => :hangup
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should mark the call as ended" do
|
|
106
|
+
flexmock(subject).should_receive(:hangup).once
|
|
107
|
+
subject << end_event
|
|
108
|
+
subject.should_not be_active
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should set the end reason" do
|
|
112
|
+
subject << end_event
|
|
113
|
+
subject.end_reason.should == :hangup
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should instruct the command registry to terminate" do
|
|
117
|
+
flexmock(subject.commands).should_receive(:terminate).once
|
|
118
|
+
subject << end_event
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
describe "tagging a call" do
|
|
124
|
+
it 'with a single Symbol' do
|
|
125
|
+
lambda {
|
|
126
|
+
subject.tag :moderator
|
|
127
|
+
}.should_not raise_error
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'with multiple Symbols' do
|
|
131
|
+
lambda {
|
|
132
|
+
subject.tag :moderator
|
|
133
|
+
subject.tag :female
|
|
134
|
+
}.should_not raise_error
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'with a non-Symbol, non-String object' do
|
|
138
|
+
bad_objects = [123, Object.new, 888.88, nil, true, false, StringIO.new]
|
|
139
|
+
bad_objects.each do |bad_object|
|
|
140
|
+
lambda {
|
|
141
|
+
subject.tag bad_object
|
|
142
|
+
}.should raise_error ArgumentError
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "#remove_tag" do
|
|
148
|
+
subject.tag :moderator
|
|
149
|
+
subject.tag :female
|
|
150
|
+
subject.remove_tag :female
|
|
151
|
+
subject.tag :male
|
|
152
|
+
subject.tags.should == [:moderator, :male]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe "#tagged_with?" do
|
|
156
|
+
it 'with one tag' do
|
|
157
|
+
subject.tag :guest
|
|
158
|
+
subject.tagged_with?(:guest).should be true
|
|
159
|
+
subject.tagged_with?(:authorized).should be false
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it 'with many tags' do
|
|
163
|
+
subject.tag :customer
|
|
164
|
+
subject.tag :authorized
|
|
165
|
+
subject.tagged_with?(:customer).should be true
|
|
166
|
+
subject.tagged_with?(:authorized).should be true
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
describe "#write_command" do
|
|
171
|
+
let(:mock_command) { flexmock('Command') }
|
|
172
|
+
|
|
173
|
+
it "should asynchronously write the command to the Punchblock connection" do
|
|
174
|
+
mock_client = flexmock('Client')
|
|
175
|
+
flexmock(subject).should_receive(:client).once.and_return mock_client
|
|
176
|
+
mock_client.should_receive(:execute_command).once.with(mock_command, :call_id => subject.id).and_return true
|
|
177
|
+
subject.write_command mock_command
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
describe "with a hungup call" do
|
|
181
|
+
before do
|
|
182
|
+
flexmock(subject).should_receive(:active?).and_return(false)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "should raise a Hangup exception" do
|
|
186
|
+
lambda { subject.write_command mock_command }.should raise_error(Hangup)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe "if the command is a Hangup" do
|
|
190
|
+
let(:mock_command) { Punchblock::Command::Hangup.new }
|
|
191
|
+
|
|
192
|
+
it "should not raise a Hangup exception" do
|
|
193
|
+
lambda { subject.write_command mock_command }.should_not raise_error
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
describe '#write_and_await_response' do
|
|
200
|
+
let(:message) { Punchblock::Command::Accept.new }
|
|
201
|
+
let(:response) { :foo }
|
|
202
|
+
|
|
203
|
+
before do
|
|
204
|
+
flexmock(message).should_receive(:execute!).and_return true
|
|
205
|
+
message.response = response
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "writes a command to the call" do
|
|
209
|
+
flexmock(subject).should_receive(:write_command).once.with(message)
|
|
210
|
+
subject.write_and_await_response message
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "adds the command to the registry" do
|
|
214
|
+
subject.write_and_await_response message
|
|
215
|
+
subject.commands.should_not be_empty
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "blocks until a response is received" do
|
|
219
|
+
slow_command = Punchblock::Command::Dial.new
|
|
220
|
+
Thread.new do
|
|
221
|
+
sleep 0.5
|
|
222
|
+
slow_command.response = response
|
|
223
|
+
end
|
|
224
|
+
starting_time = Time.now
|
|
225
|
+
subject.write_and_await_response slow_command
|
|
226
|
+
(Time.now - starting_time).should >= 0.5
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
describe "with a successful response" do
|
|
230
|
+
it "returns the executed command" do
|
|
231
|
+
subject.write_and_await_response(message).should be message
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
describe "with an error response" do
|
|
236
|
+
let(:response) { Exception.new }
|
|
237
|
+
|
|
238
|
+
it "raises the error" do
|
|
239
|
+
lambda { subject.write_and_await_response message }.should raise_error Exception
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
describe "basic control commands" do
|
|
245
|
+
include FlexMock::ArgumentTypes
|
|
246
|
+
|
|
247
|
+
def expect_message_waiting_for_response(message)
|
|
248
|
+
flexmock(subject).should_receive(:write_and_await_response).once.with(message).and_return(message)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
describe '#accept' do
|
|
252
|
+
describe "with no headers" do
|
|
253
|
+
it 'should send an Accept message' do
|
|
254
|
+
expect_message_waiting_for_response Punchblock::Command::Accept.new
|
|
255
|
+
subject.accept
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
describe "with headers set" do
|
|
260
|
+
it 'should send an Accept message with the correct headers' do
|
|
261
|
+
headers = {:foo => 'bar'}
|
|
262
|
+
expect_message_waiting_for_response Punchblock::Command::Accept.new(:headers => headers)
|
|
263
|
+
subject.accept headers
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
describe '#answer' do
|
|
269
|
+
describe "with no headers" do
|
|
270
|
+
it 'should send an Answer message' do
|
|
271
|
+
expect_message_waiting_for_response Punchblock::Command::Answer.new
|
|
272
|
+
subject.answer
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
describe "with headers set" do
|
|
277
|
+
it 'should send an Answer message with the correct headers' do
|
|
278
|
+
headers = {:foo => 'bar'}
|
|
279
|
+
expect_message_waiting_for_response Punchblock::Command::Answer.new(:headers => headers)
|
|
280
|
+
subject.answer headers
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
describe '#reject' do
|
|
286
|
+
describe "with a reason given" do
|
|
287
|
+
it 'should send a Reject message with the correct reason' do
|
|
288
|
+
expect_message_waiting_for_response Punchblock::Command::Reject.new(:reason => :decline)
|
|
289
|
+
subject.reject :decline
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
describe "with no reason given" do
|
|
294
|
+
it 'should send a Reject message with the reason busy' do
|
|
295
|
+
expect_message_waiting_for_response Punchblock::Command::Reject.new(:reason => :busy)
|
|
296
|
+
subject.reject
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
describe "with no headers" do
|
|
301
|
+
it 'should send a Reject message' do
|
|
302
|
+
expect_message_waiting_for_response on { |c| c.is_a?(Punchblock::Command::Reject) && c.headers_hash == {} }
|
|
303
|
+
subject.reject
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
describe "with headers set" do
|
|
308
|
+
it 'should send a Hangup message with the correct headers' do
|
|
309
|
+
headers = {:foo => 'bar'}
|
|
310
|
+
expect_message_waiting_for_response on { |c| c.is_a?(Punchblock::Command::Reject) && c.headers_hash == headers }
|
|
311
|
+
subject.reject nil, headers
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
describe "#hangup!" do
|
|
317
|
+
describe "if the call is not active" do
|
|
318
|
+
before do
|
|
319
|
+
flexmock(subject).should_receive(:active?).and_return false
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "should do nothing and return false" do
|
|
323
|
+
flexmock(subject).should_receive(:write_and_await_response).never
|
|
324
|
+
subject.hangup!.should be false
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
describe "if the call is active" do
|
|
329
|
+
it "should mark the call inactive" do
|
|
330
|
+
expect_message_waiting_for_response Punchblock::Command::Hangup.new
|
|
331
|
+
subject.hangup!
|
|
332
|
+
subject.should_not be_active
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
describe "with no headers" do
|
|
336
|
+
it 'should send a Hangup message' do
|
|
337
|
+
expect_message_waiting_for_response Punchblock::Command::Hangup.new
|
|
338
|
+
subject.hangup!
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
describe "with headers set" do
|
|
343
|
+
it 'should send a Hangup message with the correct headers' do
|
|
344
|
+
headers = {:foo => 'bar'}
|
|
345
|
+
expect_message_waiting_for_response Punchblock::Command::Hangup.new(:headers => headers)
|
|
346
|
+
subject.hangup! headers
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
describe "#join" do
|
|
353
|
+
let(:other_call_id) { rand }
|
|
354
|
+
|
|
355
|
+
it "should mark the call inactive" do
|
|
356
|
+
expect_message_waiting_for_response Punchblock::Command::Join.new :other_call_id => other_call_id
|
|
357
|
+
subject.join other_call_id
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
describe "#execute_controller" do
|
|
362
|
+
let(:latch) { CountDownLatch.new 1 }
|
|
363
|
+
let(:mock_controller) { flexmock 'CallController' }
|
|
364
|
+
|
|
365
|
+
before do
|
|
366
|
+
flexmock subject, :write_and_await_response => true
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it "should call #execute on the controller instance" do
|
|
370
|
+
flexmock(CallController).should_receive(:exec).once.with mock_controller
|
|
371
|
+
subject.execute_controller mock_controller, latch
|
|
372
|
+
latch.wait(3).should be_true
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
it "should hangup the call after all controllers have executed" do
|
|
376
|
+
flexmock(CallController).should_receive(:exec).once.with mock_controller
|
|
377
|
+
subject.should_receive(:hangup!).once
|
|
378
|
+
subject.execute_controller mock_controller, latch
|
|
379
|
+
latch.wait(3).should be_true
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
describe Call::CommandRegistry do
|
|
385
|
+
subject { Call::CommandRegistry.new }
|
|
386
|
+
|
|
387
|
+
it { should be_empty }
|
|
388
|
+
|
|
389
|
+
describe "#<<" do
|
|
390
|
+
it "should add a command to the registry" do
|
|
391
|
+
subject << :foo
|
|
392
|
+
subject.should_not be_empty
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
describe "#delete" do
|
|
397
|
+
it "should remove a command from the registry" do
|
|
398
|
+
subject << :foo
|
|
399
|
+
subject.should_not be_empty
|
|
400
|
+
subject.delete :foo
|
|
401
|
+
subject.should be_empty
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
describe "#terminate" do
|
|
406
|
+
let :commands do
|
|
407
|
+
[
|
|
408
|
+
Punchblock::Command::Answer.new,
|
|
409
|
+
Punchblock::Command::Answer.new
|
|
410
|
+
]
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it "should set each command's response to an instance of Adhearsion::Hangup if it doesn't already have a response" do
|
|
414
|
+
finished_command = Punchblock::Command::Answer.new
|
|
415
|
+
finished_command.request!
|
|
416
|
+
finished_command.response = :foo
|
|
417
|
+
subject << finished_command
|
|
418
|
+
commands.each do |command|
|
|
419
|
+
command.request!
|
|
420
|
+
subject << command
|
|
421
|
+
end
|
|
422
|
+
subject.terminate
|
|
423
|
+
commands.each do |command|
|
|
424
|
+
command.response.should be_a Hangup
|
|
425
|
+
end
|
|
426
|
+
finished_command.response.should == :foo
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
describe Call::Registry do
|
|
432
|
+
it "should set a value and retrieve it" do
|
|
433
|
+
Adhearsion::Call::Registry[:test_value] = '123'
|
|
434
|
+
Adhearsion::Call::Registry[:test_value].should == '123'
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
describe Calls do
|
|
5
|
+
before { Adhearsion.active_calls.clear! }
|
|
6
|
+
|
|
7
|
+
let(:call) { Adhearsion::Call.new mock_offer }
|
|
8
|
+
|
|
9
|
+
it 'can create a call and add it to the active calls' do
|
|
10
|
+
Adhearsion.active_calls.any?.should == false
|
|
11
|
+
call = Adhearsion.active_calls.from_offer mock_offer
|
|
12
|
+
call.should be_a Adhearsion::Call
|
|
13
|
+
Adhearsion.active_calls.size.should == 1
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it '#size should return the size of the collection' do
|
|
17
|
+
subject.size.should == 0
|
|
18
|
+
subject << call
|
|
19
|
+
subject.size.should == 1
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it '#remove_inactive_call should delete the call in the Hash' do
|
|
23
|
+
number_of_calls = 10
|
|
24
|
+
calls = Array.new(number_of_calls) { Adhearsion::Call.new mock_offer }
|
|
25
|
+
calls.each { |call| subject << call }
|
|
26
|
+
|
|
27
|
+
deleted_call = calls[number_of_calls / 2]
|
|
28
|
+
subject.remove_inactive_call deleted_call
|
|
29
|
+
subject.size.should == number_of_calls - 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it '#find should pull the Call from the Hash using the id' do
|
|
33
|
+
subject << call
|
|
34
|
+
subject.find(call.id).should be call
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "finding calls by a tag" do
|
|
38
|
+
calls = Array.new(3) { Adhearsion::Call.new mock_offer }
|
|
39
|
+
calls.each { |call| subject << call }
|
|
40
|
+
|
|
41
|
+
tagged_call = calls.last
|
|
42
|
+
tagged_call.tag :moderator
|
|
43
|
+
|
|
44
|
+
subject.with_tag(:moderator).should == [tagged_call]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|