queri 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/queri.rb +55 -102
- data/lib/queri/aggregate_report_helpers.rb +1 -1
- data/lib/queri/composite_agent_level_report_helpers.rb +1 -1
- data/lib/queri/composite_by_hour_report_helpers.rb +1 -1
- data/lib/queri/composite_report_helpers.rb +1 -1
- data/lib/queri/helpers/time_helpers.rb +10 -0
- data/lib/queri/request.rb +52 -0
- data/lib/queri/version.rb +1 -1
- data/lib/queri/xml_client.rb +60 -0
- data/spec/helpers/time_helpers_spec.rb +114 -0
- data/spec/queri_spec.rb +1 -114
- data/spec/stats/answered_calls/transfers_spec.rb +1 -1
- data/spec/stats/unanswered_calls/unanswered_outbound_calls_by_agent_spec.rb +1 -1
- data/spec/support/shared/shared_examples_for_private_constant.rb +1 -1
- data/spec/xml_client_spec.rb +117 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c46d2d6c7692bf85dc17b981507c647140edd18c
|
4
|
+
data.tar.gz: 7b3068a94ad86a6b991d49c674a9116f22c6be2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f2e65feb04706ea516319c9fa89a76ce639af989645a8e56b2f67eb2e2058c5ec404e0574f149dc6813a09ebf4a093d4d2cce2165e937492f127c3288e84a09
|
7
|
+
data.tar.gz: 409f9605ed2f3dbf5875f0aefe0bcc826ccb2ab8478f4a1ab6634cbd38313acabb8ac6b2f21593dfd0d712ae3e2e9f90ff9ac5a3df6f2b756967518a20946e41
|
data/lib/queri.rb
CHANGED
@@ -3,114 +3,67 @@ require "yaml"
|
|
3
3
|
require "xmlrpc/client"
|
4
4
|
require 'active_support/ordered_hash'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
lib = File.expand_path(File.dirname(__FILE__))
|
7
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
8
|
+
|
9
|
+
# Load helpers
|
10
|
+
require "queri/helpers/time_helpers"
|
11
|
+
require "queri/realtime_arg_helpers"
|
12
|
+
require "queri/arg_helpers"
|
13
|
+
require "queri/aggregate_report_helpers"
|
14
|
+
require "queri/composite_agent_level_report_helpers"
|
15
|
+
require "queri/composite_by_hour_report_helpers"
|
16
|
+
require "queri/composite_report_helpers"
|
17
|
+
|
18
|
+
# Load client/request libraries
|
19
|
+
require "queri/xml_client"
|
20
|
+
require "queri/request"
|
21
|
+
|
22
|
+
# Load report methods
|
23
|
+
require "queri/stats"
|
24
|
+
require "queri/realtime"
|
25
|
+
|
26
|
+
# Load Stats report classes
|
27
|
+
require "queri/stats/agents_and_sessions"
|
28
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/agents_and_sessions", "*.rb" ) ].each {|f| require f }
|
29
|
+
require "queri/stats/answered_calls"
|
30
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/answered_calls", "*.rb" ) ].each {|f| require f }
|
31
|
+
require "queri/stats/call_distribution_by_day"
|
32
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/call_distribution_by_day", "*.rb" ) ].each {|f| require f }
|
33
|
+
require "queri/stats/call_distribution_by_day_of_week"
|
34
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/call_distribution_by_day_of_week", "*.rb" ) ].each {|f| require f }
|
35
|
+
require "queri/stats/call_distribution_by_hour"
|
36
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/call_distribution_by_hour", "*.rb" ) ].each {|f| require f }
|
37
|
+
require "queri/stats/call_outcomes"
|
38
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/call_outcomes", "*.rb" ) ].each {|f| require f }
|
39
|
+
require "queri/stats/details_of_agent_sessions_and_pauses"
|
40
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/details_of_agent_sessions_and_pauses", "*.rb" ) ].each {|f| require f }
|
41
|
+
require "queri/stats/details_of_answered_calls"
|
42
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/details_of_answered_calls", "*.rb" ) ].each {|f| require f }
|
43
|
+
require "queri/stats/details_of_unanswered_calls"
|
44
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/details_of_unanswered_calls", "*.rb" ) ].each {|f| require f }
|
45
|
+
require "queri/stats/distributions"
|
46
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/distributions", "*.rb" ) ].each {|f| require f }
|
47
|
+
require "queri/stats/unanswered_calls"
|
48
|
+
Dir[ File.join( File.dirname(__FILE__), "queri/stats/unanswered_calls", "*.rb" ) ].each {|f| require f }
|
49
|
+
|
50
|
+
# Load Realtime report classes
|
51
|
+
require "queri/realtime/agents"
|
52
|
+
require "queri/realtime/calls"
|
53
|
+
require "queri/realtime/queues"
|
9
54
|
|
10
55
|
module Queri
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@config = {
|
16
|
-
:host => "127.0.0.1",
|
17
|
-
:path => "/path/to/queuemetrics.do",
|
18
|
-
:port => "8080",
|
19
|
-
:username => "username",
|
20
|
-
:password => "some_secret"
|
21
|
-
}
|
22
|
-
|
23
|
-
@valid_config_keys = @config.keys
|
24
|
-
|
25
|
-
@@server = nil
|
26
|
-
|
27
|
-
private_constant :LOGFILE, :PERIOD, :AGENT_FILTER
|
28
|
-
|
29
|
-
def self.config
|
30
|
-
@config
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.configure opts={}
|
34
|
-
raise ArgumentError, "expected hash, got something else" if opts.class != Hash
|
35
|
-
unless opts.empty?
|
36
|
-
if (@valid_config_keys - opts.keys).any?
|
37
|
-
puts "WARNING: erroneous keys given to ::config. Acceptible keys include #{@valid_config_keys}"
|
38
|
-
end
|
39
|
-
if (opts.keys & @valid_config_keys).empty?
|
40
|
-
raise ArgumentError, "erroneous keys given to ::config. Acceptible keys include #{@valid_config_keys}"
|
41
|
-
else
|
42
|
-
opts.each {|k,v| @config[k.to_sym] = v if @valid_config_keys.include?(k.to_sym)}
|
43
|
-
@@server = XMLRPC::Client.new(host = @config[:host], path = @config[:path], port = @config[:port])
|
44
|
-
end
|
56
|
+
class << self
|
57
|
+
def config
|
58
|
+
Queri::XmlClient.config
|
45
59
|
end
|
46
|
-
end
|
47
60
|
|
48
|
-
|
49
|
-
|
50
|
-
begin
|
51
|
-
config = YAML.load(IO.read(path_to_yaml_file))
|
52
|
-
rescue Errno::ENOENT
|
53
|
-
raise LoadError, "the specified configuration file could not be found"
|
54
|
-
rescue Psych::SyntaxError
|
55
|
-
raise LoadError, "the specified configuration file contains invalid syntax"
|
61
|
+
def configure opts={}
|
62
|
+
Queri::XmlClient.configure opts
|
56
63
|
end
|
57
|
-
configure(config)
|
58
|
-
@@server = XMLRPC::Client.new(host = @config[:host], path = @config[:path], port = @config[:port])
|
59
|
-
end
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
request = Request.new(*args)
|
64
|
-
response = @@server.call(*request.parameters)
|
65
|
-
return response[request.report.class.xml_code]
|
66
|
-
end
|
67
|
-
|
68
|
-
class Request
|
69
|
-
attr_reader :report
|
70
|
-
|
71
|
-
def initialize *args
|
72
|
-
raise ArgumentError, "expected arguments: queues(Array), report(Stats or Realtime obj), period_start(Time or Nil), period_end(Time or Nil)" unless valid_args?(args)
|
73
|
-
@queues, @report, @period_start, @period_end = validate_args(args)
|
74
|
-
end
|
75
|
-
|
76
|
-
def parameters
|
77
|
-
if @period_start.nil? && @period_end.nil?
|
78
|
-
[@report.class.query_method, @queues.join("|"), Queri.config[:username], Queri.config[:password], LOGFILE, AGENT_FILTER, [@report.class.xml_code]]
|
79
|
-
else
|
80
|
-
[@report.class.query_method, @queues.join("|"), Queri.config[:username], Queri.config[:password], LOGFILE, PERIOD, @period_start, @period_end, AGENT_FILTER, [@report.class.xml_code]]
|
81
|
-
end
|
65
|
+
def configure_with path_to_yaml_file
|
66
|
+
Queri::XmlClient.configure_with path_to_yaml_file
|
82
67
|
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def valid_args? args
|
87
|
-
valid = true
|
88
|
-
valid = false if args[0].class != Array
|
89
|
-
valid = false if args[1].class == NilClass
|
90
|
-
valid = false if (args[2].class != NilClass && args[2].class != Time)
|
91
|
-
valid = false if (args[3].class != NilClass && args[3].class != Time)
|
92
|
-
return valid
|
93
|
-
end
|
94
|
-
|
95
|
-
def validate_args args
|
96
|
-
raise ArgumentError, "queues array cannot be empty" if args[0].empty?
|
97
|
-
if args[1].class.name.include?("Queri::Stats::")
|
98
|
-
if (args[2].nil? || args[3].nil?)
|
99
|
-
raise ArgumentError, "Queri::Stats reports require non-nil period start and end times"
|
100
|
-
end
|
101
|
-
elsif args[1].class.name.include?("Queri::Realtime::")
|
102
|
-
unless (args[2].nil? && args[3].nil?)
|
103
|
-
raise ArgumentError, "Queri::Realtime reports require nil period start and end times"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
args[2] = format_time(args[2])
|
107
|
-
args[3] = format_time(args[3])
|
108
|
-
return args
|
109
|
-
end
|
110
|
-
|
111
|
-
def format_time time
|
112
|
-
return time unless time.respond_to?(:strftime)
|
113
|
-
time.strftime("%Y-%m-%d.%H:%M:%S")
|
114
|
-
end
|
115
68
|
end
|
116
69
|
end
|
@@ -2,7 +2,7 @@ module AggregateReportHelpers
|
|
2
2
|
private
|
3
3
|
|
4
4
|
def parse_response
|
5
|
-
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
5
|
+
r = Queri::XmlClient.send_request(@queues, self, @period_start, @period_end)
|
6
6
|
pairs = self.class.key_translations.each_pair
|
7
7
|
r.shift
|
8
8
|
new_metrics = r.map do |metric|
|
@@ -2,7 +2,7 @@ module CompositeAgentLevelReportHelpers
|
|
2
2
|
private
|
3
3
|
|
4
4
|
def parse_response
|
5
|
-
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
5
|
+
r = Queri::XmlClient.send_request(@queues, self, @period_start, @period_end)
|
6
6
|
new_keys = self.class.keys
|
7
7
|
r.shift
|
8
8
|
new_metrics = Hash.new {|h,k| h[k] = []}
|
@@ -2,7 +2,7 @@ module CompositeByHourReportHelpers
|
|
2
2
|
private
|
3
3
|
|
4
4
|
def parse_response
|
5
|
-
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
5
|
+
r = Queri::XmlClient.send_request(@queues, self, @period_start, @period_end)
|
6
6
|
k_t = self.class.key_translations
|
7
7
|
column_headers = r.shift
|
8
8
|
new_headers = []
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Queri
|
2
|
+
module Helpers
|
3
|
+
module TimeHelpers
|
4
|
+
def self.time_string_to_seconds time_string
|
5
|
+
base_60_digits = time_string[ (time_string.index(/\d/))..-1 ].split(?:).reverse.map(&:to_i)
|
6
|
+
base_60_digits.map.with_index {|d,i| d * (60 ** i)}.reduce(:+)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Queri
|
2
|
+
module XmlClient
|
3
|
+
class Request
|
4
|
+
attr_reader :report
|
5
|
+
|
6
|
+
def initialize args
|
7
|
+
raise ArgumentError, "expected arguments: queues(Array), report(Stats or Realtime obj), period_start(Time or Nil), period_end(Time or Nil)" unless valid_args?(args)
|
8
|
+
@queues, @report, @period_start, @period_end = validate_args(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def parameters
|
12
|
+
if @period_start.nil? && @period_end.nil?
|
13
|
+
[@report.class.query_method, @queues.join("|"), Queri::XmlClient.config[:username], Queri::XmlClient.config[:password], LOGFILE, AGENT_FILTER, [@report.class.xml_code]]
|
14
|
+
else
|
15
|
+
[@report.class.query_method, @queues.join("|"), Queri::XmlClient.config[:username], Queri::XmlClient.config[:password], LOGFILE, PERIOD, @period_start, @period_end, AGENT_FILTER, [@report.class.xml_code]]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def valid_args? args
|
22
|
+
valid = true
|
23
|
+
valid = false if args[0].class != Array
|
24
|
+
valid = false if args[1].class == NilClass
|
25
|
+
valid = false if (args[2].class != NilClass && args[2].class != Time)
|
26
|
+
valid = false if (args[3].class != NilClass && args[3].class != Time)
|
27
|
+
return valid
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_args args
|
31
|
+
raise ArgumentError, "queues array cannot be empty" if args[0].empty?
|
32
|
+
if args[1].class.name.include?("Queri::Stats::")
|
33
|
+
if (args[2].nil? || args[3].nil?)
|
34
|
+
raise ArgumentError, "Queri::Stats reports require non-nil period start and end times"
|
35
|
+
end
|
36
|
+
elsif args[1].class.name.include?("Queri::Realtime::")
|
37
|
+
unless (args[2].nil? && args[3].nil?)
|
38
|
+
raise ArgumentError, "Queri::Realtime reports require nil period start and end times"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
args[2] = format_time(args[2])
|
42
|
+
args[3] = format_time(args[3])
|
43
|
+
return args
|
44
|
+
end
|
45
|
+
|
46
|
+
def format_time time
|
47
|
+
return time unless time.respond_to?(:strftime)
|
48
|
+
time.strftime("%Y-%m-%d.%H:%M:%S")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/queri/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Queri
|
2
|
+
module XmlClient
|
3
|
+
LOGFILE = ""
|
4
|
+
PERIOD = ""
|
5
|
+
AGENT_FILTER = ""
|
6
|
+
|
7
|
+
@config = {
|
8
|
+
:host => "127.0.0.1",
|
9
|
+
:path => "/path/to/queuemetrics.do",
|
10
|
+
:port => "8080",
|
11
|
+
:username => "username",
|
12
|
+
:password => "some_secret"
|
13
|
+
}
|
14
|
+
|
15
|
+
@valid_config_keys = @config.keys
|
16
|
+
|
17
|
+
@@server = nil
|
18
|
+
|
19
|
+
private_constant :LOGFILE, :PERIOD, :AGENT_FILTER
|
20
|
+
|
21
|
+
def self.config
|
22
|
+
@config
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.configure opts={}
|
26
|
+
raise ArgumentError, "expected hash, got something else" if opts.class != Hash
|
27
|
+
unless opts.empty?
|
28
|
+
if (@valid_config_keys - opts.keys).any?
|
29
|
+
puts "WARNING: erroneous keys given to ::config. Acceptible keys include #{@valid_config_keys}"
|
30
|
+
end
|
31
|
+
if (opts.keys & @valid_config_keys).empty?
|
32
|
+
raise ArgumentError, "erroneous keys given to ::config. Acceptible keys include #{@valid_config_keys}"
|
33
|
+
else
|
34
|
+
opts.each {|k,v| @config[k.to_sym] = v if @valid_config_keys.include?(k.to_sym)}
|
35
|
+
@@server = XMLRPC::Client.new(host = @config[:host], path = @config[:path], port = @config[:port])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.configure_with path_to_yaml_file
|
41
|
+
raise ArgumentError, "expected path to yaml file as string, got something else" if path_to_yaml_file.class != String
|
42
|
+
begin
|
43
|
+
config = YAML.load(IO.read(path_to_yaml_file))
|
44
|
+
rescue Errno::ENOENT
|
45
|
+
raise LoadError, "the specified configuration file could not be found"
|
46
|
+
rescue Psych::SyntaxError
|
47
|
+
raise LoadError, "the specified configuration file contains invalid syntax"
|
48
|
+
end
|
49
|
+
configure(config)
|
50
|
+
@@server = XMLRPC::Client.new(host = @config[:host], path = @config[:path], port = @config[:port])
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.send_request *args
|
54
|
+
raise LoadError, "client configs not set. Assign by passing a hash to Queri.configure or a yaml file path to Queri.configure_with" if @@server.nil?
|
55
|
+
request = Request.new(args)
|
56
|
+
response = @@server.call(*request.parameters)
|
57
|
+
return response[request.report.class.xml_code]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Queri
|
4
|
+
module Helpers
|
5
|
+
describe TimeHelpers do
|
6
|
+
describe "::time_string_to_seconds" do
|
7
|
+
let(:time) { "01:00 " }
|
8
|
+
|
9
|
+
subject { TimeHelpers.time_string_to_seconds(time) }
|
10
|
+
|
11
|
+
it "should respond" do
|
12
|
+
expect{ subject }.to_not raise_error
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return a Fixnum" do
|
16
|
+
subject.should be_a Fixnum
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should properly parse a base case time" do
|
20
|
+
TimeHelpers.time_string_to_seconds("00:00 ").should eq 0
|
21
|
+
end
|
22
|
+
|
23
|
+
context "given leading non-numeric characters" do
|
24
|
+
let(:time) { "a time01:00" }
|
25
|
+
|
26
|
+
it "should accurately parse the string" do
|
27
|
+
subject.should eq 60
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "given seconds in the time string" do
|
32
|
+
let(:seconds_count) { 23 }
|
33
|
+
let(:time) { "00:#{seconds_count} " }
|
34
|
+
|
35
|
+
it "should return that value" do
|
36
|
+
subject.should eq seconds_count
|
37
|
+
end
|
38
|
+
|
39
|
+
context "greater than the number of seconds in a minute" do
|
40
|
+
let(:seconds_count) { 61 }
|
41
|
+
let(:time) { "00:#{seconds_count} " }
|
42
|
+
|
43
|
+
it "should return that value" do
|
44
|
+
subject.should eq seconds_count
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "given minutes in the time string" do
|
50
|
+
let(:minutes_count) { 5 }
|
51
|
+
let(:time) { "#{minutes_count}:00 " }
|
52
|
+
|
53
|
+
it "should return that value cast to seconds" do
|
54
|
+
subject.should eq minutes_count * 60
|
55
|
+
end
|
56
|
+
|
57
|
+
context "and seconds" do
|
58
|
+
let(:seconds_count) { 21 }
|
59
|
+
let(:time) { "#{minutes_count}:#{seconds_count} " }
|
60
|
+
|
61
|
+
it "should convert that value appropriately" do
|
62
|
+
subject.should eq (minutes_count * 60) + seconds_count
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "greater than the number of minutes in an hour" do
|
67
|
+
let(:minutes_count) { 61 }
|
68
|
+
let(:time) { "#{minutes_count}:00 " }
|
69
|
+
|
70
|
+
it "should return that value" do
|
71
|
+
subject.should eq minutes_count * 60
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "given hours in the time string" do
|
77
|
+
let(:hours_count) { 2 }
|
78
|
+
let(:time) { "#{hours_count}:00:00 " }
|
79
|
+
|
80
|
+
it "should return that value cast to seconds" do
|
81
|
+
subject.should eq hours_count * 3600
|
82
|
+
end
|
83
|
+
|
84
|
+
context "and minutes" do
|
85
|
+
let(:minutes_count) { 35 }
|
86
|
+
let(:time) { "#{hours_count}:#{minutes_count}:00 " }
|
87
|
+
|
88
|
+
it "should convert that value appropriately" do
|
89
|
+
subject.should eq (hours_count * 3600) + (minutes_count * 60)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "and seconds" do
|
94
|
+
let(:seconds_count) { 17 }
|
95
|
+
let(:time) { "#{hours_count}:00:#{seconds_count} " }
|
96
|
+
|
97
|
+
it "should convert that value appropriately" do
|
98
|
+
subject.should eq (hours_count * 3600) + seconds_count
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "greater than the number of hours in a day" do
|
103
|
+
let(:hours_count) { 25 }
|
104
|
+
let(:time) { "#{hours_count}:00:00 " }
|
105
|
+
|
106
|
+
it "should return that value" do
|
107
|
+
subject.should eq hours_count * 3600
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/spec/queri_spec.rb
CHANGED
@@ -1,32 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Queri do
|
4
|
-
let(:queues) { ["10000"] }
|
5
|
-
let(:report) { double(Queri::Realtime::Queues) }
|
6
|
-
|
7
|
-
describe "constants" do
|
8
|
-
describe "for log file" do
|
9
|
-
let(:const_symbol) { :LOGFILE }
|
10
|
-
let(:constant) { Queri::LOGFILE }
|
11
|
-
|
12
|
-
it_behaves_like "a private constant"
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "for period" do
|
16
|
-
let(:const_symbol) { :PERIOD }
|
17
|
-
let(:constant) { Queri::PERIOD }
|
18
|
-
|
19
|
-
it_behaves_like "a private constant"
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "for agent filter" do
|
23
|
-
let(:const_symbol) { :AGENT_FILTER }
|
24
|
-
let(:constant) { Queri::AGENT_FILTER }
|
25
|
-
|
26
|
-
it_behaves_like "a private constant"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
4
|
describe "::config" do
|
31
5
|
subject { Queri.config }
|
32
6
|
|
@@ -75,7 +49,7 @@ describe Queri do
|
|
75
49
|
let(:configs) { Hash[:password, "new_secret", :foo, "bar"] }
|
76
50
|
|
77
51
|
it "should warn the user against bad data" do
|
78
|
-
Queri.should_receive(:puts).with("WARNING: erroneous keys given to ::config. Acceptible keys include #{Queri.instance_variable_get(:@valid_config_keys)}")
|
52
|
+
Queri::XmlClient.should_receive(:puts).with("WARNING: erroneous keys given to ::config. Acceptible keys include #{Queri::XmlClient.instance_variable_get(:@valid_config_keys)}")
|
79
53
|
subject
|
80
54
|
end
|
81
55
|
|
@@ -178,91 +152,4 @@ describe Queri do
|
|
178
152
|
end
|
179
153
|
end
|
180
154
|
end
|
181
|
-
|
182
|
-
describe "::send_request" do
|
183
|
-
before do
|
184
|
-
@client = double(XMLRPC::Client)
|
185
|
-
@client.stub(:call).and_return( {"xml_code" => [:keys, :for, :report]} )
|
186
|
-
end
|
187
|
-
|
188
|
-
subject { Queri.send_request(queues, report) }
|
189
|
-
|
190
|
-
context "without configurations" do
|
191
|
-
before do
|
192
|
-
@saved_configs = Queri.config.dup
|
193
|
-
Queri.class_variable_set(:@@server, nil)
|
194
|
-
end
|
195
|
-
|
196
|
-
after do
|
197
|
-
Queri.configure(@saved_configs)
|
198
|
-
end
|
199
|
-
|
200
|
-
it "should raise LoadError" do
|
201
|
-
expect{ subject }.to raise_error(LoadError)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
context "with configurations" do
|
206
|
-
|
207
|
-
before do
|
208
|
-
Queri.configure_with(File.join(File.dirname(__FILE__), 'config.yml'))
|
209
|
-
report.stub(:class).and_return( Queri::Realtime::Queues )
|
210
|
-
end
|
211
|
-
|
212
|
-
it "should respond" do
|
213
|
-
expect{ subject }.to_not raise_error
|
214
|
-
end
|
215
|
-
|
216
|
-
it "should call the XMLRPC client" do
|
217
|
-
xml_client = Queri.class_variable_get(:@@server)
|
218
|
-
Queri.class_variable_set(:@@server, @client)
|
219
|
-
subject
|
220
|
-
@client.should have_received(:call)
|
221
|
-
Queri.class_variable_set(:@@server, xml_client)
|
222
|
-
end
|
223
|
-
|
224
|
-
context "given no arguments" do
|
225
|
-
subject { Queri.send_request }
|
226
|
-
|
227
|
-
it "should raise ArgumentError" do
|
228
|
-
expect{ subject }.to raise_error(ArgumentError)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
context "given an empty queues array" do
|
233
|
-
subject { Queri.send_request([], report) }
|
234
|
-
|
235
|
-
it "should raise ArgumentError" do
|
236
|
-
expect{ subject }.to raise_error(ArgumentError)
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
context "given a Stats report object" do
|
241
|
-
context "and period_start or period_end are nil" do
|
242
|
-
let(:report) { double(Queri::Stats::AnsweredCalls::AllCalls) }
|
243
|
-
let(:period_start) { Time.now - 10 }
|
244
|
-
let(:period_end) { nil }
|
245
|
-
|
246
|
-
subject { Queri.send_request(queues, report, period_start, period_end) }
|
247
|
-
|
248
|
-
it "should raise ArgumentError" do
|
249
|
-
expect{ subject }.to raise_error(ArgumentError)
|
250
|
-
end
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
context "given a Realtime report object" do
|
255
|
-
context "and period_start or period_end are not nil" do
|
256
|
-
let(:period_start) { Time.now - 10 }
|
257
|
-
let(:period_end) { nil }
|
258
|
-
|
259
|
-
subject { Queri.send_request(queues, report, period_start, period_end) }
|
260
|
-
|
261
|
-
it "should raise ArgumentError" do
|
262
|
-
expect{ subject }.to raise_error(ArgumentError)
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
155
|
end
|
@@ -6,7 +6,7 @@ describe Queri::Stats::AnsweredCalls::Transfers do
|
|
6
6
|
|
7
7
|
before do
|
8
8
|
Queri.configure_with(File.join(File.dirname(__FILE__), '..', '..', 'config.yml'))
|
9
|
-
Queri.stub(:send_request).and_return(
|
9
|
+
Queri::XmlClient.stub(:send_request).and_return(
|
10
10
|
[["Transfer to", "N. Calls", " ", "..."],
|
11
11
|
["211", "121", "10.0%", ""],
|
12
12
|
["311", "122", "10.0%", ""]]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Queri::Stats::UnansweredCalls::UnansweredOutboundCallsByAgent do
|
3
|
+
describe Queri::Stats::UnansweredCalls::UnansweredOutboundCallsByAgent, :focus do
|
4
4
|
let(:report_class) { Queri::Stats::UnansweredCalls::UnansweredOutboundCallsByAgent }
|
5
5
|
let(:xml_code) { report_class.xml_code }
|
6
6
|
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Queri::XmlClient do
|
4
|
+
let(:module_name) { Queri::XmlClient }
|
5
|
+
let(:queues) { ["10000"] }
|
6
|
+
let(:report) { double(Queri::Realtime::Queues) }
|
7
|
+
|
8
|
+
describe "constants" do
|
9
|
+
describe "for log file" do
|
10
|
+
let(:const_symbol) { :LOGFILE }
|
11
|
+
let(:constant) { Queri::XmlClient::LOGFILE }
|
12
|
+
|
13
|
+
it_behaves_like "a private constant"
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "for period" do
|
17
|
+
let(:const_symbol) { :PERIOD }
|
18
|
+
let(:constant) { Queri::XmlClient::PERIOD }
|
19
|
+
|
20
|
+
it_behaves_like "a private constant"
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "for agent filter" do
|
24
|
+
let(:const_symbol) { :AGENT_FILTER }
|
25
|
+
let(:constant) { Queri::XmlClient::AGENT_FILTER }
|
26
|
+
|
27
|
+
it_behaves_like "a private constant"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "::send_request" do
|
32
|
+
before do
|
33
|
+
@client = double(XMLRPC::Client)
|
34
|
+
@client.stub(:call).and_return( {"xml_code" => [:keys, :for, :report]} )
|
35
|
+
end
|
36
|
+
|
37
|
+
subject { Queri::XmlClient.send_request(queues, report) }
|
38
|
+
|
39
|
+
context "without configurations" do
|
40
|
+
before do
|
41
|
+
@saved_configs = Queri::XmlClient.config.dup
|
42
|
+
Queri::XmlClient.class_variable_set(:@@server, nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
after do
|
46
|
+
Queri::XmlClient.configure(@saved_configs)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise LoadError" do
|
50
|
+
expect{ subject }.to raise_error(LoadError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "with configurations" do
|
55
|
+
|
56
|
+
before do
|
57
|
+
Queri::XmlClient.configure_with(File.join(File.dirname(__FILE__), 'config.yml'))
|
58
|
+
report.stub(:class).and_return( Queri::Realtime::Queues )
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should respond" do
|
62
|
+
expect{ subject }.to_not raise_error
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should call the XMLRPC client" do
|
66
|
+
xml_client = Queri::XmlClient.class_variable_get(:@@server)
|
67
|
+
Queri::XmlClient.class_variable_set(:@@server, @client)
|
68
|
+
subject
|
69
|
+
@client.should have_received(:call)
|
70
|
+
Queri::XmlClient.class_variable_set(:@@server, xml_client)
|
71
|
+
end
|
72
|
+
|
73
|
+
context "given no arguments" do
|
74
|
+
subject { Queri::XmlClient.send_request }
|
75
|
+
|
76
|
+
it "should raise ArgumentError" do
|
77
|
+
expect{ subject }.to raise_error(ArgumentError)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "given an empty queues array" do
|
82
|
+
subject { Queri::XmlClient.send_request([], report) }
|
83
|
+
|
84
|
+
it "should raise ArgumentError" do
|
85
|
+
expect{ subject }.to raise_error(ArgumentError)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "given a Stats report object" do
|
90
|
+
context "and period_start or period_end are nil" do
|
91
|
+
let(:report) { double(Queri::Stats::AnsweredCalls::AllCalls) }
|
92
|
+
let(:period_start) { Time.now - 10 }
|
93
|
+
let(:period_end) { nil }
|
94
|
+
|
95
|
+
subject { Queri::XmlClient.send_request(queues, report, period_start, period_end) }
|
96
|
+
|
97
|
+
it "should raise ArgumentError" do
|
98
|
+
expect{ subject }.to raise_error(ArgumentError)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "given a Realtime report object" do
|
104
|
+
context "and period_start or period_end are not nil" do
|
105
|
+
let(:period_start) { Time.now - 10 }
|
106
|
+
let(:period_end) { nil }
|
107
|
+
|
108
|
+
subject { Queri::XmlClient.send_request(queues, report, period_start, period_end) }
|
109
|
+
|
110
|
+
it "should raise ArgumentError" do
|
111
|
+
expect{ subject }.to raise_error(ArgumentError)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brad Rice
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -85,11 +85,13 @@ files:
|
|
85
85
|
- lib/queri/composite_agent_level_report_helpers.rb
|
86
86
|
- lib/queri/composite_by_hour_report_helpers.rb
|
87
87
|
- lib/queri/composite_report_helpers.rb
|
88
|
+
- lib/queri/helpers/time_helpers.rb
|
88
89
|
- lib/queri/realtime.rb
|
89
90
|
- lib/queri/realtime/agents.rb
|
90
91
|
- lib/queri/realtime/calls.rb
|
91
92
|
- lib/queri/realtime/queues.rb
|
92
93
|
- lib/queri/realtime_arg_helpers.rb
|
94
|
+
- lib/queri/request.rb
|
93
95
|
- lib/queri/stats.rb
|
94
96
|
- lib/queri/stats/agents_and_sessions.rb
|
95
97
|
- lib/queri/stats/agents_and_sessions/agent_availability.rb
|
@@ -182,7 +184,9 @@ files:
|
|
182
184
|
- lib/queri/stats/unanswered_calls/unanswered_calls_distribution_by_length.rb
|
183
185
|
- lib/queri/stats/unanswered_calls/unanswered_outbound_calls_by_agent.rb
|
184
186
|
- lib/queri/version.rb
|
187
|
+
- lib/queri/xml_client.rb
|
185
188
|
- queri.gemspec
|
189
|
+
- spec/helpers/time_helpers_spec.rb
|
186
190
|
- spec/queri_spec.rb
|
187
191
|
- spec/realtime/agents_spec.rb
|
188
192
|
- spec/realtime/calls_spec.rb
|
@@ -292,6 +296,7 @@ files:
|
|
292
296
|
- spec/support/shared/shared_examples_for_report_method.rb
|
293
297
|
- spec/support/shared/shared_examples_for_stats_report.rb
|
294
298
|
- spec/support/time_helper.rb
|
299
|
+
- spec/xml_client_spec.rb
|
295
300
|
homepage: ''
|
296
301
|
licenses:
|
297
302
|
- MIT
|
@@ -317,6 +322,7 @@ signing_key:
|
|
317
322
|
specification_version: 4
|
318
323
|
summary: Send requests to QM's XMLRPC client and receive human-readable responses
|
319
324
|
test_files:
|
325
|
+
- spec/helpers/time_helpers_spec.rb
|
320
326
|
- spec/queri_spec.rb
|
321
327
|
- spec/realtime/agents_spec.rb
|
322
328
|
- spec/realtime/calls_spec.rb
|
@@ -426,3 +432,4 @@ test_files:
|
|
426
432
|
- spec/support/shared/shared_examples_for_report_method.rb
|
427
433
|
- spec/support/shared/shared_examples_for_stats_report.rb
|
428
434
|
- spec/support/time_helper.rb
|
435
|
+
- spec/xml_client_spec.rb
|