adhearsion 1.0.1 → 1.0.2
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 +10 -0
- data/CHANGELOG +8 -0
- data/README.markdown +33 -0
- data/Rakefile +28 -68
- data/adhearsion.gemspec +19 -133
- data/app_generators/ahn/templates/Gemfile +0 -4
- data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +4 -16
- data/lib/adhearsion/cli.rb +17 -0
- data/lib/adhearsion/component_manager/component_tester.rb +1 -3
- data/lib/adhearsion/component_manager/spec_framework.rb +4 -10
- data/lib/adhearsion/foundation/object.rb +10 -0
- data/lib/adhearsion/version.rb +1 -1
- data/spec/ahn_command_spec.rb +284 -0
- data/spec/component_manager_spec.rb +292 -0
- data/spec/constants_spec.rb +8 -0
- data/spec/drb_spec.rb +65 -0
- data/spec/fixtures/dialplan.rb +3 -0
- data/spec/foundation/event_socket_spec.rb +168 -0
- data/spec/host_definitions_spec.rb +79 -0
- data/spec/initialization_spec.rb +163 -0
- data/spec/initializer/configuration_spec.rb +270 -0
- data/spec/initializer/loading_spec.rb +149 -0
- data/spec/initializer/paths_spec.rb +74 -0
- data/spec/logging_spec.rb +86 -0
- data/spec/relationship_properties_spec.rb +54 -0
- data/spec/silence.rb +10 -0
- data/spec/spec_helper.rb +101 -0
- data/spec/voip/asterisk/agi_server_spec.rb +473 -0
- data/spec/voip/asterisk/ami/ami_spec.rb +549 -0
- data/spec/voip/asterisk/ami/lexer/ami_fixtures.yml +30 -0
- data/spec/voip/asterisk/ami/lexer/lexer_story +291 -0
- data/spec/voip/asterisk/ami/lexer/lexer_story.rb +241 -0
- data/spec/voip/asterisk/ami/lexer/story_helper.rb +124 -0
- data/spec/voip/asterisk/ami/old_tests.rb +204 -0
- data/spec/voip/asterisk/ami/super_manager/super_manager_story +25 -0
- data/spec/voip/asterisk/ami/super_manager/super_manager_story.rb +15 -0
- data/spec/voip/asterisk/ami/super_manager/super_manager_story_helper.rb +5 -0
- data/spec/voip/asterisk/commands_spec.rb +2179 -0
- data/spec/voip/asterisk/config_file_generators/agents_spec.rb +251 -0
- data/spec/voip/asterisk/config_file_generators/queues_spec.rb +323 -0
- data/spec/voip/asterisk/config_file_generators/voicemail_spec.rb +306 -0
- data/spec/voip/asterisk/config_manager_spec.rb +127 -0
- data/spec/voip/asterisk/menu_command/calculated_match_spec.rb +109 -0
- data/spec/voip/asterisk/menu_command/matchers_spec.rb +97 -0
- data/spec/voip/call_routing_spec.rb +125 -0
- data/spec/voip/dialplan_manager_spec.rb +468 -0
- data/spec/voip/dsl/dialing_dsl_spec.rb +270 -0
- data/spec/voip/dsl/dispatcher_spec.rb +82 -0
- data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
- data/spec/voip/dsl/parser_spec.rb +69 -0
- data/spec/voip/freeswitch/basic_connection_manager_spec.rb +39 -0
- data/spec/voip/freeswitch/inbound_connection_manager_spec.rb +39 -0
- data/spec/voip/freeswitch/oes_server_spec.rb +9 -0
- data/spec/voip/numerical_string_spec.rb +61 -0
- data/spec/voip/phone_number_spec.rb +45 -0
- data/theatre-spec/dsl_examples/dynamic_stomp.rb +7 -0
- data/theatre-spec/dsl_examples/simple_before_call.rb +7 -0
- data/theatre-spec/dsl_spec.rb +43 -0
- data/theatre-spec/invocation_spec.rb +167 -0
- data/theatre-spec/namespace_spec.rb +125 -0
- data/theatre-spec/spec_helper.rb +37 -0
- data/theatre-spec/spec_helper_spec.rb +28 -0
- data/theatre-spec/theatre_class_spec.rb +150 -0
- metadata +171 -34
@@ -0,0 +1,306 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'adhearsion/voip/asterisk/config_generators/voicemail.conf'
|
3
|
+
|
4
|
+
describe '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
|
+
it 'should have a [general] context' do
|
11
|
+
config.to_sanitary_hash.has_key?('[general]').should be true
|
12
|
+
end
|
13
|
+
|
14
|
+
it '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
|
+
it 'an exception should be raised if the context name is "general"' do
|
19
|
+
the_following_code {
|
20
|
+
config.context(:general) {|_|}
|
21
|
+
}.should raise_error ArgumentError
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '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
|
+
it 'the recordings setting setter' do
|
34
|
+
Adhearsion::VoIP::Asterisk::ConfigFileGenerators::Voicemail.new.recordings.should be_a_kind_of recordings.class
|
35
|
+
end
|
36
|
+
|
37
|
+
it '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_error
|
43
|
+
|
44
|
+
the_following_code {
|
45
|
+
recordings.format :lolcats
|
46
|
+
}.should raise_error ArgumentError
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '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
|
+
it '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
|
+
it '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
|
+
it 'the body must not be allowed to exceed 512 characters' do
|
76
|
+
the_following_code {
|
77
|
+
email.body "X" * 512
|
78
|
+
}.should_not raise_error ArgumentError
|
79
|
+
|
80
|
+
the_following_code {
|
81
|
+
email.body "X" * 513
|
82
|
+
}.should raise_error ArgumentError
|
83
|
+
|
84
|
+
the_following_code {
|
85
|
+
email.body "X" * 1000
|
86
|
+
}.should raise_error ArgumentError
|
87
|
+
end
|
88
|
+
|
89
|
+
it '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
|
+
describe '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
|
+
it '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
|
+
it '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 be 555
|
111
|
+
end
|
112
|
+
|
113
|
+
it '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 == '123'
|
116
|
+
end
|
117
|
+
|
118
|
+
it '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_error ArgumentError
|
122
|
+
end
|
123
|
+
|
124
|
+
it '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_error ArgumentError
|
128
|
+
end
|
129
|
+
|
130
|
+
it "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
|
+
it '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 be false
|
142
|
+
end
|
143
|
+
|
144
|
+
it '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 be false
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "A Voicemail context definition" do
|
152
|
+
|
153
|
+
it "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_a_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 be true
|
164
|
+
end
|
165
|
+
|
166
|
+
it '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_error LocalJumpError
|
170
|
+
end
|
171
|
+
|
172
|
+
it '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 be true
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
describe 'Defining Voicemail contexts with mailbox definitions' do
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
describe '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
|
+
it '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 be 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.split("\n").grep(/^$|^[^;]/).join("\n").strip.should == target_config.strip
|
304
|
+
|
305
|
+
end
|
306
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'adhearsion/voip/asterisk/config_manager'
|
3
|
+
|
4
|
+
module ConfigurationManagerTestHelper
|
5
|
+
|
6
|
+
def mock_config_manager
|
7
|
+
mock_config_manager_for sample_standard_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def mock_config_manager_for(config_string)
|
11
|
+
new_config_manager_with("bogus filename").tap do |manager|
|
12
|
+
flexmock(manager).should_receive(:execute).and_return(config_string)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def new_config_manager_with(filename)
|
17
|
+
Adhearsion::VoIP::Asterisk::ConfigurationManager.new(filename)
|
18
|
+
end
|
19
|
+
|
20
|
+
def sample_standard_config
|
21
|
+
<<-CONFIG
|
22
|
+
[jicksta]
|
23
|
+
foo=bar
|
24
|
+
qaz=qwerty
|
25
|
+
baz=zxcvb
|
26
|
+
[picard]
|
27
|
+
type=friend
|
28
|
+
insecure=very
|
29
|
+
host=dynamic
|
30
|
+
secret=blargh
|
31
|
+
CONFIG
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "The configuration file parser behavior" do
|
36
|
+
|
37
|
+
include ConfigurationManagerTestHelper
|
38
|
+
|
39
|
+
it "should expose a sections array" do
|
40
|
+
manager = mock_config_manager
|
41
|
+
manager.sections.map(&:first).should == ["jicksta", "picard"]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should ignore comments" do
|
45
|
+
context_names = %w(monkey data)
|
46
|
+
tested_key_name, tested_key_value_before_comment = "bar", "baz"
|
47
|
+
manager = mock_config_manager_for <<-CONFIG
|
48
|
+
[monkey]
|
49
|
+
#{tested_key_name}=#{tested_key_value_before_comment};thiscommentshouldnotbehere
|
50
|
+
asdf=fdsa
|
51
|
+
;[data]
|
52
|
+
;ignored=asdf
|
53
|
+
CONFIG
|
54
|
+
manager.sections.map(&:first).should == [context_names.first]
|
55
|
+
manager[context_names.first].size.should be 2
|
56
|
+
manager[context_names.first][tested_key_name].should == tested_key_value_before_comment
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should match context names with dashes and underscores" do
|
60
|
+
context_names = %w"foo-bar qaz_b-a-z"
|
61
|
+
definition_string = <<-CONFIG
|
62
|
+
[#{context_names.first}]
|
63
|
+
platypus=no
|
64
|
+
zebra=no
|
65
|
+
crappyconfig=yes
|
66
|
+
|
67
|
+
[#{context_names.last}]
|
68
|
+
callerid="Jay Phillips" <133>
|
69
|
+
CONFIG
|
70
|
+
mock_config_manager_for(definition_string).sections.map(&:first).should == context_names
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should strip whitespace around keys and values" do
|
74
|
+
section_name = "hey-there-hot-momma"
|
75
|
+
tested_key_name, tested_key_value_before_comment = "bar", "i heart white space. SIKE!"
|
76
|
+
config_manager = mock_config_manager_for <<-CONFIG
|
77
|
+
\t[#{section_name}]
|
78
|
+
|
79
|
+
thereis = a lot of whitespace after these
|
80
|
+
|
81
|
+
#{tested_key_name} = \t\t\t #{tested_key_value_before_comment}
|
82
|
+
|
83
|
+
CONFIG
|
84
|
+
config_manager[section_name][tested_key_name].should == tested_key_value_before_comment
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return a Hash of properties when searching for an existing section" do
|
88
|
+
result = mock_config_manager["jicksta"]
|
89
|
+
result.should be_a_kind_of Hash
|
90
|
+
result.size.should be 3
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should return nil when searching for a non-existant section" do
|
94
|
+
mock_config_manager["i-so-dont-exist-dude"].should be nil
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "The configuration file writer" do
|
100
|
+
|
101
|
+
include ConfigurationManagerTestHelper
|
102
|
+
|
103
|
+
attr_reader :config_manager
|
104
|
+
|
105
|
+
before(:each) do
|
106
|
+
@config_manager = mock_config_manager
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should remove an old section when replacing it" do
|
110
|
+
config_manager.delete_section "picard"
|
111
|
+
config_manager.sections.map(&:first).should == ["jicksta"]
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should add a new section to the end" do
|
115
|
+
section_name = "wittynamehere"
|
116
|
+
config_manager.new_section(section_name, :type => "friend",
|
117
|
+
:witty => "yes",
|
118
|
+
:shaken => "yes",
|
119
|
+
:stirred => "no")
|
120
|
+
new_section = config_manager.sections.last
|
121
|
+
new_section.first.should be section_name
|
122
|
+
new_section.last.size.should be 4
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "The configuration file generator" do
|
127
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'adhearsion/voip/menu_state_machine/calculated_match'
|
3
|
+
|
4
|
+
module CalculatedMatchCollectionTestHelper
|
5
|
+
def mock_with_potential_matches(potential_matches)
|
6
|
+
Adhearsion::VoIP::CalculatedMatch.new :potential_matches => potential_matches
|
7
|
+
end
|
8
|
+
|
9
|
+
def mock_with_exact_matches(exact_matches)
|
10
|
+
Adhearsion::VoIP::CalculatedMatch.new :exact_matches => exact_matches
|
11
|
+
end
|
12
|
+
|
13
|
+
def mock_with_potential_and_exact_matches(potential_matches, exact_matches)
|
14
|
+
Adhearsion::VoIP::CalculatedMatch.new :potential_matches => potential_matches,
|
15
|
+
:exact_matches => exact_matches
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'CalculatedMatch' do
|
21
|
+
it "should make accessible the context name" do
|
22
|
+
Adhearsion::VoIP::CalculatedMatch.new(:match_payload => :foobar).match_payload.should be :foobar
|
23
|
+
end
|
24
|
+
it "should make accessible the original pattern" do
|
25
|
+
Adhearsion::VoIP::CalculatedMatch.new(:pattern => :something).pattern.should be :something
|
26
|
+
end
|
27
|
+
it "should make accessible the matched query" do
|
28
|
+
Adhearsion::VoIP::CalculatedMatch.new(:query => 123).query.should be 123
|
29
|
+
end
|
30
|
+
it '#type_of_match should return :exact, :potential, or nil' do
|
31
|
+
Adhearsion::VoIP::CalculatedMatch.new(:potential_matches => [1]).type_of_match.should be :potential
|
32
|
+
Adhearsion::VoIP::CalculatedMatch.new(:exact_matches => [3,3]).type_of_match.should be :exact
|
33
|
+
Adhearsion::VoIP::CalculatedMatch.new(:exact_matches => [8,3], :potential_matches => [0,9]).type_of_match.should be :exact
|
34
|
+
Adhearsion::VoIP::CalculatedMatch.new.type_of_match.should be nil
|
35
|
+
end
|
36
|
+
it '#exact_match? should return true if the match was exact' do
|
37
|
+
Adhearsion::VoIP::CalculatedMatch.new(:exact_matches => [0,3,5]).exact_match?.should be true
|
38
|
+
end
|
39
|
+
|
40
|
+
it '#potential_match? should return true if the match was exact' do
|
41
|
+
Adhearsion::VoIP::CalculatedMatch.new(:potential_matches => [88,99,77]).potential_match?.should be true
|
42
|
+
end
|
43
|
+
|
44
|
+
it '#exact_matches should return an array of exact matches' do
|
45
|
+
Adhearsion::VoIP::CalculatedMatch.new(:exact_matches => [0,3,5]).exact_matches.should == [0,3,5]
|
46
|
+
end
|
47
|
+
|
48
|
+
it '#potential_matches should return an array of potential matches' do
|
49
|
+
Adhearsion::VoIP::CalculatedMatch.new(:potential_matches => [88,99,77]).potential_matches.should == [88,99,77]
|
50
|
+
end
|
51
|
+
|
52
|
+
it '::failed_match! should return a match that *really* failed' do
|
53
|
+
failure = Adhearsion::VoIP::CalculatedMatch.failed_match! 10..20, 30, :match_payload_does_not_matter
|
54
|
+
failure.exact_match?.should_not be true
|
55
|
+
failure.potential_match?.should_not be true
|
56
|
+
failure.type_of_match.should be nil
|
57
|
+
|
58
|
+
failure.match_payload.should be :match_payload_does_not_matter
|
59
|
+
failure.pattern.should == (10..20)
|
60
|
+
failure.query.should == 30
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'CalculatedMatchCollection' do
|
66
|
+
|
67
|
+
include CalculatedMatchCollectionTestHelper
|
68
|
+
|
69
|
+
attr_reader :collection
|
70
|
+
before(:each) do
|
71
|
+
@collection = Adhearsion::VoIP::CalculatedMatchCollection.new
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'the <<() method should collect the potential matches into the actual_potential_matches Array' do
|
75
|
+
mock_matches_array_1 = [:foo, :bar, :qaz],
|
76
|
+
mock_matches_array_2 = [10,20,30]
|
77
|
+
mock_matches_1 = mock_with_potential_matches mock_matches_array_1
|
78
|
+
mock_matches_2 = mock_with_potential_matches mock_matches_array_2
|
79
|
+
|
80
|
+
collection << mock_matches_1
|
81
|
+
collection.actual_potential_matches.should == mock_matches_array_1
|
82
|
+
|
83
|
+
collection << mock_matches_2
|
84
|
+
collection.actual_potential_matches.should == mock_matches_array_1 + mock_matches_array_2
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'the <<() method should collect the exact matches into the actual_exact_matches Array' do
|
88
|
+
mock_matches_array_1 = [:blam, :blargh],
|
89
|
+
mock_matches_array_2 = [5,4,3,2,1]
|
90
|
+
mock_matches_1 = mock_with_exact_matches mock_matches_array_1
|
91
|
+
mock_matches_2 = mock_with_exact_matches mock_matches_array_2
|
92
|
+
|
93
|
+
collection << mock_matches_1
|
94
|
+
collection.actual_exact_matches.should == mock_matches_array_1
|
95
|
+
|
96
|
+
collection << mock_matches_2
|
97
|
+
collection.actual_exact_matches.should == mock_matches_array_1 + mock_matches_array_2
|
98
|
+
end
|
99
|
+
|
100
|
+
it "if any exact matches exist, the exact_match?() method should return true" do
|
101
|
+
collection << mock_with_exact_matches([1,2,3])
|
102
|
+
collection.exact_match?.should be true
|
103
|
+
end
|
104
|
+
|
105
|
+
it "if any potential matches exist, the potential_match?() method should return true" do
|
106
|
+
collection << mock_with_potential_matches([1,2,3])
|
107
|
+
collection.potential_match?.should be true
|
108
|
+
end
|
109
|
+
end
|