electric_slide 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/.travis.yml +10 -0
- data/CHANGELOG.md +21 -0
- data/LICENSE +1 -1
- data/README.markdown +33 -6
- data/electric_slide.gemspec +3 -1
- data/lib/electric_slide.rb +36 -36
- data/lib/electric_slide/agent.rb +61 -38
- data/lib/electric_slide/agent_strategy/longest_idle.rb +1 -1
- data/lib/electric_slide/call_queue.rb +172 -38
- data/lib/electric_slide/version.rb +1 -1
- data/spec/electric_slide/agent_spec.rb +29 -3
- data/spec/electric_slide/agent_strategy/fixed_priority_spec.rb +7 -8
- data/spec/electric_slide/call_queue_spec.rb +436 -25
- data/spec/electric_slide_spec.rb +58 -14
- data/spec/spec_helper.rb +6 -0
- metadata +23 -6
@@ -6,9 +6,10 @@ describe ElectricSlide::Agent do
|
|
6
6
|
let(:options) { { id: 1, address: '123@foo.com', presence: :available} }
|
7
7
|
|
8
8
|
class MyAgent < ElectricSlide::Agent
|
9
|
-
on_connect
|
10
|
-
|
11
|
-
|
9
|
+
on_connect { foo }
|
10
|
+
on_connection_failed { foo }
|
11
|
+
on_disconnect { foo }
|
12
|
+
on_presence_change { foo }
|
12
13
|
|
13
14
|
def foo
|
14
15
|
:bar
|
@@ -17,7 +18,32 @@ describe ElectricSlide::Agent do
|
|
17
18
|
|
18
19
|
subject {MyAgent.new options}
|
19
20
|
|
21
|
+
after do
|
22
|
+
[:connect_callback, :disconnect_callback, :connection_failed_callback, :presence_change_callback].each do |callback|
|
23
|
+
ElectricSlide::Agent.instance_variable_set "@#{callback}", nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
20
27
|
it 'executes a connect callback' do
|
21
28
|
expect(subject.callback(:connect)).to eql :bar
|
22
29
|
end
|
30
|
+
|
31
|
+
it 'executes a disconnect callback' do
|
32
|
+
expect(subject.callback(:disconnect)).to eql :bar
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'executes a connection failed callback' do
|
36
|
+
expect(subject.callback(:connection_failed)).to eql :bar
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'executes a presence change callback' do
|
40
|
+
expect(subject.callback(:presence_change, nil, nil, nil, nil)).to eql :bar
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'executes the presence change callback on state change' do
|
44
|
+
called = false
|
45
|
+
ElectricSlide::Agent.on_presence_change { |queue, agent_call, presence| called = true }
|
46
|
+
agent = ElectricSlide::Agent.new presence: :unavailable
|
47
|
+
agent.presence = :busy
|
48
|
+
end
|
23
49
|
end
|
@@ -5,11 +5,10 @@ require 'electric_slide/agent_strategy/fixed_priority'
|
|
5
5
|
require 'ostruct'
|
6
6
|
|
7
7
|
describe ElectricSlide::AgentStrategy::FixedPriority do
|
8
|
-
let(:subject) { ElectricSlide::AgentStrategy::FixedPriority.new }
|
9
8
|
it 'should allow adding an agent with a specified priority' do
|
10
|
-
subject.agent_available
|
9
|
+
expect(subject.agent_available?).to be false
|
11
10
|
subject << OpenStruct.new({ id: 101, priority: 1 })
|
12
|
-
subject.agent_available
|
11
|
+
expect(subject.agent_available?).to be true
|
13
12
|
end
|
14
13
|
|
15
14
|
it 'should allow adding multiple agents at the same priority' do
|
@@ -17,7 +16,7 @@ describe ElectricSlide::AgentStrategy::FixedPriority do
|
|
17
16
|
agent2 = OpenStruct.new({ id: 102, priority: 2 })
|
18
17
|
subject << agent1
|
19
18
|
subject << agent2
|
20
|
-
subject.checkout_agent.
|
19
|
+
expect(subject.checkout_agent).to eql(agent1)
|
21
20
|
end
|
22
21
|
|
23
22
|
it 'should return all agents of a higher priority before returning an agent of a lower priority' do
|
@@ -27,9 +26,9 @@ describe ElectricSlide::AgentStrategy::FixedPriority do
|
|
27
26
|
subject << agent1
|
28
27
|
subject << agent2
|
29
28
|
subject << agent3
|
30
|
-
subject.checkout_agent.
|
31
|
-
subject.checkout_agent.
|
32
|
-
subject.checkout_agent.
|
29
|
+
expect(subject.checkout_agent).to eql(agent1)
|
30
|
+
expect(subject.checkout_agent).to eql(agent2)
|
31
|
+
expect(subject.checkout_agent).to eql(agent3)
|
33
32
|
end
|
34
33
|
|
35
34
|
it 'should detect an agent available if one is available at any priority' do
|
@@ -38,6 +37,6 @@ describe ElectricSlide::AgentStrategy::FixedPriority do
|
|
38
37
|
subject << agent1
|
39
38
|
subject << agent2
|
40
39
|
subject.checkout_agent
|
41
|
-
subject.agent_available
|
40
|
+
expect(subject.agent_available?).to be true
|
42
41
|
end
|
43
42
|
end
|
@@ -1,42 +1,453 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
|
+
require 'electric_slide/agent_strategy/fixed_priority'
|
3
4
|
|
4
5
|
describe ElectricSlide::CallQueue do
|
5
6
|
let(:queue) { ElectricSlide::CallQueue.new }
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
|
8
|
+
context "enqueuing calls" do
|
9
|
+
let(:call_a) { dummy_call }
|
10
|
+
let(:call_b) { dummy_call }
|
11
|
+
let(:call_c) { dummy_call }
|
12
|
+
before :each do
|
13
|
+
queue.enqueue call_a
|
14
|
+
queue.enqueue call_b
|
15
|
+
queue.enqueue call_c
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return callers in the same order they were enqueued" do
|
19
|
+
expect(queue.get_next_caller).to be call_a
|
20
|
+
expect(queue.get_next_caller).to be call_b
|
21
|
+
expect(queue.get_next_caller).to be call_c
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return a priority caller ahead of the queue" do
|
25
|
+
call_d = dummy_call
|
26
|
+
queue.priority_enqueue call_d
|
27
|
+
expect(queue.get_next_caller).to be call_d
|
28
|
+
expect(queue.get_next_caller).to be call_a
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should remove a caller who abandons the queue" do
|
32
|
+
queue.enqueue call_a
|
33
|
+
queue.enqueue call_b
|
34
|
+
call_a << Punchblock::Event::End.new(reason: :hangup)
|
35
|
+
expect(queue.get_next_caller).to be call_b
|
36
|
+
end
|
37
|
+
|
38
|
+
it "records the time in the :electric_slide_enqueued_at call variable on the queued call" do
|
39
|
+
enqueue_time = DateTime.new(2015, 9, 30, 15, 0, 23)
|
40
|
+
Timecop.freeze enqueue_time
|
41
|
+
queue.enqueue call_a
|
42
|
+
expect(call_a[:electric_slide_enqueued_at]).to eq(enqueue_time)
|
43
|
+
end
|
13
44
|
end
|
14
45
|
|
15
|
-
it "should
|
16
|
-
expect
|
17
|
-
expect(queue.get_next_caller).to be call_b
|
18
|
-
expect(queue.get_next_caller).to be call_c
|
46
|
+
it "should raise when given an invalid Agent" do
|
47
|
+
expect { queue.add_agent nil }.to raise_error(ArgumentError)
|
19
48
|
end
|
20
49
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
50
|
+
describe 'connecting agents to callers' do
|
51
|
+
let(:agent_return_method) { :auto }
|
52
|
+
|
53
|
+
let(:queue) { ElectricSlide::CallQueue.new(connection_type: connection_type, agent_return_method: agent_return_method) }
|
54
|
+
let(:agent_id) { '123' }
|
55
|
+
let(:agent) { ElectricSlide::Agent.new id: agent_id, address: '123', presence: :available }
|
56
|
+
let!(:agent_call) { Adhearsion::OutboundCall.new }
|
57
|
+
let(:queued_call) { dummy_call }
|
58
|
+
let(:connected_time) { DateTime.now }
|
59
|
+
|
60
|
+
before do
|
61
|
+
allow(Adhearsion::OutboundCall).to receive(:new) { agent_call }
|
62
|
+
allow(agent).to receive(:dial_options_for) {
|
63
|
+
{ confirm: double('ConfirmController') }
|
64
|
+
}
|
65
|
+
|
66
|
+
allow(queued_call).to receive(:active?) { true }
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with connection type :call" do
|
70
|
+
let(:connection_type) { :call }
|
71
|
+
|
72
|
+
before do
|
73
|
+
allow(agent_call).to receive(:dial)
|
74
|
+
queue.add_agent agent
|
75
|
+
queue.enqueue queued_call
|
76
|
+
end
|
77
|
+
|
78
|
+
it "sets the agent's `call` attribute" do
|
79
|
+
expect(agent.call).to be agent_call
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'records the agent in the `:agent` call variable on the queued call' do
|
83
|
+
expect(queued_call[:agent]).to eq(agent)
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when the call ends' do
|
87
|
+
let(:double_agent) { double(ElectricSlide::Agent, presence: :available).as_null_object }
|
88
|
+
|
89
|
+
before do
|
90
|
+
# add another agent so that it gets selected after the
|
91
|
+
# currently-selected agent's call ends; otherwise, the agent just
|
92
|
+
# gets returned and is immediately connected to the queued call,
|
93
|
+
# causing its state to change before the examples have a chance to
|
94
|
+
# check it
|
95
|
+
queue.add_agent double_agent
|
96
|
+
end
|
97
|
+
|
98
|
+
it "unsets the agent's `call` attribute" do
|
99
|
+
expect {
|
100
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
101
|
+
}.to change(agent, :call).from(agent_call).to(nil)
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when the return strategy is :auto" do
|
105
|
+
let(:agent_return_method) { :auto }
|
106
|
+
|
107
|
+
it "makes the agent available for a call" do
|
108
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
109
|
+
expect(queue.checkout_agent).to eql(agent)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "sets the agent's presence to :available" do
|
113
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
114
|
+
expect(queue.get_agent(agent.id).presence).to eql(:available)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when the return strategy is :manual" do
|
119
|
+
let(:agent_return_method) { :manual }
|
120
|
+
|
121
|
+
it "does not make the agent available for a call" do
|
122
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
123
|
+
expect(queue.checkout_agent).to eql(nil)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "sets the agent's presence to :after_call" do
|
127
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
128
|
+
expect(queue.get_agent(agent.id).presence).to eql(:after_call)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when the agent's and caller's calls are not joined" do
|
133
|
+
context 'and the call ends' do
|
134
|
+
before do
|
135
|
+
queue.remove_agent(double_agent)
|
136
|
+
|
137
|
+
# prevent the agent from being returned to the queue so the queued
|
138
|
+
# call isn't grabbed by the agent again, changing queued call state
|
139
|
+
# before the example can check it
|
140
|
+
agent.presence = :unavailable
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'unsets the `:agent` call variable on the queued call' do
|
144
|
+
expect {
|
145
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
146
|
+
}.to change{ queued_call[:agent] }.from(agent).to(nil)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "with callbacks" do
|
152
|
+
after do
|
153
|
+
[:connect_callback, :disconnect_callback, :connection_failed_callback, :presence_change_callback].each do |callback|
|
154
|
+
ElectricSlide::Agent.instance_variable_set "@#{callback}", nil
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "invokes the presence change callback" do
|
159
|
+
called = false
|
160
|
+
ElectricSlide::Agent.on_presence_change { |queue, agent_call, presence| called = true }
|
161
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
162
|
+
expect(called).to be true
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "when the agent's and caller's calls are joined" do
|
168
|
+
before do
|
169
|
+
queued_call << Punchblock::Event::Joined.new(timestamp: connected_time)
|
170
|
+
agent_call << Punchblock::Event::Joined.new(timestamp: connected_time)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "records the connection time in the :electric_slide_connected_at call variable on the queued call" do
|
174
|
+
expect(queued_call[:electric_slide_connected_at]).to eq(connected_time)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "with connection type :bridge" do
|
180
|
+
let(:connection_type) { :bridge }
|
181
|
+
|
182
|
+
before do
|
183
|
+
allow(agent_call).to receive(:active?) { true }
|
184
|
+
allow(queued_call).to receive(:hangup) { true }
|
185
|
+
agent.call = agent_call
|
186
|
+
queue.add_agent agent
|
187
|
+
|
188
|
+
allow(agent_call).to receive(:join) do
|
189
|
+
agent_call << Punchblock::Event::Joined.new(timestamp: connected_time)
|
190
|
+
queued_call << Punchblock::Event::Joined.new(timestamp: connected_time)
|
191
|
+
end
|
192
|
+
queue.enqueue queued_call
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'records the agent in the `:agent` call variable on the queued call' do
|
196
|
+
expect(queued_call[:agent]).to eq(agent)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "records the connection time in the :electric_slide_connected_at call variable on the queued call" do
|
200
|
+
expect(queued_call[:electric_slide_connected_at]).to eq(connected_time)
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'when the call ends' do
|
204
|
+
it "unsets the agent's `call` attribute" do
|
205
|
+
expect {
|
206
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
207
|
+
}.to change(agent, :call).from(agent_call).to(nil)
|
208
|
+
end
|
209
|
+
|
210
|
+
it "marks the agent :unavailable" do
|
211
|
+
expect {
|
212
|
+
agent_call << Punchblock::Event::End.new(reason: :hangup)
|
213
|
+
}.to change(agent, :presence).from(:on_call).to(:unavailable)
|
214
|
+
end
|
215
|
+
|
216
|
+
context "when the return strategy is :auto" do
|
217
|
+
let(:agent_return_method) { :auto }
|
218
|
+
|
219
|
+
it "makes the agent available for a call" do
|
220
|
+
agent_call << Punchblock::Event::Unjoined.new
|
221
|
+
expect(queue.checkout_agent).to eql(agent)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "sets the agent's presence to :available" do
|
225
|
+
agent_call << Punchblock::Event::Unjoined.new
|
226
|
+
expect(queue.get_agent(agent.id).presence).to eql(:available)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context "when the return strategy is :manual" do
|
231
|
+
let(:agent_return_method) { :manual }
|
232
|
+
|
233
|
+
it "does not make the agent available for a call" do
|
234
|
+
agent_call << Punchblock::Event::Unjoined.new
|
235
|
+
expect(queue.checkout_agent).to eql(nil)
|
236
|
+
end
|
237
|
+
|
238
|
+
it "sets the agent's presence to :after_call" do
|
239
|
+
agent_call << Punchblock::Event::Unjoined.new
|
240
|
+
expect(queue.get_agent(agent.id).presence).to eql(:after_call)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
26
245
|
end
|
27
246
|
|
28
|
-
|
29
|
-
queue.
|
30
|
-
|
31
|
-
|
32
|
-
|
247
|
+
describe '#add_agent' do
|
248
|
+
let(:queue) { ElectricSlide::CallQueue.new }
|
249
|
+
let(:agent) { ElectricSlide::Agent.new(id: '1', address: 'agent@example.com') }
|
250
|
+
|
251
|
+
before do
|
252
|
+
allow(agent).to receive(:call) { Adhearsion::OutboundCall.new }
|
253
|
+
end
|
254
|
+
|
255
|
+
it "associates the agent with in the queue" do
|
256
|
+
expect {
|
257
|
+
queue.add_agent agent
|
258
|
+
}.to change(queue, :get_agents).from([]).to([agent])
|
259
|
+
end
|
260
|
+
|
261
|
+
it "makes the agent available to take calls" do
|
262
|
+
expect {
|
263
|
+
queue.add_agent agent
|
264
|
+
}.to change(queue, :checkout_agent).from(nil).to(agent)
|
265
|
+
end
|
266
|
+
|
267
|
+
it "connects the agent to waiting queued calls"
|
268
|
+
|
269
|
+
context 'when given an agent already in the queue' do
|
270
|
+
before do
|
271
|
+
queue.add_agent(agent)
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'should raise an error' do
|
275
|
+
expect{
|
276
|
+
queue.add_agent(agent)
|
277
|
+
}.to raise_error(ElectricSlide::CallQueue::DuplicateAgentError)
|
278
|
+
end
|
279
|
+
end
|
33
280
|
end
|
34
281
|
|
35
|
-
|
36
|
-
|
282
|
+
describe '#return_agent' do
|
283
|
+
let(:queue) { ElectricSlide::CallQueue.new }
|
284
|
+
let(:agent) { ElectricSlide::Agent.new(id: '1', address: 'agent@example.com', presence: :on_call) }
|
285
|
+
|
286
|
+
before do
|
287
|
+
allow(agent).to receive(:call) { Adhearsion::OutboundCall.new }
|
288
|
+
end
|
289
|
+
|
290
|
+
context 'when the agent is a member of the queue' do
|
291
|
+
before do
|
292
|
+
queue.add_agent agent
|
293
|
+
end
|
294
|
+
|
295
|
+
it "sets the agent presence available" do
|
296
|
+
expect {
|
297
|
+
queue.return_agent agent
|
298
|
+
}.to change(agent, :presence).from(:on_call).to(:available)
|
299
|
+
end
|
300
|
+
|
301
|
+
it "makes the agent available to take calls" do
|
302
|
+
expect {
|
303
|
+
queue.return_agent agent
|
304
|
+
}.to change(queue, :checkout_agent).from(nil).to(agent)
|
305
|
+
end
|
306
|
+
|
307
|
+
context "when returned with some presence other than available" do
|
308
|
+
it "reflects that status on the agent" do
|
309
|
+
expect {
|
310
|
+
queue.return_agent agent, :after_call
|
311
|
+
}.to change(agent, :presence).from(:on_call).to(:after_call)
|
312
|
+
end
|
313
|
+
|
314
|
+
it "does not make the agent available to take calls" do
|
315
|
+
expect {
|
316
|
+
queue.return_agent agent, :after_call
|
317
|
+
}.to_not change { queue.checkout_agent }
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
context 'when given an agent not in the queue' do
|
323
|
+
it 'should cleanly return false' do
|
324
|
+
expect(queue.return_agent(agent)).to be(false)
|
325
|
+
end
|
326
|
+
|
327
|
+
context 'when called with a bang' do
|
328
|
+
it 'should raise an error' do
|
329
|
+
expect{
|
330
|
+
queue.return_agent!(agent)
|
331
|
+
}.to raise_error(ElectricSlide::CallQueue::MissingAgentError)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
37
335
|
end
|
38
336
|
|
39
|
-
|
40
|
-
|
337
|
+
describe '#remove_agent' do
|
338
|
+
let(:queue) { ElectricSlide::CallQueue.new }
|
339
|
+
let(:agent) { ElectricSlide::Agent.new(id: '1', address: 'agent@example.com', presence: :available) }
|
340
|
+
|
341
|
+
before do
|
342
|
+
queue.add_agent agent
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'sets the agent presence to `:unavailable`' do
|
346
|
+
expect {
|
347
|
+
queue.remove_agent agent
|
348
|
+
}.to change(agent, :presence).from(:available).to(:unavailable)
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'invokes the presence change callback' do
|
352
|
+
called = false
|
353
|
+
ElectricSlide::Agent.on_presence_change { |queue, agent_call, presence| called = true }
|
354
|
+
queue.remove_agent agent
|
355
|
+
expect(called).to be
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'takes the agent out of the call rotation' do
|
359
|
+
expect {
|
360
|
+
queue.remove_agent agent
|
361
|
+
}.to change(queue, :checkout_agent).from(agent).to(nil)
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'removes the agent from the queue' do
|
365
|
+
queue.remove_agent agent
|
366
|
+
expect(queue.get_agents).to_not include(agent)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
describe '#update' do
|
371
|
+
let(:queue) {
|
372
|
+
ElectricSlide::CallQueue.new(
|
373
|
+
agent_strategy: ElectricSlide::AgentStrategy::LongestIdle,
|
374
|
+
connection_type: :call,
|
375
|
+
agent_return_method: :auto
|
376
|
+
)
|
377
|
+
}
|
378
|
+
|
379
|
+
it 'updates all the given attributes' do
|
380
|
+
queue.update(
|
381
|
+
agent_strategy: ElectricSlide::AgentStrategy::FixedPriority,
|
382
|
+
connection_type: :bridge,
|
383
|
+
agent_return_method: :manual
|
384
|
+
)
|
385
|
+
expect(queue.agent_strategy).to eq(ElectricSlide::AgentStrategy::FixedPriority)
|
386
|
+
expect(queue.connection_type).to eq(:bridge)
|
387
|
+
expect(queue.agent_return_method).to eq(:manual)
|
388
|
+
end
|
389
|
+
|
390
|
+
context 'when given an unrecognized attribute' do
|
391
|
+
it 'does not raise an error' do
|
392
|
+
expect{
|
393
|
+
queue.update(foo: :bar)
|
394
|
+
}.to_not raise_exception
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
context 'when given `nil`' do
|
399
|
+
it 'does not raise an error' do
|
400
|
+
expect{
|
401
|
+
queue.update(foo: :bar)
|
402
|
+
}.to_not raise_exception
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
describe '#agent_strategy=' do
|
408
|
+
let(:queue) {
|
409
|
+
ElectricSlide::CallQueue.new(
|
410
|
+
agent_strategy: ElectricSlide::AgentStrategy::LongestIdle,
|
411
|
+
connection_type: :call,
|
412
|
+
agent_return_method: :auto
|
413
|
+
)
|
414
|
+
}
|
415
|
+
|
416
|
+
it 'returns the given strategy class' do
|
417
|
+
expect(queue.agent_strategy = ElectricSlide::AgentStrategy::FixedPriority).to eq(ElectricSlide::AgentStrategy::FixedPriority)
|
418
|
+
end
|
419
|
+
|
420
|
+
it 'assigns a new strategy' do
|
421
|
+
expect(ElectricSlide::AgentStrategy::FixedPriority).to receive(:new)
|
422
|
+
queue.agent_strategy = ElectricSlide::AgentStrategy::FixedPriority
|
423
|
+
end
|
424
|
+
|
425
|
+
it 'returns all agents to the queue (strategy)' do
|
426
|
+
agent = double(ElectricSlide::Agent, address: '100', presence: :available, priority: 100).as_null_object
|
427
|
+
queue.add_agent(agent)
|
428
|
+
|
429
|
+
queue.agent_strategy = ElectricSlide::AgentStrategy::FixedPriority
|
430
|
+
expect(queue.available_agent_summary).to eq({ total: 1, priorities: { 100 => 1 }})
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe '#connection_type=' do
|
435
|
+
context 'when given an invalid connection type' do
|
436
|
+
it 'raises an `InvalidConnectionType` exception' do
|
437
|
+
expect{
|
438
|
+
queue.connection_type = :party_line
|
439
|
+
}.to raise_exception(ElectricSlide::CallQueue::InvalidConnectionType)
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
describe '#agent_return_method=' do
|
445
|
+
context 'when given an invalid agent return method' do
|
446
|
+
it 'raises an `InvalidRequeueMethod` exception' do
|
447
|
+
expect{
|
448
|
+
queue.agent_return_method = :semiauto
|
449
|
+
}.to raise_exception(ElectricSlide::CallQueue::InvalidRequeueMethod)
|
450
|
+
end
|
451
|
+
end
|
41
452
|
end
|
42
453
|
end
|