adhearsion-asterisk 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +3 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +6 -0
  5. data/Guardfile +5 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +143 -0
  8. data/Rakefile +23 -0
  9. data/adhearsion-asterisk.gemspec +35 -0
  10. data/lib/adhearsion-asterisk.rb +1 -0
  11. data/lib/adhearsion/asterisk.rb +12 -0
  12. data/lib/adhearsion/asterisk/config_generator.rb +103 -0
  13. data/lib/adhearsion/asterisk/config_generator/agents.rb +138 -0
  14. data/lib/adhearsion/asterisk/config_generator/queues.rb +247 -0
  15. data/lib/adhearsion/asterisk/config_generator/voicemail.rb +238 -0
  16. data/lib/adhearsion/asterisk/config_manager.rb +60 -0
  17. data/lib/adhearsion/asterisk/plugin.rb +464 -0
  18. data/lib/adhearsion/asterisk/queue_proxy.rb +177 -0
  19. data/lib/adhearsion/asterisk/queue_proxy/agent_proxy.rb +81 -0
  20. data/lib/adhearsion/asterisk/queue_proxy/queue_agents_list_proxy.rb +132 -0
  21. data/lib/adhearsion/asterisk/version.rb +5 -0
  22. data/spec/adhearsion/asterisk/config_generators/agents_spec.rb +258 -0
  23. data/spec/adhearsion/asterisk/config_generators/queues_spec.rb +322 -0
  24. data/spec/adhearsion/asterisk/config_generators/voicemail_spec.rb +306 -0
  25. data/spec/adhearsion/asterisk/config_manager_spec.rb +125 -0
  26. data/spec/adhearsion/asterisk/plugin_spec.rb +618 -0
  27. data/spec/adhearsion/asterisk/queue_proxy/agent_proxy_spec.rb +90 -0
  28. data/spec/adhearsion/asterisk/queue_proxy/queue_agents_list_proxy_spec.rb +145 -0
  29. data/spec/adhearsion/asterisk/queue_proxy_spec.rb +156 -0
  30. data/spec/adhearsion/asterisk_spec.rb +9 -0
  31. data/spec/spec_helper.rb +23 -0
  32. data/spec/support/the_following_code.rb +3 -0
  33. metadata +229 -0
