sevenscale-adhearsion 0.7.1003 → 0.8.0

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 (149) hide show
  1. data/CHANGELOG +8 -2
  2. data/EVENTS +11 -0
  3. data/Rakefile +92 -26
  4. data/adhearsion.gemspec +131 -23
  5. data/app_generators/ahn/ahn_generator.rb +21 -7
  6. data/app_generators/ahn/templates/.ahnrc +10 -4
  7. data/app_generators/ahn/templates/Rakefile +7 -2
  8. data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +15 -0
  9. data/app_generators/ahn/templates/components/disabled/HOW_TO_ENABLE +7 -0
  10. data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +47 -0
  11. data/app_generators/ahn/templates/components/disabled/stomp_gateway/config.yml +12 -0
  12. data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +34 -0
  13. data/app_generators/ahn/templates/components/simon_game/{lib/simon_game.rb → simon_game.rb} +14 -19
  14. data/app_generators/ahn/templates/config/startup.rb +3 -6
  15. data/app_generators/ahn/templates/dialplan.rb +2 -3
  16. data/app_generators/ahn/templates/events.rb +32 -6
  17. data/bin/jahn +10 -0
  18. data/examples/asterisk_manager_interface/standalone.rb +51 -0
  19. data/lib/adhearsion/cli.rb +140 -23
  20. data/lib/adhearsion/component_manager/component_tester.rb +55 -0
  21. data/lib/adhearsion/component_manager/spec_framework.rb +24 -0
  22. data/lib/adhearsion/component_manager.rb +169 -238
  23. data/lib/adhearsion/events_support.rb +59 -237
  24. data/lib/adhearsion/{core_extensions → foundation}/all.rb +0 -0
  25. data/lib/adhearsion/{blank_slate.rb → foundation/blank_slate.rb} +0 -0
  26. data/lib/adhearsion/{core_extensions → foundation}/custom_daemonizer.rb +0 -0
  27. data/lib/adhearsion/foundation/event_socket.rb +203 -0
  28. data/lib/adhearsion/foundation/future_resource.rb +36 -0
  29. data/lib/adhearsion/{core_extensions → foundation}/global.rb +0 -0
  30. data/lib/adhearsion/{core_extensions → foundation}/metaprogramming.rb +0 -0
  31. data/lib/adhearsion/foundation/numeric.rb +13 -0
  32. data/lib/adhearsion/foundation/pseudo_guid.rb +10 -0
  33. data/lib/adhearsion/{core_extensions → foundation}/relationship_properties.rb +2 -0
  34. data/lib/adhearsion/foundation/string.rb +26 -0
  35. data/lib/adhearsion/foundation/synchronized_hash.rb +96 -0
  36. data/lib/adhearsion/{core_extensions → foundation}/thread_safety.rb +0 -0
  37. data/lib/adhearsion/host_definitions.rb +5 -1
  38. data/lib/adhearsion/initializer/asterisk.rb +33 -11
  39. data/lib/adhearsion/initializer/configuration.rb +58 -6
  40. data/lib/adhearsion/initializer/database.rb +3 -46
  41. data/lib/adhearsion/initializer/drb.rb +9 -3
  42. data/lib/adhearsion/initializer/freeswitch.rb +3 -3
  43. data/lib/adhearsion/initializer/rails.rb +1 -1
  44. data/lib/adhearsion/initializer.rb +213 -87
  45. data/lib/adhearsion/tasks/deprecations.rb +59 -0
  46. data/lib/adhearsion/tasks.rb +2 -1
  47. data/lib/adhearsion/version.rb +3 -3
  48. data/lib/adhearsion/voip/asterisk/agi_server.rb +6 -6
  49. data/lib/adhearsion/voip/asterisk/commands.rb +100 -2
  50. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +1754 -0
  51. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +286 -0
  52. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +78 -0
  53. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +87 -0
  54. data/lib/adhearsion/voip/asterisk/manager_interface.rb +562 -0
  55. data/lib/adhearsion/voip/asterisk/super_manager.rb +19 -0
  56. data/lib/adhearsion/voip/asterisk.rb +1 -8
  57. data/lib/adhearsion/voip/call.rb +5 -1
  58. data/lib/adhearsion/voip/dial_plan.rb +74 -61
  59. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +1 -1
  60. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +2 -6
  61. data/lib/adhearsion/voip/dsl/numerical_string.rb +2 -2
  62. data/lib/adhearsion/voip/freeswitch/oes_server.rb +2 -2
  63. data/lib/adhearsion.rb +16 -11
  64. data/lib/theatre/README.markdown +64 -0
  65. data/lib/theatre/callback_definition_loader.rb +84 -0
  66. data/lib/theatre/guid.rb +23 -0
  67. data/lib/theatre/invocation.rb +121 -0
  68. data/lib/theatre/namespace_manager.rb +153 -0
  69. data/lib/theatre/version.rb +2 -0
  70. data/lib/theatre.rb +151 -0
  71. metadata +60 -147
  72. data/Manifest.txt +0 -151
  73. data/README.txt +0 -5
  74. data/ahn_generators/component/USAGE +0 -5
  75. data/ahn_generators/component/component_generator.rb +0 -57
  76. data/ahn_generators/component/templates/configuration.rb +0 -0
  77. data/ahn_generators/component/templates/lib/lib.rb.erb +0 -3
  78. data/ahn_generators/component/templates/test/test.rb.erb +0 -12
  79. data/ahn_generators/component/templates/test/test_helper.rb +0 -14
  80. data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
  81. data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +0 -14
  82. data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +0 -31
  83. data/lib/adhearsion/core_extensions/array.rb +0 -0
  84. data/lib/adhearsion/core_extensions/guid.rb +0 -5
  85. data/lib/adhearsion/core_extensions/hash.rb +0 -0
  86. data/lib/adhearsion/core_extensions/numeric.rb +0 -4
  87. data/lib/adhearsion/core_extensions/proc.rb +0 -0
  88. data/lib/adhearsion/core_extensions/pseudo_uuid.rb +0 -11
  89. data/lib/adhearsion/core_extensions/publishable.rb +0 -73
  90. data/lib/adhearsion/core_extensions/string.rb +0 -26
  91. data/lib/adhearsion/core_extensions/thread.rb +0 -13
  92. data/lib/adhearsion/core_extensions/time.rb +0 -0
  93. data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
  94. data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
  95. data/lib/adhearsion/distributed/gateways/rest_gateway.rb +0 -9
  96. data/lib/adhearsion/distributed/gateways/soap_gateway.rb +0 -9
  97. data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +0 -9
  98. data/lib/adhearsion/distributed/peer_finder.rb +0 -0
  99. data/lib/adhearsion/distributed/remote_cli.rb +0 -0
  100. data/lib/adhearsion/hooks.rb +0 -57
  101. data/lib/adhearsion/initializer/paths.rb +0 -55
  102. data/lib/adhearsion/voip/asterisk/ami/actions.rb +0 -238
  103. data/lib/adhearsion/voip/asterisk/ami/machine.rb +0 -871
  104. data/lib/adhearsion/voip/asterisk/ami/machine.rl +0 -109
  105. data/lib/adhearsion/voip/asterisk/ami/parser.rb +0 -262
  106. data/lib/adhearsion/voip/asterisk/ami.rb +0 -147
  107. data/spec/fixtures/dialplan.rb +0 -3
  108. data/spec/initializer/test_configuration.rb +0 -267
  109. data/spec/initializer/test_loading.rb +0 -162
  110. data/spec/initializer/test_paths.rb +0 -43
  111. data/spec/sample.rb +0 -9
  112. data/spec/silence.rb +0 -10
  113. data/spec/test_ahn_command.rb +0 -149
  114. data/spec/test_code_quality.rb +0 -87
  115. data/spec/test_component_manager.rb +0 -97
  116. data/spec/test_constants.rb +0 -8
  117. data/spec/test_drb.rb +0 -104
  118. data/spec/test_events.rb +0 -136
  119. data/spec/test_helper.rb +0 -106
  120. data/spec/test_hooks.rb +0 -15
  121. data/spec/test_host_definitions.rb +0 -79
  122. data/spec/test_initialization.rb +0 -124
  123. data/spec/test_logging.rb +0 -80
  124. data/spec/test_relationship_properties.rb +0 -54
  125. data/spec/voip/asterisk/ami_response_definitions.rb +0 -23
  126. data/spec/voip/asterisk/config_file_generators/test_agents.rb +0 -253
  127. data/spec/voip/asterisk/config_file_generators/test_queues.rb +0 -325
  128. data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +0 -306
  129. data/spec/voip/asterisk/menu_command/test_calculated_match.rb +0 -111
  130. data/spec/voip/asterisk/menu_command/test_matchers.rb +0 -98
  131. data/spec/voip/asterisk/mock_ami_server.rb +0 -176
  132. data/spec/voip/asterisk/test_agi_server.rb +0 -453
  133. data/spec/voip/asterisk/test_ami.rb +0 -227
  134. data/spec/voip/asterisk/test_commands.rb +0 -2006
  135. data/spec/voip/asterisk/test_config_manager.rb +0 -129
  136. data/spec/voip/dsl/dispatcher_spec_helper.rb +0 -45
  137. data/spec/voip/dsl/test_dialing_dsl.rb +0 -268
  138. data/spec/voip/dsl/test_dispatcher.rb +0 -82
  139. data/spec/voip/dsl/test_parser.rb +0 -87
  140. data/spec/voip/freeswitch/test_basic_connection_manager.rb +0 -39
  141. data/spec/voip/freeswitch/test_inbound_connection_manager.rb +0 -39
  142. data/spec/voip/freeswitch/test_oes_server.rb +0 -9
  143. data/spec/voip/test_call_routing.rb +0 -127
  144. data/spec/voip/test_dialplan_manager.rb +0 -442
  145. data/spec/voip/test_numerical_string.rb +0 -48
  146. data/spec/voip/test_phone_number.rb +0 -36
  147. data/test/test_ahn_generator.rb +0 -59
  148. data/test/test_component_generator.rb +0 -52
  149. data/test/test_generator_helper.rb +0 -20
