garb 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +178 -0
- data/Rakefile +54 -0
- data/lib/extensions/happymapper.rb +67 -0
- data/lib/extensions/operator.rb +20 -0
- data/lib/extensions/string.rb +13 -0
- data/lib/extensions/symbol.rb +36 -0
- data/lib/garb.rb +70 -0
- data/lib/garb/authentication_request.rb +46 -0
- data/lib/garb/data_request.rb +28 -0
- data/lib/garb/oauth_session.rb +21 -0
- data/lib/garb/profile.rb +45 -0
- data/lib/garb/report.rb +31 -0
- data/lib/garb/report_parameter.rb +36 -0
- data/lib/garb/report_response.rb +62 -0
- data/lib/garb/resource.rb +89 -0
- data/lib/garb/session.rb +19 -0
- data/lib/garb/version.rb +13 -0
- data/test/fixtures/profile_feed.xml +33 -0
- data/test/fixtures/report_feed.xml +46 -0
- data/test/test_helper.rb +16 -0
- data/test/unit/authentication_request_test.rb +91 -0
- data/test/unit/data_request_test.rb +52 -0
- data/test/unit/garb_test.rb +9 -0
- data/test/unit/oauth_session_test.rb +11 -0
- data/test/unit/operator_test.rb +37 -0
- data/test/unit/profile_test.rb +58 -0
- data/test/unit/report_parameter_test.rb +62 -0
- data/test/unit/report_response_test.rb +29 -0
- data/test/unit/report_test.rb +71 -0
- data/test/unit/resource_test.rb +19 -0
- data/test/unit/session_test.rb +26 -0
- data/test/unit/string_test.rb +9 -0
- data/test/unit/symbol_test.rb +44 -0
- metadata +99 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
class AuthenticationRequestTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the AuthenticationRequest class" do
|
7
|
+
|
8
|
+
setup { @request = AuthenticationRequest.new('email', 'password') }
|
9
|
+
|
10
|
+
should "have a collection of parameters that include the email and password" do
|
11
|
+
expected =
|
12
|
+
{
|
13
|
+
'Email' => 'user@example.com',
|
14
|
+
'Passwd' => 'fuzzybunnies',
|
15
|
+
'accountType' => 'HOSTED_OR_GOOGLE',
|
16
|
+
'service' => 'analytics',
|
17
|
+
'source' => 'vigetLabs-garb-001'
|
18
|
+
}
|
19
|
+
|
20
|
+
request = AuthenticationRequest.new('user@example.com', 'fuzzybunnies')
|
21
|
+
assert_equal expected, request.parameters
|
22
|
+
end
|
23
|
+
|
24
|
+
should "have a URI" do
|
25
|
+
assert_equal URI.parse('https://www.google.com/accounts/ClientLogin'), @request.uri
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
should "be able to send a request to the GAAPI service" do
|
30
|
+
@request.expects(:build_request).returns('post')
|
31
|
+
response = mock {|m| m.expects(:is_a?).with(Net::HTTPOK).returns(true) }
|
32
|
+
|
33
|
+
http = mock do |m|
|
34
|
+
m.expects(:use_ssl=).with(true)
|
35
|
+
m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
36
|
+
m.expects(:request).with('post').yields(response)
|
37
|
+
end
|
38
|
+
|
39
|
+
Net::HTTP.expects(:new).with('www.google.com', 443).returns(http)
|
40
|
+
|
41
|
+
@request.send_request
|
42
|
+
end
|
43
|
+
|
44
|
+
should "be able to build a request for the GAAPI service" do
|
45
|
+
params = "param"
|
46
|
+
@request.expects(:parameters).with().returns(params)
|
47
|
+
|
48
|
+
post = mock
|
49
|
+
post.expects(:set_form_data).with(params)
|
50
|
+
|
51
|
+
Net::HTTP::Post.expects(:new).with('/accounts/ClientLogin').returns(post)
|
52
|
+
|
53
|
+
@request.build_request
|
54
|
+
end
|
55
|
+
|
56
|
+
should "be able to retrieve an auth_token from the body" do
|
57
|
+
response_data =
|
58
|
+
"SID=mysid\n" +
|
59
|
+
"LSID=mylsid\n" +
|
60
|
+
"Auth=auth_token\n"
|
61
|
+
|
62
|
+
@request.expects(:send_request).with().returns(stub(:body => response_data))
|
63
|
+
|
64
|
+
assert_equal 'auth_token', @request.auth_token
|
65
|
+
end
|
66
|
+
|
67
|
+
should "raise an exception when requesting an auth_token when the authorization fails" do
|
68
|
+
@request.stubs(:build_request)
|
69
|
+
response = mock do |m|
|
70
|
+
m.expects(:is_a?).with(Net::HTTPOK).returns(false)
|
71
|
+
end
|
72
|
+
|
73
|
+
http = stub do |s|
|
74
|
+
s.stubs(:use_ssl=)
|
75
|
+
s.stubs(:verify_mode=)
|
76
|
+
s.stubs(:request).yields(response)
|
77
|
+
end
|
78
|
+
|
79
|
+
Net::HTTP.stubs(:new).with('www.google.com', 443).returns(http)
|
80
|
+
|
81
|
+
assert_raise(Garb::AuthenticationRequest::AuthError) do
|
82
|
+
@request.send_request
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
class DataRequestTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the DataRequest class" do
|
7
|
+
|
8
|
+
should "be able to build the query string from parameters" do
|
9
|
+
parameters = {'ids' => '12345', 'metrics' => 'country'}
|
10
|
+
data_request = DataRequest.new("", parameters)
|
11
|
+
|
12
|
+
query_string = data_request.query_string
|
13
|
+
|
14
|
+
assert_match(/^\?/, query_string)
|
15
|
+
|
16
|
+
query_string.sub!(/^\?/, '')
|
17
|
+
|
18
|
+
assert_equal ["ids=12345", "metrics=country"], query_string.split('&').sort
|
19
|
+
end
|
20
|
+
|
21
|
+
should "return an empty query string if parameters are empty" do
|
22
|
+
data_request = DataRequest.new("")
|
23
|
+
assert_equal "", data_request.query_string
|
24
|
+
end
|
25
|
+
|
26
|
+
should "be able to build a uri" do
|
27
|
+
url = 'http://example.com'
|
28
|
+
expected = URI.parse('http://example.com')
|
29
|
+
|
30
|
+
assert_equal expected, DataRequest.new(url).uri
|
31
|
+
end
|
32
|
+
|
33
|
+
should "be able to make a request to the GAAPI" do
|
34
|
+
Session.expects(:auth_token).with().returns('toke')
|
35
|
+
response = mock
|
36
|
+
response.expects(:is_a?).with(Net::HTTPOK).returns(true)
|
37
|
+
|
38
|
+
http = mock do |m|
|
39
|
+
m.expects(:use_ssl=).with(true)
|
40
|
+
m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
41
|
+
m.expects(:get).with('/data?key=value', 'Authorization' => 'GoogleLogin auth=toke').returns(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
Net::HTTP.expects(:new).with('example.com', 443).returns(http)
|
45
|
+
|
46
|
+
data_request = DataRequest.new('https://example.com/data', 'key' => 'value')
|
47
|
+
assert_equal response, data_request.send_request
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
class OperatorTest < Test::Unit::TestCase
|
4
|
+
context "An instance of an Operator" do
|
5
|
+
should "lower camelize the target" do
|
6
|
+
assert_equal "ga:uniqueVisits=", Operator.new(:unique_visits, "=").to_ga
|
7
|
+
end
|
8
|
+
|
9
|
+
should "return target and operator together" do
|
10
|
+
assert_equal "ga:metric=", Operator.new(:metric, "=").to_ga
|
11
|
+
end
|
12
|
+
|
13
|
+
should "prefix the operator to the target" do
|
14
|
+
assert_equal "-ga:metric", Operator.new(:metric, "-", true).to_ga
|
15
|
+
end
|
16
|
+
|
17
|
+
should "know if it is equal to another operator" do
|
18
|
+
op1 = Operator.new(:hello, "==")
|
19
|
+
op2 = Operator.new(:hello, "==")
|
20
|
+
assert_equal op1, op2
|
21
|
+
end
|
22
|
+
|
23
|
+
should "not be equal to another operator if target, operator, or prefix is different" do
|
24
|
+
op1 = Operator.new(:hello, "==")
|
25
|
+
op2 = Operator.new(:hello, "==", true)
|
26
|
+
assert_not_equal op1, op2
|
27
|
+
|
28
|
+
op1 = Operator.new(:hello1, "==")
|
29
|
+
op2 = Operator.new(:hello2, "==")
|
30
|
+
assert_not_equal op1, op2
|
31
|
+
|
32
|
+
op1 = Operator.new(:hello, "!=")
|
33
|
+
op2 = Operator.new(:hello, "==")
|
34
|
+
assert_not_equal op1, op2
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
class ProfileTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Profile class" do
|
7
|
+
|
8
|
+
should "be able to return a list of all profiles" do
|
9
|
+
Session.stubs(:email).with().returns('user@host.com')
|
10
|
+
|
11
|
+
url = 'https://www.google.com/analytics/feeds/accounts/user@host.com'
|
12
|
+
|
13
|
+
xml = read_fixture('profile_feed.xml')
|
14
|
+
|
15
|
+
data_request = mock
|
16
|
+
data_request.expects(:send_request).with().returns(stub(:body => xml))
|
17
|
+
|
18
|
+
DataRequest.expects(:new).with(url).returns(data_request)
|
19
|
+
|
20
|
+
entries = [stub]
|
21
|
+
|
22
|
+
Profile::Entry.expects(:parse).with(xml).returns(entries)
|
23
|
+
|
24
|
+
profiles = []
|
25
|
+
entries.each do |entry|
|
26
|
+
profile = stub
|
27
|
+
profiles << profile
|
28
|
+
Garb::Profile.expects(:new).with(entry).returns(profile)
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_equal profiles, Profile.all
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
context "An instance of the Profile class" do
|
37
|
+
|
38
|
+
setup do
|
39
|
+
@entry = (Profile::Entry.parse(read_fixture('profile_feed.xml'))).first
|
40
|
+
@profile = Profile.new(@entry)
|
41
|
+
end
|
42
|
+
|
43
|
+
should "have a value for :title" do
|
44
|
+
assert_equal "Historical", @profile.title
|
45
|
+
end
|
46
|
+
|
47
|
+
should "have a value for :table_id" do
|
48
|
+
assert_equal 'ga:12345', @profile.table_id
|
49
|
+
end
|
50
|
+
|
51
|
+
should "have a value for :id" do
|
52
|
+
assert_equal '12345', @profile.id
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
class ReportParameterTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the ReportParameter class" do
|
7
|
+
setup do
|
8
|
+
@metrics = ReportParameter.new(:metrics)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "have a name" do
|
12
|
+
assert_equal "metrics", @metrics.name
|
13
|
+
end
|
14
|
+
|
15
|
+
should "have a list of elements" do
|
16
|
+
assert_equal [], @metrics.elements
|
17
|
+
end
|
18
|
+
|
19
|
+
should "be able to add new elements" do
|
20
|
+
assert_equal(@metrics, @metrics << :request_uri)
|
21
|
+
assert_equal [:request_uri], @metrics.elements
|
22
|
+
end
|
23
|
+
|
24
|
+
should "merge an array of elements" do
|
25
|
+
assert_equal(@metrics, @metrics << [:request_uri])
|
26
|
+
assert_equal [:request_uri], @metrics.elements
|
27
|
+
end
|
28
|
+
|
29
|
+
context "converting to params" do
|
30
|
+
should "be able to format the parameters into strings" do
|
31
|
+
@metrics << :request_uri
|
32
|
+
assert_equal({'metrics' => 'ga:requestUri'}, @metrics.to_params)
|
33
|
+
end
|
34
|
+
|
35
|
+
should "join multiple symbol elements" do
|
36
|
+
@metrics << :request_uri << :city
|
37
|
+
assert_equal({'metrics' => 'ga:requestUri,ga:city'}, @metrics.to_params)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "join operator elements" do
|
41
|
+
@metrics << :city.desc
|
42
|
+
assert_equal({'metrics' => '-ga:city'}, @metrics.to_params)
|
43
|
+
end
|
44
|
+
|
45
|
+
should "parameterize hash operators and join elements" do
|
46
|
+
@metrics << {:city.eql => 'New York'}
|
47
|
+
params = {'metrics' => 'ga:city%3D%3DNew+York'}
|
48
|
+
|
49
|
+
assert_equal params, @metrics.to_params
|
50
|
+
end
|
51
|
+
|
52
|
+
should "properly encode operators" do
|
53
|
+
@metrics << {:request_uri.contains => 'New York'}
|
54
|
+
params = {'metrics' => 'ga:requestUri%3D~New+York'}
|
55
|
+
|
56
|
+
assert_equal params, @metrics.to_params
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
class ReportResponseTest < Test::Unit::TestCase
|
5
|
+
context "An instance of the ReportResponse class" do
|
6
|
+
setup do
|
7
|
+
@xml = File.read(File.join(File.dirname(__FILE__), '..', "/fixtures/report_feed.xml"))
|
8
|
+
@response = ReportResponse.new(@xml)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "parse xml response with happymapper" do
|
12
|
+
h1 = {"city"=>"(not set)", "pageviews"=>"33", "country"=>"(not set)"}
|
13
|
+
h2 = {"city"=>"Kabul", "pageviews"=>"2", "country"=>"Afghanistan"}
|
14
|
+
h3 = {"city"=>"Tirana", "pageviews"=>"1", "country"=>"Albania"}
|
15
|
+
|
16
|
+
OpenStruct.expects(:new).with(h1).returns('entry1')
|
17
|
+
OpenStruct.expects(:new).with(h2).returns('entry2')
|
18
|
+
OpenStruct.expects(:new).with(h3).returns('entry3')
|
19
|
+
|
20
|
+
assert_equal(['entry1', 'entry2', 'entry3'], @response.parse)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "have results or parse them" do
|
24
|
+
@response.expects(:parse)
|
25
|
+
@response.results
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
# Also tests Garb::Resource, which is the basis for Garb::Report
|
5
|
+
class ReportTest < Test::Unit::TestCase
|
6
|
+
context "An instance of the Report class" do
|
7
|
+
setup do
|
8
|
+
@now = Time.now
|
9
|
+
Time.stubs(:now).returns(@now)
|
10
|
+
@profile = stub(:table_id => 'ga:1234')
|
11
|
+
@report = Report.new(@profile)
|
12
|
+
end
|
13
|
+
|
14
|
+
%w(metrics dimensions filters sorts).each do |param|
|
15
|
+
should "have parameters for #{param}" do
|
16
|
+
assert @report.send(:"#{param}").is_a?(ReportParameter)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
should "have default parameters" do
|
21
|
+
@report.stubs(:format_time).returns('2009-08-01')
|
22
|
+
params = {'ids' => 'ga:1234', 'start-date' => '2009-08-01', 'end-date' => '2009-08-01'}
|
23
|
+
assert_equal params, @report.default_params
|
24
|
+
end
|
25
|
+
|
26
|
+
should "collect params from metrics, dimensions, filters, sort, and defaults" do
|
27
|
+
@report.stubs(:metrics).returns(stub(:to_params => {'metrics' => 6}))
|
28
|
+
@report.stubs(:dimensions).returns(stub(:to_params => {'dimensions' => 5}))
|
29
|
+
@report.stubs(:filters).returns(stub(:to_params => {'filters' => 4}))
|
30
|
+
@report.stubs(:sorts).returns(stub(:to_params => {'sort' => 3}))
|
31
|
+
@report.stubs(:page_params).returns({'page_params' => 2})
|
32
|
+
@report.stubs(:default_params).returns({'default_params' => 1})
|
33
|
+
|
34
|
+
params = {'metrics' => 6, 'dimensions' => 5, 'filters' => 4, 'sort' => 3, 'page_params' => 2, 'default_params' => 1}
|
35
|
+
assert_equal params, @report.params
|
36
|
+
end
|
37
|
+
|
38
|
+
should "format time" do
|
39
|
+
assert_equal @now.strftime('%Y-%m-%d'), @report.format_time(@now)
|
40
|
+
end
|
41
|
+
|
42
|
+
should "send a data request to GA" do
|
43
|
+
response = mock {|m| m.expects(:body).returns('response body') }
|
44
|
+
request = mock {|m| m.expects(:send_request).returns(response) }
|
45
|
+
@report.expects(:params).returns('params')
|
46
|
+
|
47
|
+
DataRequest.expects(:new).with(Garb::Report::URL, 'params').returns(request)
|
48
|
+
assert_equal 'response body', @report.send_request_for_body
|
49
|
+
end
|
50
|
+
|
51
|
+
should "fetch and parse results from GA" do
|
52
|
+
@report.expects(:send_request_for_body).with().returns('xml')
|
53
|
+
ReportResponse.expects(:new).with('xml').returns(mock(:results => ['entry']))
|
54
|
+
assert_equal ['entry'], @report.results
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "An instance of the Report class with initial options" do
|
59
|
+
setup do
|
60
|
+
@profile = stub(:table_id => 'ga:1234')
|
61
|
+
@report = Report.new(@profile, :limit => 10, :offset => 20)
|
62
|
+
end
|
63
|
+
|
64
|
+
should "have page paramaters" do
|
65
|
+
params = {'max-results' => 10, 'start-index' => 20}
|
66
|
+
assert_equal params, @report.page_params
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
class TestReport
|
4
|
+
include Garb::Resource
|
5
|
+
end
|
6
|
+
|
7
|
+
# Most of the resource testing is done as a part of ReportTest
|
8
|
+
class ResourceTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
context "A class with Garb::Resource mixed in" do
|
11
|
+
should "get results from GA" do
|
12
|
+
profile = stub
|
13
|
+
TestReport.expects(:send_request_for_body).returns('xml')
|
14
|
+
Garb::ReportResponse.expects(:new).with('xml').returns(mock(:results => 'analytics'))
|
15
|
+
|
16
|
+
assert_equal 'analytics', TestReport.results(profile)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|