@@ -0,0 +1,177 @@
1
+ module Adhearsion
2
+ module Asterisk
3
+ class QueueProxy
4
+
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :AgentProxy
8
+ autoload :QueueAgentsListProxy
9
+
10
+ class << self
11
+ def format_join_hash_key_arguments(options)
12
+ bad_argument = lambda do |(key, value)|
13
+ raise ArgumentError, "Unrecognize value for #{key.inspect} -- #{value.inspect}"
14
+ end
15
+
16
+ # Direct Queue() arguments:
17
+ timeout = options.delete :timeout
18
+ announcement = options.delete :announce
19
+
20
+ # Terse single-character options
21
+ ring_style = options.delete :play
22
+ allow_hangup = options.delete :allow_hangup
23
+ allow_transfer = options.delete :allow_transfer
24
+ agi = options.delete :agi
25
+
26
+ raise ArgumentError, "Unrecognized args to join!: #{options.inspect}" if options.any?
27
+
28
+ ring_style = case ring_style
29
+ when :ringing then 'r'
30
+ when :music then ''
31
+ when nil
32
+ else bad_argument[:play => ring_style]
33
+ end.to_s
34
+
35
+ allow_hangup = case allow_hangup
36
+ when :caller then 'H'
37
+ when :agent then 'h'
38
+ when :everyone then 'Hh'
39
+ when nil
40
+ else bad_argument[:allow_hangup => allow_hangup]
41
+ end.to_s
42
+
43
+ allow_transfer = case allow_transfer
44
+ when :caller then 'T'
45
+ when :agent then 't'
46
+ when :everyone then 'Tt'
47
+ when nil
48
+ else bad_argument[:allow_transfer => allow_transfer]
49
+ end.to_s
50
+
51
+ terse_character_options = ring_style + allow_transfer + allow_hangup
52
+
53
+ [terse_character_options, '', announcement, timeout, agi].map(&:to_s)
54
+ end
55
+ end
56
+
57
+ attr_reader :name, :environment
58
+
59
+ def initialize(name, environment)
60
+ @name, @environment = name, environment
61
+ end
62
+
63
+ # Makes the current channel join the queue.
64
+ #
65
+ # @param [Hash] options
66
+ #
67
+ # :timeout - The number of seconds to wait for an agent to answer
68
+ # :play - Can be :ringing or :music.
69
+ # :announce - A sound file to play instead of the normal queue announcement.
70
+ # :allow_transfer - Can be :caller, :agent, or :everyone. Allow someone to transfer the call.
71
+ # :allow_hangup - Can be :caller, :agent, or :everyone. Allow someone to hangup with the * key.
72
+ # :agi - An AGI script to be called on the calling parties channel just before being connected.
73
+ #
74
+ # @example
75
+ # queue('sales').join!
76
+ # @example
77
+ # queue('sales').join! :timeout => 1.minute
78
+ # @example
79
+ # queue('sales').join! :play => :music
80
+ # @example
81
+ # queue('sales').join! :play => :ringing
82
+ # @example
83
+ # queue('sales').join! :announce => "custom/special-queue-announcement"
84
+ # @example
85
+ # queue('sales').join! :allow_transfer => :caller
86
+ # @example
87
+ # queue('sales').join! :allow_transfer => :agent
88
+ # @example
89
+ # queue('sales').join! :allow_hangup => :caller
90
+ # @example
91
+ # queue('sales').join! :allow_hangup => :agent
92
+ # @example
93
+ # queue('sales').join! :allow_hangup => :everyone
94
+ # @example
95
+ # queue('sales').join! :agi => 'agi://localhost/sales_queue_callback'
96
+ # @example
97
+ # queue('sales').join! :allow_transfer => :agent, :timeout => 30.seconds,
98
+ def join!(options = {})
99
+ environment.execute("queue", name, *self.class.format_join_hash_key_arguments(options))
100
+ normalize_queue_status_variable environment.get_variable("QUEUESTATUS")
101
+ end
102
+
103
+ # Get the agents associated with a queue
104
+ #
105
+ # @param [Hash] options
106
+ # @return [QueueAgentsListProxy]
107
+ def agents(options = {})
108
+ cached = options.has_key?(:cache) ? options.delete(:cache) : true
109
+ raise ArgumentError, "Unrecognized arguments to #agents: #{options.inspect}" if options.keys.any?
110
+ if cached
111
+ @cached_proxy ||= QueueAgentsListProxy.new(self, true)
112
+ else
113
+ @uncached_proxy ||= QueueAgentsListProxy.new(self, false)
114
+ end
115
+ end
116
+
117
+ # Check how many channels are waiting in the queue
118
+ # @return [Integer]
119
+ # @raise QueueDoesNotExistError
120
+ def waiting_count
121
+ raise QueueDoesNotExistError.new(name) unless exists?
122
+ environment.get_variable("QUEUE_WAITING_COUNT(#{name})").to_i
123
+ end
124
+
125
+ # Check whether the waiting count is zero
126
+ # @return [Boolean]
127
+ def empty?
128
+ waiting_count == 0
129
+ end
130
+
131
+ # Check whether any calls are waiting in the queue
132
+ # @return [Boolean]
133
+ def any?
134
+ waiting_count > 0
135
+ end
136
+
137
+ # Check whether a queue exists/is defined in Asterisk
138
+ # @return [Boolean]
139
+ def exists?
140
+ environment.execute('RemoveQueueMember', name, 'SIP/AdhearsionQueueExistenceCheck')
141
+ environment.get_variable("RQMSTATUS") != 'NOSUCHQUEUE'
142
+ end
143
+
144
+ private
145
+
146
+ # Ensure the queue exists by interpreting the QUEUESTATUS variable
147
+ #
148
+ # According to http://www.voip-info.org/wiki/view/Asterisk+cmd+Queue
149
+ # possible values are:
150
+ #
151
+ # TIMEOUT => :timeout
152
+ # FULL => :full
153
+ # JOINEMPTY => :joinempty
154
+ # LEAVEEMPTY => :leaveempty
155
+ # JOINUNAVAIL => :joinunavail
156
+ # LEAVEUNAVAIL => :leaveunavail
157
+ # CONTINUE => :continue
158
+ #
159
+ # If the QUEUESTATUS variable is not set the call was successfully connected,
160
+ # and Adhearsion will return :completed.
161
+ #
162
+ # @param [String] QUEUESTATUS variable from Asterisk
163
+ # @return [Symbol] Symbolized version of QUEUESTATUS
164
+ # @raise QueueDoesNotExistError
165
+ def normalize_queue_status_variable(variable)
166
+ variable = "COMPLETED" if variable.nil?
167
+ variable.downcase.to_sym
168
+ end
169
+
170
+ class QueueDoesNotExistError < StandardError
171
+ def initialize(queue_name)
172
+ super "Queue #{queue_name} does not exist!"
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,81 @@
1
+ module Adhearsion
2
+ module Asterisk
3
+ class QueueProxy
4
+ class AgentProxy
5
+
6
+ SUPPORTED_METADATA_NAMES = %w[status password name mohclass exten channel] unless defined? SUPPORTED_METADATA_NAMES
7
+
8
+ class << self
9
+ def id_from_agent_channel(id)
10
+ id = id.to_s
11
+ id.starts_with?('Agent/') ? id[%r[^Agent/(.+)$],1] : id
12
+ end
13
+ end
14
+
15
+ attr_reader :interface, :proxy, :queue_name, :id
16
+ def initialize(interface, proxy)
17
+ @interface, @proxy = interface, proxy
18
+ @id = self.class.id_from_agent_channel interface
19
+ @queue_name = proxy.name
20
+ end
21
+
22
+ def remove!
23
+ proxy.environment.execute 'RemoveQueueMember', queue_name, interface
24
+ case proxy.environment.get_variable("RQMSTATUS")
25
+ when "REMOVED" then true
26
+ when "NOTINQUEUE" then false
27
+ when "NOSUCHQUEUE"
28
+ raise QueueDoesNotExistError.new(queue_name)
29
+ else
30
+ raise "Unrecognized RQMSTATUS variable!"
31
+ end
32
+ end
33
+
34
+ # Pauses the given agent for this queue only. If you wish to pause this agent
35
+ # for all queues, pass in :everywhere => true. Returns true if the agent was
36
+ # successfully paused and false if the agent was not found.
37
+ def pause!(options = {})
38
+ args = [(options.delete(:everywhere) ? nil : queue_name), interface]
39
+ proxy.environment.execute 'PauseQueueMember', *args
40
+ case proxy.environment.get_variable("PQMSTATUS")
41
+ when "PAUSED" then true
42
+ when "NOTFOUND" then false
43
+ else
44
+ raise "Unrecognized PQMSTATUS value!"
45
+ end
46
+ end
47
+
48
+ # Pauses the given agent for this queue only. If you wish to pause this agent
49
+ # for all queues, pass in :everywhere => true. Returns true if the agent was
50
+ # successfully paused and false if the agent was not found.
51
+ def unpause!(options = {})
52
+ args = [(options.delete(:everywhere) ? nil : queue_name), interface]
53
+ proxy.environment.execute 'UnpauseQueueMember', *args
54
+ case proxy.environment.get_variable("UPQMSTATUS")
55
+ when "UNPAUSED" then true
56
+ when "NOTFOUND" then false
57
+ else
58
+ raise "Unrecognized UPQMSTATUS value!"
59
+ end
60
+ end
61
+
62
+ # Returns true/false depending on whether this agent is logged in.
63
+ def logged_in?
64
+ status == 'LOGGEDIN'
65
+ end
66
+
67
+ private
68
+
69
+ def status
70
+ agent_metadata 'status'
71
+ end
72
+
73
+ def agent_metadata(data_name)
74
+ data_name = data_name.to_s.downcase
75
+ raise ArgumentError, "unrecognized agent metadata name #{data_name}" unless SUPPORTED_METADATA_NAMES.include? data_name
76
+ proxy.environment.variable "AGENT(#{id}:#{data_name})"
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,132 @@
1
+ module Adhearsion
2
+ module Asterisk
3
+ class QueueProxy
4
+ class QueueAgentsListProxy
5
+ include Enumerable
6
+
7
+ attr_reader :proxy, :agents
8
+
9
+ def initialize(proxy, cached = false)
10
+ @proxy = proxy
11
+ @cached = cached
12
+ end
13
+
14
+ def count
15
+ if cached? && @cached_count
16
+ @cached_count
17
+ else
18
+ @cached_count = proxy.environment.get_variable("QUEUE_MEMBER_COUNT(#{proxy.name})").to_i
19
+ end
20
+ end
21
+ alias size count
22
+ alias length count
23
+
24
+ # @param [Hash] args
25
+ # :name value will be viewable in the queue_log
26
+ # :penalty is the penalty assigned to this agent for answering calls on this queue
27
+ def new(*args)
28
+ options = args.last.kind_of?(Hash) ? args.pop : {}
29
+ interface = args.shift
30
+
31
+ raise ArgumentError, "You must specify an interface to add." if interface.nil?
32
+ raise ArgumentError, "You may only supply an interface and a Hash argument!" if args.any?
33
+
34
+ penalty = options.delete(:penalty) || ''
35
+ name = options.delete(:name) || ''
36
+ state_interface = options.delete(:state_interface) || ''
37
+
38
+ raise ArgumentError, "Unrecognized argument(s): #{options.inspect}" if options.any?
39
+
40
+ proxy.environment.execute "AddQueueMember", proxy.name, interface, penalty, '', name, state_interface
41
+
42
+ added = case proxy.environment.get_variable("AQMSTATUS")
43
+ when "ADDED" then true
44
+ when "MEMBERALREADY" then false
45
+ when "NOSUCHQUEUE" then raise QueueDoesNotExistError.new(proxy.name)
46
+ else
47
+ raise "UNRECOGNIZED AQMSTATUS VALUE!"
48
+ end
49
+
50
+ if added
51
+ check_agent_cache!
52
+ AgentProxy.new(interface, proxy).tap do |agent_proxy|
53
+ @agents << agent_proxy
54
+ end
55
+ else
56
+ false
57
+ end
58
+ end
59
+
60
+ # Logs a pre-defined agent into this queue and waits for calls. Pass in :silent => true to stop
61
+ # the message which says "Agent logged in".
62
+ def login!(*args)
63
+ options = args.last.kind_of?(Hash) ? args.pop : {}
64
+
65
+ silent = options.delete(:silent).equal?(false) ? '' : 's'
66
+ id = args.shift
67
+ id &&= AgentProxy.id_from_agent_channel(id)
68
+ raise ArgumentError, "Unrecognized Hash options to #login: #{options.inspect}" if options.any?
69
+ raise ArgumentError, "Unrecognized argument to #login: #{args.inspect}" if args.any?
70
+
71
+ proxy.environment.execute 'AgentLogin', id, silent
72
+ end
73
+
74
+ # Removes the current channel from this queue
75
+ def logout!
76
+ # TODO: DRY this up. Repeated in the AgentProxy...
77
+ proxy.environment.execute 'RemoveQueueMember', proxy.name
78
+ case proxy.environment.get_variable("RQMSTATUS")
79
+ when "REMOVED" then true
80
+ when "NOTINQUEUE" then false
81
+ when "NOSUCHQUEUE"
82
+ raise QueueDoesNotExistError.new(proxy.name)
83
+ else
84
+ raise "Unrecognized RQMSTATUS variable!"
85
+ end
86
+ end
87
+
88
+ def each(&block)
89
+ check_agent_cache!
90
+ agents.each &block
91
+ end
92
+
93
+ def first
94
+ check_agent_cache!
95
+ agents.first
96
+ end
97
+
98
+ def last
99
+ check_agent_cache!
100
+ agents.last
101
+ end
102
+
103
+ def cached?
104
+ @cached
105
+ end
106
+
107
+ def to_a
108
+ check_agent_cache!
109
+ @agents
110
+ end
111
+
112
+ private
113
+
114
+ def check_agent_cache!
115
+ if cached?
116
+ load_agents! unless agents
117
+ else
118
+ load_agents!
119
+ end
120
+ end
121
+
122
+ def load_agents!
123
+ raw_data = proxy.environment.get_variable "QUEUE_MEMBER_LIST(#{proxy.name})"
124
+ @agents = raw_data.split(',').map(&:strip).reject(&:empty?).map do |agent|
125
+ AgentProxy.new agent, proxy
126
+ end
127
+ @cached_count = @agents.size
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,5 @@
1
+ module Adhearsion
2
+ module Asterisk
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,258 @@
1
+ require 'spec_helper'
2
+ require 'adhearsion/asterisk/config_generator/agents'
3
+
4
+ module AgentsConfigGeneratorTestHelper
5
+
6
+ def reset_agents!
7
+ @agents = Adhearsion::Asterisk::ConfigGenerator::Agents.new
8
+ end
9
+
10
+ def generated_config_has_pair(pair)
11
+ agents.conf.split("\n").grep(/=[^>]/).each do |line|
12
+ key, value = line.strip.split('=')
13
+ return true if pair == {key.to_sym => value}
14
+ end
15
+ false
16
+ end
17
+
18
+ end
19
+
20
+ describe "The agents.conf config file agents" do
21
+
22
+ include AgentsConfigGeneratorTestHelper
23
+
24
+ attr_reader :agents
25
+ before(:each) do
26
+ reset_agents!
27
+ end
28
+ it "The agent() method should enqueue a Hash into Agents#agent_definitions" do
29
+ agents.agent 1337, :password => 9876, :name => "Jay Phillips"
30
+ agents.agent_definitions.size.should be 1
31
+ agents.agent_definitions.first.should == {:id => 1337, :password => 9876, :name => "Jay Phillips"}
32
+ end
33
+
34
+ it 'should add the warning message to the to_s output' do
35
+ agents.conf.should =~ /^\s*;.{10}/
36
+ end
37
+
38
+ it "The conf() method should always create a general section" do
39
+ agents.conf.should =~ /^\[general\]/
40
+ end
41
+
42
+ it "The agent() method should generate a proper String" do
43
+ agents.agent 123, :name => "Otto Normalverbraucher", :password => "007"
44
+ agents.agent 889, :name => "John Doe", :password => "998"
45
+
46
+ agents.conf.split("\n").grep(/^agent =>/).map(&:strip).should == [
47
+ "agent => 123,007,Otto Normalverbraucher",
48
+ "agent => 889,998,John Doe"
49
+ ]
50
+ end
51
+
52
+ it "The persistent_agents() method should generate a persistentagents yes/no pair" do
53
+ agents.persistent_agents true
54
+ generated_config_has_pair(:persistentagents => "yes").should be true
55
+
56
+ reset_agents!
57
+
58
+ agents.persistent_agents false
59
+ generated_config_has_pair(:persistentagents => "no").should be true
60
+ end
61
+
62
+ it "The persistent_agents() method should be in the [general] section" do
63
+ agents.persistent_agents true
64
+ agents.general_section.should == {:persistentagents => "yes"}
65
+
66
+ end
67
+
68
+ it "max_login_tries() should generate a 'maxlogintries' numerical pair" do
69
+ agents.max_login_tries 50
70
+ generated_config_has_pair(:maxlogintries => "50").should be true
71
+ end
72
+
73
+ it "max_login_tries() should be in the agents section" do
74
+ agents.max_login_tries 0
75
+ agents.agent_section.should == {:maxlogintries => 0}
76
+ end
77
+
78
+ it "log_off_after_duration should generate autologoff" do
79
+ agents.log_off_after_duration 15.seconds
80
+ generated_config_has_pair(:autologoff => "15").should be true
81
+ end
82
+
83
+ it "log_off_if_unavailable should add autologoffunavail to the agents section" do
84
+ agents.log_off_if_unavailable false
85
+ agents.agent_section.should == {:autologoffunavail => "no"}
86
+ end
87
+
88
+ it "require_hash_to_acknowledge() should generate a 'ackcall' yes/no pair" do
89
+ agents.require_hash_to_acknowledge false
90
+ agents.agent_section.should == {:ackcall => "no"}
91
+ end
92
+
93
+ it "allow_star_to_hangup should generate a 'endcall' yes/no pair" do
94
+ agents.allow_star_to_hangup false
95
+ agents.agent_section.should == {:endcall => "no"}
96
+ end
97
+
98
+ it "time_between_calls should convert its argument to milliseconds" do
99
+ agents.time_between_calls 1.hour
100
+ agents.agent_section.should == {:wrapuptime => 1.hour * 1_000}
101
+ end
102
+
103
+ it "hold_music_class should convert its argument to a String" do
104
+ agents.hold_music_class :podcast
105
+ agents.agent_section_special.should == {:musiconhold => "podcast"}
106
+ end
107
+
108
+ it "play_on_agent_goodbye should generate 'agentgoodbye'" do
109
+ agents.play_on_agent_goodbye "tt-monkeys"
110
+ agents.agent_section_special.should == {:agentgoodbye => "tt-monkeys"}
111
+ end
112
+
113
+ it "change_cdr_source should generate updatecdr" do
114
+ agents.change_cdr_source false
115
+ agents.agent_section.should == {:updatecdr => "no"}
116
+ end
117
+
118
+ it "play_for_waiting_keep_alive" do
119
+ agents.play_for_waiting_keep_alive "tt-weasels"
120
+ agents.agent_section.should == {:custom_beep => "tt-weasels"}
121
+ end
122
+
123
+ it "save_recordings_in should generate 'savecallsin'" do
124
+ agents.save_recordings_in "/second/star/on/the/right"
125
+ agents.agent_section.should == {:savecallsin => "/second/star/on/the/right"}
126
+ end
127
+
128
+ it "recording_prefix should generate 'urlprefix'" do
129
+ agents.recording_prefix "ohai"
130
+ agents.agent_section.should == {:urlprefix => "ohai"}
131
+ end
132
+
133
+ it "recording_format should only allow a few symbols as an argument" do
134
+ the_following_code {
135
+ agents.recording_format :wav
136
+ agents.agent_section.should == {:recordformat => :wav}
137
+ }.should_not raise_error
138
+
139
+ reset_agents!
140
+
141
+ the_following_code {
142
+ agents.recording_format :wav49
143
+ agents.agent_section.should == {:recordformat => :wav49}
144
+ }.should_not raise_error
145
+
146
+ reset_agents!
147
+
148
+ the_following_code {
149
+ agents.recording_format :gsm
150
+ agents.agent_section.should == {:recordformat => :gsm}
151
+ }.should_not raise_error
152
+
153
+ reset_agents!
154
+
155
+ the_following_code {
156
+ agents.recording_format :mp3
157
+ agents.agent_section.should == {:recordformat => :mp3}
158
+ }.should raise_error ArgumentError
159
+
160
+ end
161
+
162
+ it "record_agent_calls should generate a 'recordagentcalls' yes/no pair" do
163
+ agents.record_agent_calls false
164
+ agents.agent_section.should == {:recordagentcalls => 'no'}
165
+ end
166
+
167
+ it "allow_multiple_logins_per_extension should generate 'multiplelogin' in [general]" do
168
+ agents.allow_multiple_logins_per_extension true
169
+ agents.general_section.should == {:multiplelogin => 'yes'}
170
+ end
171
+
172
+ end
173
+
174
+ describe "The default agents.conf config file converted to this syntax" do
175
+
176
+ include AgentsConfigGeneratorTestHelper
177
+
178
+ attr_reader :default_config, :agents
179
+ before(:each) do
180
+ reset_agents!
181
+ @default_config = <<-CONFIG
182
+ [general]
183
+ persistentagents=yes
184
+
185
+ [agents]
186
+ maxlogintries=5
187
+ autologoff=15
188
+ ackcall=no
189
+ endcall=yes
190
+ wrapuptime=5000
191
+ musiconhold => default
192
+ agentgoodbye => goodbye_file
193
+ updatecdr=no
194
+ group=1,2
195
+ recordagentcalls=yes
196
+ recordformat=gsm
197
+ urlprefix=http://localhost/calls/
198
+ savecallsin=/var/calls
199
+ custom_beep=beep
200
+
201
+ agent => 1001,4321,Mark Spencer
202
+ agent => 1002,4321,Will Meadows
203
+ CONFIG
204
+ end
205
+
206
+ it "they're basically the same" do
207
+ agents.persistent_agents true
208
+ agents.max_login_tries 5
209
+ agents.log_off_after_duration 15
210
+ agents.require_hash_to_acknowledge false
211
+ agents.allow_star_to_hangup true
212
+ agents.time_between_calls 5
213
+ agents.hold_music_class :default
214
+ agents.play_on_agent_goodbye "goodbye_file"
215
+ agents.change_cdr_source false
216
+ agents.groups 1,2
217
+ agents.record_agent_calls true
218
+ agents.recording_format :gsm
219
+ agents.recording_prefix "http://localhost/calls/"
220
+ agents.save_recordings_in "/var/calls"
221
+ agents.play_for_waiting_keep_alive "beep"
222
+
223
+ agents.agent 1001, :password => 4321, :name => "Mark Spencer"
224
+ agents.agent 1002, :password => 4321, :name => "Will Meadows"
225
+
226
+ cleaned_up_default_config =
227
+ Adhearsion::Asterisk::ConfigGenerator.create_sanitary_hash_from(default_config)
228
+
229
+ cleaned_up_generated_config = agents.to_sanitary_hash
230
+
231
+ cleaned_up_generated_config.should == cleaned_up_default_config
232
+ end
233
+
234
+ end
235
+
236
+
237
+ describe "AgentsConfigGeneratorTestHelper" do
238
+
239
+ include AgentsConfigGeneratorTestHelper
240
+
241
+ attr_reader :agents
242
+ before(:each) do
243
+ reset_agents!
244
+ end
245
+
246
+ it "generated_config_has_pair() works properly with one pair" do
247
+ @agents = mock "A fake agents with just one pair", :conf => "foo=bar"
248
+ generated_config_has_pair(:foo => "bar").should be true
249
+ end
250
+
251
+ it "generated_config_has_pair() works properly with two pairs" do
252
+ @agents = mock "A fake agents with just one pair"
253
+ @agents.expects(:conf).twice.returns("[general]\n\nqaz=qwerty\nagent => 1,2,3")
254
+
255
+ generated_config_has_pair(:qaz => "qwerty").should be true
256
+ generated_config_has_pair(:foo => "bar").should be false
257
+ end
258
+ end