@@ -1,325 +0,0 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. .. .. test_helper])
2
- require 'adhearsion/voip/asterisk/config_generators/queues.conf'
3
-
4
- context "The queues.conf config file generator" do
5
-
6
- include QueuesConfigFileGeneratorTestHelper
7
-
8
- attr_reader :queues
9
- before:each do
10
- reset_queues!
11
- end
12
-
13
- test 'should set autofill=yes by default' do
14
- generated_config_should_have_pair :autofill => 'yes'
15
- end
16
-
17
- test 'should have a [general] section' do
18
- queues.conf.should.include "[general]\n"
19
- end
20
-
21
- test 'should yield a Queues object in its constructor' do
22
- Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Queues.new do |config|
23
- config.should.be.kind_of Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Queues
24
- end
25
- end
26
-
27
- test 'should add the warning message to the to_s output' do
28
- queues.conf.should =~ /^\s*;.{10}/
29
- end
30
-
31
- end
32
-
33
- context "The queues.conf config file queues's QueueDefinition" do
34
-
35
- include QueuesConfigFileGeneratorTestHelper
36
-
37
- attr_reader :queues
38
- before:each do
39
- reset_queues!
40
- end
41
-
42
- test 'should include [queue_name]' do
43
- name_of_queue = "leet_hax0rz"
44
- queues.queue(name_of_queue).to_s.should.include "[#{name_of_queue}]"
45
- end
46
-
47
- test '#member should create a valid Agent "channel driver" to the member definition list' do
48
- sample_queue = queues.queue "sales" do |sales|
49
- sales.member 123
50
- sales.member "Jay"
51
- sales.member 'SIP/jay-desk-650'
52
- sales.member 'IAX2/12345@voipms/15554443333'
53
- end
54
- sample_queue.members.should == %w[Agent/123 Agent/Jay SIP/jay-desk-650 IAX2/12345@voipms/15554443333]
55
- end
56
-
57
- test 'should automatically enable the two AMI-related events' do
58
- @queues = queues.queue 'name'
59
- generated_config_should_have_pair :eventwhencalled => 'vars'
60
- generated_config_should_have_pair :eventmemberstatus => 'yes'
61
- end
62
-
63
- test '#strategy should only allow the pre-defined settings' do
64
- [:ringall, :roundrobin, :leastrecent, :fewestcalls, :random, :rrmemory].each do |strategy|
65
- the_following_code {
66
- q = queues.queue 'foobar'
67
- q.strategy strategy
68
- }.should.not.raise
69
- end
70
-
71
- the_following_code {
72
- queues.queue('qwerty').strategy :this_is_not_a_valid_strategy
73
- }.should.raise ArgumentError
74
-
75
- end
76
-
77
- test '#sound_files raises an argument error when it sees an unrecognized key' do
78
- the_following_code {
79
- queues.queue 'foobar' do |foobar|
80
- foobar.sound_files \
81
- :you_are_next => rand.to_s,
82
- :there_are => rand.to_s,
83
- :calls_waiting => rand.to_s,
84
- :hold_time => rand.to_s,
85
- :minutes => rand.to_s,
86
- :seconds => rand.to_s,
87
- :thank_you => rand.to_s,
88
- :less_than => rand.to_s,
89
- :report_hold => rand.to_s,
90
- :periodic_announcement => rand.to_s
91
- end
92
- }.should.not.raise
93
-
94
- [:x_you_are_next, :x_there_are, :x_calls_waiting, :x_hold_time, :x_minutes,
95
- :x_seconds, :x_thank_you, :x_less_than, :x_report_hold, :x_periodic_announcement].each do |bad_key|
96
- the_following_code {
97
- queues.queue("foobar") do |foobar|
98
- foobar.sound_files bad_key => rand.to_s
99
- end
100
- }.should.raise ArgumentError
101
- end
102
-
103
- end
104
-
105
- end
106
-
107
- context "The private, helper methods in QueueDefinition" do
108
-
109
- include QueuesConfigFileGeneratorTestHelper
110
-
111
- attr_reader :queue
112
- before:each do
113
- reset_queues!
114
- @queue = @queues.queue "doesn't matter"
115
- end
116
-
117
- test '#boolean should convert a boolean into "yes" or "no"' do
118
- mock_of_properties = flexmock "mock of the properties instance variable of a QueueDefinition"
119
- mock_of_properties.should_receive(:[]=).once.with("icanhascheezburger", "yes")
120
- flexmock(queue).should_receive(:properties).and_return mock_of_properties
121
- queue.send(:boolean, "icanhascheezburger" => true)
122
- end
123
-
124
- test '#int should raise an argument error when its argument is not Numeric' do
125
- the_following_code {
126
- queue.send(:int, "eisley" => :i_break_things!)
127
- }.should.raise ArgumentError
128
- end
129
-
130
- test '#int should coerce a String into a Numeric if possible' do
131
- mock_of_properties = flexmock "mock of the properties instance variable of a QueueDefinition"
132
- mock_of_properties.should_receive(:[]=).once.with("chimpanzee", 1337)
133
- flexmock(queue).should_receive(:properties).and_return mock_of_properties
134
- queue.send(:int, "chimpanzee" => "1337")
135
- end
136
-
137
- test '#string should add the argument directly to the properties' do
138
- mock_of_properties = flexmock "mock of the properties instance variable of a QueueDefinition"
139
- mock_of_properties.should_receive(:[]=).once.with("eins", "zwei")
140
- flexmock(queue).should_receive(:properties).and_return mock_of_properties
141
- queue.send(:string, "eins" => "zwei")
142
- end
143
-
144
- test '#one_of() should add its successful match to the properties attribute' do
145
- mock_properties = flexmock "mock of the properties instance variable of a QueueDefinition"
146
- mock_properties.should_receive(:[]=).once.with(:doesnt_matter, 5)
147
- flexmock(queue).should_receive(:properties).once.and_return mock_properties
148
-
149
- queue.send(:one_of, 1..100, :doesnt_matter => 5)
150
- end
151
-
152
- test "one_of() should convert booleans to yes/no" do
153
- mock_properties = flexmock "mock of the properties instance variable of a QueueDefinition"
154
- mock_properties.should_receive(:[]=).once.with(:doesnt_matter, 'yes')
155
- flexmock(queue).should_receive(:properties).once.and_return mock_properties
156
- queue.send(:one_of, [true, false, :strict], :doesnt_matter => true)
157
-
158
- mock_properties = flexmock "mock of the properties instance variable of a QueueDefinition"
159
- mock_properties.should_receive(:[]=).once.with(:doesnt_matter, :strict)
160
- flexmock(queue).should_receive(:properties).once.and_return mock_properties
161
- queue.send(:one_of, [true, false, :strict], :doesnt_matter => :strict)
162
-
163
- mock_properties = flexmock "mock of the properties instance variable of a QueueDefinition"
164
- mock_properties.should_receive(:[]=).once.with(:doesnt_matter, 'no')
165
- flexmock(queue).should_receive(:properties).once.and_return mock_properties
166
- queue.send(:one_of, [true, false, :strict], :doesnt_matter => false)
167
- end
168
-
169
- test '#one_of() should raise an ArgumentError if a value is not in the criteria' do
170
- the_following_code {
171
- queue.send(:one_of, [:jay, :thomas, :phillips], :sister => :jill)
172
- }.should.raise ArgumentError
173
- end
174
- end
175
-
176
- context 'The queues.conf config file generator when ran against a really big example' do
177
-
178
- include QueuesConfigFileGeneratorTestHelper
179
-
180
- attr_reader :queues, :default_config
181
- before:each do
182
- reset_queues!
183
- @default_config = default_config = <<-CONFIG
184
- [general]
185
- persistentmembers=yes
186
- autofill=yes
187
- monitor-type=MixMonitor
188
-
189
- [markq]
190
- musicclass=default
191
- announce=queue-markq
192
- strategy=ringall
193
- servicelevel=60
194
- context=qoutcon
195
- timeout=15
196
- retry=5
197
- weight=0
198
- wrapuptime=15
199
- autofill=yes
200
- autopause=yes
201
- maxlen=0
202
- setinterfacevar=yes
203
- announce-frequency=90
204
- periodic-announce-frequency=60
205
- announce-holdtime=once
206
- announce-round-seconds=10
207
- queue-youarenext=queue-youarenext
208
- queue-thereare=queue-thereare
209
- queue-callswaiting=queue-callswaiting
210
- queue-holdtime=queue-holdtime
211
- queue-minutes=queue-minutes
212
- queue-seconds=queue-seconds
213
- queue-thankyou=queue-thankyou
214
- queue-lessthan=queue-less-than
215
- queue-reporthold=queue-reporthold
216
- periodic-announce=queue-periodic-announce
217
- monitor-format=gsm
218
- monitor-type=MixMonitor
219
- joinempty=yes
220
- leavewhenempty=yes
221
- eventwhencalled=vars
222
- eventmemberstatus=yes
223
- reportholdtime=no
224
- ringinuse=no
225
- memberdelay=0
226
- timeoutrestart=no
227
-
228
- member => Zap/1
229
- member => Agent/007
230
- CONFIG
231
- end
232
-
233
- test "a sample config with multiple queues" do
234
-
235
- generated = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Queues.new do |config|
236
- config.persistent_members true
237
- config.monitor_type :mix_monitor
238
-
239
- config.queue 'markq' do |markq|
240
- markq.music_class :default
241
- markq.play_on_connect 'queue-markq'
242
- markq.strategy :ringall
243
- markq.service_level 60
244
- markq.exit_to_context_on_digit_press 'qoutcon'
245
- markq.ring_timeout 15
246
- markq.retry_after_waiting 5
247
- markq.weight 0
248
- markq.wrapup_time 15
249
- markq.autopause true
250
- markq.maximum_length 0
251
- markq.queue_status_announce_frequency 90
252
- markq.announce_hold_time :once
253
- markq.announce_round_seconds 10
254
- markq.sound_files \
255
- :you_are_next => "queue-youarenext",
256
- :there_are => "queue-thereare",
257
- :calls_waiting => "queue-callswaiting",
258
- :hold_time => "queue-holdtime",
259
- :minutes => "queue-minutes",
260
- :seconds => "queue-seconds",
261
- :thank_you => "queue-thankyou",
262
- :less_than => "queue-less-than",
263
- :report_hold => "queue-reporthold"
264
- markq.periodically_announce "queue-periodic-announce"
265
- markq.monitor_format :gsm
266
- markq.monitor_type :mix_monitor
267
- markq.join_empty true
268
- markq.leave_when_empty true
269
- markq.report_hold_time false
270
- markq.ring_in_use false
271
- markq.delay_connection_by 0
272
- markq.timeout_restart false
273
-
274
- markq.member 'Zap/1'
275
- markq.member '007'
276
- end
277
- end
278
-
279
- cleaned_up_default_config = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::
280
- AsteriskConfigGenerator.create_sanitary_hash_from(default_config)
281
-
282
- cleaned_up_generated_config = generated.to_sanitary_hash
283
-
284
- cleaned_up_generated_config.should == cleaned_up_default_config
285
- end
286
-
287
- end
288
-
289
- context "ConfigFileGeneratorTestHelper" do
290
-
291
- include QueuesConfigFileGeneratorTestHelper
292
-
293
- attr_reader :queues
294
-
295
- test "generated_config_has_pair() works properly" do
296
- @queues = flexmock "A fake queues with just one pair", :to_s => "foo=bar"
297
- generated_config_has_pair(:foo => "bar").should.be true
298
-
299
- @queues = flexmock "A fake queues with just one pair", :to_s => "[general]\n\nqaz=qwerty\nagent => 1,2,3"
300
- generated_config_has_pair(:qaz => "qwerty").should.be true
301
- generated_config_has_pair(:foo => "bar").should.be false
302
- end
303
-
304
- end
305
-
306
- BEGIN {
307
- module QueuesConfigFileGeneratorTestHelper
308
-
309
- def reset_queues!
310
- @queues = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Queues.new
311
- end
312
-
313
- def generated_config_should_have_pair(pair)
314
- generated_config_has_pair(pair).should.equal true
315
- end
316
-
317
- def generated_config_has_pair(pair)
318
- queues.to_s.grep(/=[^>]/).each do |line|
319
- key, value = line.strip.split('=')
320
- return true if pair == {key.to_sym => value}
321
- end
322
- false
323
- end
324
- end
325
- }
@@ -1,306 +0,0 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. .. .. test_helper])
2
- require 'adhearsion/voip/asterisk/config_generators/voicemail.conf'
3
-
4
- context 'Basic requirements of the Voicemail config generator' do
5
- attr_reader :config
6
- before :each do
7
- @config = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail.new
8
- end
9
-
10
- test 'should have a [general] context' do
11
- config.to_sanitary_hash.has_key?('[general]').should.equal true
12
- end
13
-
14
- test 'should set the format to "wav" by default in the general section' do
15
- config.to_sanitary_hash['[general]'].should.include 'format=wav'
16
- end
17
-
18
- test 'an exception should be raised if the context name is "general"' do
19
- the_following_code {
20
- config.context(:general) {|_|}
21
- }.should.raise ArgumentError
22
- end
23
-
24
- end
25
-
26
- context 'Defining recording-related settings of the Voicemail config file' do
27
-
28
- attr_reader :recordings
29
- before :each do
30
- @recordings = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail::RecordingDefinition.new
31
- end
32
-
33
- test 'the recordings setting setter' do
34
- Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail.new.recordings.should.be.kind_of? recordings.class
35
- end
36
-
37
- test 'recordings format should only allow a few options' do
38
- the_following_code {
39
- recordings.format :wav
40
- recordings.format :wav49
41
- recordings.format :gsm
42
- }.should.not.raise
43
-
44
- the_following_code {
45
- recordings.format :lolcats
46
- }.should.raise ArgumentError
47
- end
48
-
49
- end
50
-
51
- context 'Defining email-related Voicemail settings' do
52
-
53
- attr_reader :email
54
- before :each do
55
- @email = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail::EmailDefinition.new
56
- end
57
-
58
- test 'the [] operator is overloaded to return conveniences for the body() and subject() methods' do
59
- variables = %{#{email[:name]} #{email[:mailbox]} #{email[:date]} #{email[:duration]} } +
60
- %{#{email[:message_number]} #{email[:caller_id]} #{email[:caller_id_number]} } +
61
- %{#{email[:caller_id_name]}}
62
- formatted = %{${VM_NAME} ${VM_MAILBOX} ${VM_DATE} ${VM_DUR} ${VM_MSGNUM} ${VM_CALLERID} ${VM_CIDNUM} ${VM_CIDNAME}}
63
- email.body variables
64
- email.subject variables
65
- email.properties[:emailbody].should == formatted
66
- email.properties[:emailsubject].should == formatted
67
- end
68
-
69
- test 'when defining a body, newlines should be escaped and carriage returns removed' do
70
- unescaped, escaped = "one\ntwo\n\r\r\nthree\n\n\n", 'one\ntwo\n\nthree\n\n\n'
71
- email.body unescaped
72
- email.properties[:emailbody].should == escaped
73
- end
74
-
75
- test 'the body must not be allowed to exceed 512 characters' do
76
- the_following_code {
77
- email.body "X" * 512
78
- }.should.not.raise ArgumentError
79
-
80
- the_following_code {
81
- email.body "X" * 513
82
- }.should.raise ArgumentError
83
-
84
- the_following_code {
85
- email.body "X" * 1000
86
- }.should.raise ArgumentError
87
- end
88
-
89
- test 'should store away the email command properly' do
90
- mail_command = "/usr/sbin/sendmail -f alice@wonderland.com -t"
91
- email.command mail_command
92
- email.properties[:mailcmd].should == mail_command
93
- end
94
-
95
- end
96
-
97
- context 'A mailbox definition' do
98
- attr_reader :mailbox
99
- before :each do
100
- @mailbox = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail::ContextDefinition::MailboxDefinition.new("123")
101
- end
102
-
103
- test 'setting the name should be reflected in the to_hash form of the definition' do
104
- mailbox.name "Foobar"
105
- mailbox.to_hash[:name].should == "Foobar"
106
- end
107
-
108
- test 'setting the pin_number should be reflected in the to_hash form of the definition' do
109
- mailbox.pin_number 555
110
- mailbox.to_hash[:pin_number].should.equal 555
111
- end
112
-
113
- test 'the mailbox number should be available in the mailbox_number getter' do
114
- Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail::ContextDefinition::MailboxDefinition.new '123'
115
- mailbox.mailbox_number.should.equal '123'
116
- end
117
-
118
- test 'an ArgumentError should be raised if the mailbox_number is not numeric' do
119
- the_following_code {
120
- Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail::ContextDefinition::MailboxDefinition.new("this is not numeric")
121
- }.should.raise ArgumentError
122
- end
123
-
124
- test 'an ArgumentError should be raised if the pin_number is not numeric' do
125
- the_following_code {
126
- mailbox.pin_number "this is not numeric"
127
- }.should.raise ArgumentError
128
- end
129
-
130
- test "the string representation should be valid" do
131
- expected = "123 => 1337,Jay Phillips,ahn@adhearsion.com"
132
- mailbox.pin_number 1337
133
- mailbox.name "Jay Phillips"
134
- mailbox.email "ahn@adhearsion.com"
135
- mailbox.to_s.should == expected
136
- end
137
-
138
- test 'should not add a trailing comma when the email is left out' do
139
- mailbox.pin_number 1337
140
- mailbox.name "Jay Phillips"
141
- mailbox.to_s.ends_with?(',').should.equal false
142
- end
143
-
144
- test 'should not add a trailing comma when the email and name is left out' do
145
- mailbox.pin_number 1337
146
- mailbox.to_s.ends_with?(',').should.equal false
147
- end
148
-
149
- end
150
-
151
- context "A Voicemail context definition" do
152
-
153
- test "should ultimately add a [] context definition to the string output" do
154
- voicemail = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail.new
155
- voicemail.context "monkeys" do |config|
156
- config.should.be.kind_of voicemail.class::ContextDefinition
157
- config.mailbox 1234 do |mailbox|
158
- mailbox.pin_number 3333
159
- mailbox.email "alice@wonderland.com"
160
- mailbox.name "Alice Little"
161
- end
162
- end
163
- voicemail.to_sanitary_hash.has_key?('[monkeys]').should.equal true
164
- end
165
-
166
- test 'should raise a LocalJumpError if no block is given' do
167
- the_following_code {
168
- Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail.new.context('lols')
169
- }.should.raise LocalJumpError
170
- end
171
-
172
- test 'its string representation should begin with a context declaration' do
173
- vm = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail.new
174
- vm.context("jay") {|_|}.to_s.starts_with?("[jay]").should.equal true
175
- end
176
-
177
- end
178
-
179
- context 'Defining Voicemail contexts with mailbox definitions' do
180
-
181
- end
182
-
183
- context 'An expansive example of the Voicemail config generator' do
184
-
185
- before :each do
186
- @employees = [
187
- {:name => "Tango", :pin_number => 7777, :mailbox_number => 10},
188
- {:name => "Echo", :pin_number => 7777, :mailbox_number => 20},
189
- {:name => "Sierra", :pin_number => 7777, :mailbox_number => 30},
190
- {:name => "Tango2", :pin_number => 7777, :mailbox_number => 40}
191
- ].map { |hash| OpenStruct.new(hash) }
192
-
193
- @groups = [
194
- {:name => "Brand New Cadillac", :pin_number => 1111, :mailbox_number => 1},
195
- {:name => "Jimmy Jazz", :pin_number => 2222, :mailbox_number => 2},
196
- {:name => "Death or Glory", :pin_number => 3333, :mailbox_number => 3},
197
- {:name => "Rudie Can't Fail", :pin_number => 4444, :mailbox_number => 4},
198
- {:name => "Spanish Bombs", :pin_number => 5555, :mailbox_number => 5}
199
- ].map { |hash| OpenStruct.new(hash) }
200
- end
201
-
202
- test 'a huge, brittle integration test' do
203
- vm = Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail.new do |voicemail|
204
- voicemail.context :default do |context|
205
- context.mailbox 123 do |mailbox|
206
- mailbox.name "Administrator"
207
- mailbox.email "jabberwocky@wonderland.com"
208
- mailbox.pin_number 9876
209
- end
210
- end
211
-
212
- voicemail.context :employees do |context|
213
- @employees.each do |employee|
214
- context.mailbox employee.mailbox_number do |mailbox|
215
- mailbox.pin_number 1337
216
- mailbox.name employee.name
217
- end
218
- end
219
- end
220
-
221
- voicemail.context :groups do |context|
222
- @groups.each do |group|
223
- context.mailbox group.mailbox_number do |mailbox|
224
- mailbox.pin_number 1337
225
- mailbox.name group.name
226
- mailbox.email "foo@qaz.org"
227
- end
228
- end
229
- end
230
-
231
- voicemail.execute_on_pin_change "/path/to/my/changer_script.rb"
232
- ############################################################################
233
- ############################################################################
234
-
235
- signature = "Your Friendly Phone System"
236
-
237
- # execute_after_email "netcat 192.168.1.2 12345"
238
- # greeting_maximum 1.minute
239
- # time_jumped_with_skip_key 3.seconds # milliseconds!
240
- # logging_in do |config|
241
- # config.maximum_attempts 3
242
- # end
243
-
244
- voicemail.recordings do |config|
245
- config.format :wav # ONCE YOU PICK A FORMAT, NEVER CHANGE IT UNLESS YOU KNOW THE CONSEQUENCES!
246
- config.allowed_length 3.seconds..5.minutes
247
- config.maximum_silence 10.seconds
248
- # config.silence_threshold 128 # wtf?
249
- end
250
-
251
- voicemail.emails do |config|
252
- config.from :name => signature, :email => "noreply@adhearsion.com"
253
- config.attach_recordings true
254
- config.command '/usr/sbin/sendmail -f alice@wonderland.com -t'
255
- config.subject "New voicemail for #{config[:name]}"
256
- config.body <<-BODY.unindent
257
- Dear #{config[:name]}:
258
-
259
- The caller #{config[:caller_id]} left you a #{config[:duration]} long voicemail
260
- (number #{config[:message_number]}) on #{config[:date]} in mailbox #{config[:mailbox]}.
261
-
262
- #{ "The recording is attached to this email.\n" if config.attach_recordings? }
263
- - #{signature}
264
- BODY
265
- end
266
- end
267
- internalized = vm.to_sanitary_hash
268
- internalized.size.should.equal 5 # general, zonemessages, default, employees, groups
269
-
270
- target_config = <<-CONFIG
271
- [general]
272
- attach=yes
273
- emailbody=Dear ${VM_NAME}:\\nThe caller ${VM_CALLERID} left you a ${VM_DUR} long voicemail\\n(number ${VM_MSGNUM}) on ${VM_DATE} in mailbox ${VM_MAILBOX}.\\nThe recording is attached to this email.\\n- Your Friendly Phone System\\n
274
- emailsubject=New voicemail for ${VM_NAME}
275
- externpass=/path/to/my/changer_script.rb
276
- format=wav
277
- fromstring=Your Friendly Phone System
278
- mailcmd=/usr/sbin/sendmail -f alice@wonderland.com -t
279
- serveremail=noreply@adhearsion.com
280
-
281
- [zonemessages]
282
- eastern=America/New_York|'vm-received' Q 'digits/at' IMp
283
- central=America/Chicago|'vm-received' Q 'digits/at' IMp
284
- central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours'
285
- military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'
286
- european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM
287
- [default]
288
- 123 => 9876,Administrator,jabberwocky@wonderland.com
289
-
290
- [employees]
291
- 10 => 1337,Tango
292
- 20 => 1337,Echo
293
- 30 => 1337,Sierra
294
- 40 => 1337,Tango2
295
-
296
- [groups]
297
- 1 => 1337,Brand New Cadillac,foo@qaz.org
298
- 2 => 1337,Jimmy Jazz,foo@qaz.org
299
- 3 => 1337,Death or Glory,foo@qaz.org
300
- 4 => 1337,Rudie Can't Fail,foo@qaz.org
301
- 5 => 1337,Spanish Bombs,foo@qaz.org
302
- CONFIG
303
- vm.to_s.grep(/^$|^[^;]/).join.strip.should == target_config.strip
304
-
305
- end
306
- end