titanous-garb 0.8.5
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/README.md +262 -0
- data/Rakefile +56 -0
- data/lib/garb.rb +69 -0
- data/lib/garb/account.rb +21 -0
- data/lib/garb/account_feed_request.rb +25 -0
- data/lib/garb/authentication_request.rb +53 -0
- data/lib/garb/data_request.rb +42 -0
- data/lib/garb/destination.rb +20 -0
- data/lib/garb/filter_parameters.rb +41 -0
- data/lib/garb/goal.rb +20 -0
- data/lib/garb/management/account.rb +32 -0
- data/lib/garb/management/feed.rb +26 -0
- data/lib/garb/management/goal.rb +20 -0
- data/lib/garb/management/profile.rb +39 -0
- data/lib/garb/management/web_property.rb +30 -0
- data/lib/garb/model.rb +89 -0
- data/lib/garb/profile.rb +33 -0
- data/lib/garb/profile_reports.rb +16 -0
- data/lib/garb/report.rb +28 -0
- data/lib/garb/report_parameter.rb +25 -0
- data/lib/garb/report_response.rb +34 -0
- data/lib/garb/reports.rb +5 -0
- data/lib/garb/reports/bounces.rb +5 -0
- data/lib/garb/reports/exits.rb +5 -0
- data/lib/garb/reports/pageviews.rb +5 -0
- data/lib/garb/reports/unique_pageviews.rb +5 -0
- data/lib/garb/reports/visits.rb +5 -0
- data/lib/garb/resource.rb +115 -0
- data/lib/garb/session.rb +35 -0
- data/lib/garb/step.rb +13 -0
- data/lib/garb/version.rb +13 -0
- data/lib/support.rb +40 -0
- data/test/fixtures/cacert.pem +67 -0
- data/test/fixtures/profile_feed.xml +72 -0
- data/test/fixtures/report_feed.xml +46 -0
- data/test/test_helper.rb +37 -0
- data/test/unit/garb/account_feed_request_test.rb +9 -0
- data/test/unit/garb/account_test.rb +53 -0
- data/test/unit/garb/authentication_request_test.rb +121 -0
- data/test/unit/garb/data_request_test.rb +120 -0
- data/test/unit/garb/destination_test.rb +28 -0
- data/test/unit/garb/filter_parameters_test.rb +59 -0
- data/test/unit/garb/goal_test.rb +24 -0
- data/test/unit/garb/management/account_test.rb +54 -0
- data/test/unit/garb/management/profile_test.rb +59 -0
- data/test/unit/garb/management/web_property_test.rb +58 -0
- data/test/unit/garb/model_test.rb +134 -0
- data/test/unit/garb/oauth_session_test.rb +11 -0
- data/test/unit/garb/profile_reports_test.rb +29 -0
- data/test/unit/garb/profile_test.rb +77 -0
- data/test/unit/garb/report_parameter_test.rb +43 -0
- data/test/unit/garb/report_response_test.rb +37 -0
- data/test/unit/garb/report_test.rb +99 -0
- data/test/unit/garb/resource_test.rb +49 -0
- data/test/unit/garb/session_test.rb +91 -0
- data/test/unit/garb/step_test.rb +15 -0
- data/test/unit/garb_test.rb +26 -0
- data/test/unit/symbol_operator_test.rb +37 -0
- metadata +180 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
class GoalTest < MiniTest::Unit::TestCase
|
5
|
+
context "A Goal" do
|
6
|
+
should "have a name, number, and value" do
|
7
|
+
goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'true'})
|
8
|
+
assert_equal 'Read Blog', goal.name
|
9
|
+
assert_equal 1, goal.number
|
10
|
+
assert_equal 10.0, goal.value
|
11
|
+
end
|
12
|
+
|
13
|
+
should "know if it is active" do
|
14
|
+
goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'true'})
|
15
|
+
assert goal.active?
|
16
|
+
end
|
17
|
+
|
18
|
+
should "know if it is not active" do
|
19
|
+
goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'false'})
|
20
|
+
assert_equal false, goal.active?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
module Management
|
5
|
+
class AccountTest < MiniTest::Unit::TestCase
|
6
|
+
context "The Account class" do
|
7
|
+
should "turn entries for path into array of accounts" do
|
8
|
+
feed = stub(:entries => ["entry1"])
|
9
|
+
Feed.stubs(:new).returns(feed)
|
10
|
+
|
11
|
+
Account.stubs(:new)
|
12
|
+
Account.all
|
13
|
+
|
14
|
+
assert_received(Feed, :new) {|e| e.with(Session, '/accounts')}
|
15
|
+
assert_received(feed, :entries)
|
16
|
+
assert_received(Account, :new) {|e| e.with("entry1", Session)}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "an Account" do
|
21
|
+
setup do
|
22
|
+
entry = {
|
23
|
+
"title" => "Google Analytics Account Garb",
|
24
|
+
"link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/123456"}],
|
25
|
+
"dxp:property" => [
|
26
|
+
{"name" => "ga:accountId", "value" => "123456"},
|
27
|
+
{"name" => "ga:accountName", "value" => "Garb"}
|
28
|
+
]
|
29
|
+
}
|
30
|
+
@account = Account.new(entry, Session)
|
31
|
+
end
|
32
|
+
|
33
|
+
should "extract id and title from GA entry" do
|
34
|
+
assert_equal "Garb", @account.title
|
35
|
+
assert_equal "123456", @account.id
|
36
|
+
end
|
37
|
+
|
38
|
+
should "extract a name from GA entry properties" do
|
39
|
+
assert_equal "Garb", @account.name
|
40
|
+
end
|
41
|
+
|
42
|
+
should "combine the Account.path and the id into an new path" do
|
43
|
+
assert_equal "/accounts/123456", @account.path
|
44
|
+
end
|
45
|
+
|
46
|
+
should "have a reference to the session it was created with" do
|
47
|
+
assert_equal Session, @account.session
|
48
|
+
end
|
49
|
+
|
50
|
+
should "have web properties"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
module Management
|
5
|
+
class ProfileTest < MiniTest::Unit::TestCase
|
6
|
+
context "The Profile class" do
|
7
|
+
should "turn entries for path into array of profile" do
|
8
|
+
feed = stub(:entries => ["entry1"])
|
9
|
+
Feed.stubs(:new).returns(feed)
|
10
|
+
|
11
|
+
Profile.stubs(:new)
|
12
|
+
Profile.all
|
13
|
+
|
14
|
+
assert_received(Feed, :new) {|e| e.with(Session, '/accounts/~all/webproperties/~all/profiles')}
|
15
|
+
assert_received(feed, :entries)
|
16
|
+
assert_received(Profile, :new) {|e| e.with("entry1", Session)}
|
17
|
+
end
|
18
|
+
|
19
|
+
should "find all web properties for a given account"
|
20
|
+
should "find all web properties for a given web_property"
|
21
|
+
end
|
22
|
+
|
23
|
+
context "A Profile" do
|
24
|
+
setup do
|
25
|
+
entry = {
|
26
|
+
"link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/1189765/webproperties/UA-1189765-1/profiles/98765"}],
|
27
|
+
"dxp:property" => [
|
28
|
+
{"name" => "ga:profileId", "value" => "98765"},
|
29
|
+
{"name" => "ga:accountId", "value" => "1189765"},
|
30
|
+
{"name" => "ga:webPropertyId", "value" => 'UA-1189765-1'},
|
31
|
+
{"name" => "ga:profileName", "value" => "example.com"}
|
32
|
+
]
|
33
|
+
}
|
34
|
+
@profile = Profile.new(entry, Session)
|
35
|
+
end
|
36
|
+
|
37
|
+
should "have a title" do
|
38
|
+
assert_equal "example.com", @profile.title
|
39
|
+
end
|
40
|
+
|
41
|
+
should "have an id" do
|
42
|
+
assert_equal '98765', @profile.id
|
43
|
+
end
|
44
|
+
|
45
|
+
should "have an account_id" do
|
46
|
+
assert_equal '1189765', @profile.account_id
|
47
|
+
end
|
48
|
+
|
49
|
+
should "have a web_property_id" do
|
50
|
+
assert_equal 'UA-1189765-1', @profile.web_property_id
|
51
|
+
end
|
52
|
+
|
53
|
+
should "have a path" do
|
54
|
+
assert_equal "/accounts/1189765/webproperties/UA-1189765-1/profiles/98765", @profile.path
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
module Management
|
5
|
+
class WebPropertyTest < MiniTest::Unit::TestCase
|
6
|
+
context "the WebProperty class" do
|
7
|
+
should "turn entries for path into array of web properties" do
|
8
|
+
feed = stub(:entries => ["entry1"])
|
9
|
+
Feed.stubs(:new).returns(feed)
|
10
|
+
|
11
|
+
WebProperty.stubs(:new)
|
12
|
+
WebProperty.all
|
13
|
+
|
14
|
+
assert_received(Feed, :new) {|e| e.with(Session, '/accounts/~all/webproperties')}
|
15
|
+
assert_received(feed, :entries)
|
16
|
+
assert_received(WebProperty, :new) {|e| e.with("entry1", Session)}
|
17
|
+
end
|
18
|
+
|
19
|
+
should "find all web properties for a given account" do
|
20
|
+
WebProperty.stubs(:all)
|
21
|
+
WebProperty.for_account(stub(:session => Session, :path => '/accounts/123456'))
|
22
|
+
|
23
|
+
assert_received(WebProperty, :all) do |e|
|
24
|
+
e.with(Session, '/accounts/123456/webproperties')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "a WebProperty" do
|
30
|
+
setup do
|
31
|
+
entry = {
|
32
|
+
"link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/1189765/webproperties/UA-1189765-1"}],
|
33
|
+
"dxp:property" => [
|
34
|
+
{"name" => "ga:accountId", "value" => "1189765"},
|
35
|
+
{"name" => "ga:webPropertyId", "value" => 'UA-1189765-1'}
|
36
|
+
]
|
37
|
+
}
|
38
|
+
|
39
|
+
@web_property = WebProperty.new(entry, Session)
|
40
|
+
end
|
41
|
+
|
42
|
+
should "have an id" do
|
43
|
+
assert_equal "UA-1189765-1", @web_property.id
|
44
|
+
end
|
45
|
+
|
46
|
+
should "have an account_id" do
|
47
|
+
assert_equal "1189765", @web_property.account_id
|
48
|
+
end
|
49
|
+
|
50
|
+
should "have profiles" do
|
51
|
+
Profile.stubs(:for_web_property)
|
52
|
+
@web_property.profiles
|
53
|
+
assert_received(Profile, :for_web_property) {|e| e.with(@web_property)}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ResultKlass
|
4
|
+
def initialize(attrs)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module Garb
|
9
|
+
class ModelTest < MiniTest::Unit::TestCase
|
10
|
+
context "A class extended with Garb::Model" do
|
11
|
+
setup do
|
12
|
+
@test_model = Class.new
|
13
|
+
@test_model.extend(Garb::Model)
|
14
|
+
end
|
15
|
+
|
16
|
+
# public API
|
17
|
+
should "be able to define metrics" do
|
18
|
+
report_parameter = stub(:<<)
|
19
|
+
ReportParameter.stubs(:new).returns(report_parameter)
|
20
|
+
|
21
|
+
@test_model.metrics :visits, :pageviews
|
22
|
+
|
23
|
+
assert_received(ReportParameter, :new) {|e| e.with(:metrics)}
|
24
|
+
assert_received(report_parameter, :<<) {|e| e.with([:visits, :pageviews])}
|
25
|
+
end
|
26
|
+
|
27
|
+
should "be able to define dimensions" do
|
28
|
+
report_parameter = stub(:<<)
|
29
|
+
ReportParameter.stubs(:new).returns(report_parameter)
|
30
|
+
|
31
|
+
@test_model.dimensions :page_path, :event_category
|
32
|
+
|
33
|
+
assert_received(ReportParameter, :new) {|e| e.with(:dimensions)}
|
34
|
+
assert_received(report_parameter, :<<) {|e| e.with([:page_path, :event_category])}
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be able to se the instance klass" do
|
38
|
+
@test_model.set_instance_klass ResultKlass
|
39
|
+
assert_equal ResultKlass, @test_model.instance_klass
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with a profile" do
|
43
|
+
setup do
|
44
|
+
entry = {
|
45
|
+
"title" => "Google Analytics Profile example.com",
|
46
|
+
"link" => [{"rel" => "self", "href" => Garb::Management::Feed::BASE_URL+"/accounts/1189765/webproperties/UA-1189765-1/profiles/98765"}],
|
47
|
+
"dxp:property" => [
|
48
|
+
{"name" => "ga:profileId", "value" => "98765"},
|
49
|
+
{"name" => "ga:accountId", "value" => "1189765"},
|
50
|
+
{"name" => "ga:webPropertyId", "value" => 'UA-1189765-1'}
|
51
|
+
]
|
52
|
+
}
|
53
|
+
|
54
|
+
@profile = Garb::Management::Profile.new(entry, Session)
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when getting results" do
|
58
|
+
setup do
|
59
|
+
@response = stub(:body => "raw report data")
|
60
|
+
DataRequest.stubs(:new).returns(stub(:send_request => @response))
|
61
|
+
ReportResponse.stubs(:new).returns(stub(:results => ['result']))
|
62
|
+
|
63
|
+
@test_model.stubs(:metrics).returns(stub(:to_params => {'metrics' => 'ga:visits'}))
|
64
|
+
@test_model.stubs(:dimensions).returns(stub(:to_params => {'dimensions' => 'ga:pagePath'}))
|
65
|
+
|
66
|
+
now = Time.now
|
67
|
+
Time.stubs(:new).returns(now)
|
68
|
+
|
69
|
+
@params = {'ids' => Garb.to_ga(@profile.id),
|
70
|
+
'start-date' => (now - Model::MONTH).strftime('%Y-%m-%d'),
|
71
|
+
'end-date' => now.strftime('%Y-%m-%d'),
|
72
|
+
'metrics' => 'ga:visits',
|
73
|
+
'dimensions' => 'ga:pagePath'}
|
74
|
+
end
|
75
|
+
|
76
|
+
should "get all results" do
|
77
|
+
assert_equal ['result'], @test_model.results(@profile)
|
78
|
+
assert_received(ReportResponse, :new) {|e| e.with("raw report data", OpenStruct)}
|
79
|
+
assert_data_params(@params)
|
80
|
+
end
|
81
|
+
|
82
|
+
should "be able to filter" do
|
83
|
+
filter_parameters = stub(:<<)
|
84
|
+
FilterParameters.stubs(:new).returns(stub(:parameters => filter_parameters, :to_params => {'filters' => "params"}))
|
85
|
+
assert_equal ['result'], @test_model.results(@profile, :filters => {:page_path => '/'})
|
86
|
+
|
87
|
+
assert_data_params(@params.merge({'filters' => 'params'}))
|
88
|
+
assert_received(filter_parameters, :<<) {|e| e.with({:page_path => '/'})}
|
89
|
+
end
|
90
|
+
|
91
|
+
should "be able to set the filter segment by id" do
|
92
|
+
assert_equal ['result'], @test_model.results(@profile, :segment_id => 1)
|
93
|
+
assert_data_params(@params.merge({'segment' => 'gaid::1'}))
|
94
|
+
end
|
95
|
+
|
96
|
+
should "be able to sort" do
|
97
|
+
sort_parameter = stub(:<<)
|
98
|
+
sort_parameter.stubs(:to_params => {'sort' => 'sort value'})
|
99
|
+
ReportParameter.stubs(:new).returns(sort_parameter)
|
100
|
+
|
101
|
+
assert_equal ['result'], @test_model.results(@profile, :sort => [:visits])
|
102
|
+
assert_received(sort_parameter, :<<) {|e| e.with([:visits])}
|
103
|
+
assert_data_params(@params.merge({'sort' => 'sort value'}))
|
104
|
+
end
|
105
|
+
|
106
|
+
should "be able to limit" do
|
107
|
+
assert_equal ['result'], @test_model.results(@profile, :limit => 20)
|
108
|
+
assert_data_params(@params.merge({'max-results' => 20}))
|
109
|
+
end
|
110
|
+
|
111
|
+
should "be able to offset" do
|
112
|
+
assert_equal ['result'], @test_model.results(@profile, :offset => 10)
|
113
|
+
assert_data_params(@params.merge({'start-index' => 10}))
|
114
|
+
end
|
115
|
+
|
116
|
+
# should "be able to shift the date range"
|
117
|
+
|
118
|
+
should "return a set of results in the defined class" do
|
119
|
+
@test_model.stubs(:instance_klass).returns(ResultKlass)
|
120
|
+
|
121
|
+
assert_equal ['result'], @test_model.results(@profile)
|
122
|
+
assert_received(ReportResponse, :new) {|e| e.with("raw report data", ResultKlass)}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# should "have a block syntax for filtering results"
|
127
|
+
# should "return results as an array of the class it belongs to, if that class is an ActiveRecord descendant"
|
128
|
+
# should "return results as an array of the class it belongs to, if that class is a DataMapper descendant"
|
129
|
+
# should "return results as an array of the class it belongs to, if that class is a MongoMapper descendant"
|
130
|
+
# should "return results as an array of the class it belongs to, if that class is a Mongoid descendant"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
|
5
|
+
Exits = Class.new
|
6
|
+
|
7
|
+
class FakeProfile
|
8
|
+
include ProfileReports
|
9
|
+
end
|
10
|
+
|
11
|
+
class ProfileReportsTest < MiniTest::Unit::TestCase
|
12
|
+
context "The ProfileReports module" do
|
13
|
+
should "define a new method when given a class" do
|
14
|
+
ProfileReports.add_report_method(Exits)
|
15
|
+
assert_equal true, FakeProfile.new.respond_to?(:exits)
|
16
|
+
end
|
17
|
+
|
18
|
+
should "return results from the given class with options" do
|
19
|
+
results = [1,2,3]
|
20
|
+
Exits.stubs(:results).returns(results)
|
21
|
+
ProfileReports.add_report_method(Exits)
|
22
|
+
|
23
|
+
profile = FakeProfile.new
|
24
|
+
assert_equal results, profile.exits(:start => "now")
|
25
|
+
assert_received(Exits, :results) {|e| e.with(profile, :start => "now")}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Garb
|
4
|
+
class ProfileTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Profile class" do
|
7
|
+
setup {@session = Session.new}
|
8
|
+
|
9
|
+
should "be able to return a list of all profiles" do
|
10
|
+
afr = AccountFeedRequest.new
|
11
|
+
afr.stubs(:parsed_response).returns(Crack::XML.parse(read_fixture('profile_feed.xml')))
|
12
|
+
AccountFeedRequest.stubs(:new).returns(afr)
|
13
|
+
|
14
|
+
assert_equal ['12345', '12346'], Profile.all(@session).map(&:id)
|
15
|
+
assert_received(AccountFeedRequest, :new) {|e| e.with(@session)}
|
16
|
+
end
|
17
|
+
|
18
|
+
should "return the first profile for a given web property id" do
|
19
|
+
profile1 = stub(:web_property_id => '12345', :id => 'abcdef')
|
20
|
+
profile2 = stub(:web_property_id => '67890', :id => 'ghijkl')
|
21
|
+
entries = [profile1, profile2]
|
22
|
+
|
23
|
+
Profile.stubs(:all).returns(entries)
|
24
|
+
|
25
|
+
assert_equal profile1, Profile.first('12345', @session)
|
26
|
+
|
27
|
+
assert_received(Profile, :all) {|e| e.with(@session)}
|
28
|
+
end
|
29
|
+
|
30
|
+
should "return the first profile for a given table id" do
|
31
|
+
profile1 = stub(:id => '12345', :web_property_id => 'abcdef')
|
32
|
+
profile2 = stub(:id => '67890', :web_property_id => 'ghijkl')
|
33
|
+
entries = [profile1, profile2]
|
34
|
+
|
35
|
+
Profile.stubs(:all).returns(entries)
|
36
|
+
|
37
|
+
assert_equal profile2, Profile.first('67890', @session)
|
38
|
+
|
39
|
+
assert_received(Profile, :all) {|e| e.with(@session)}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "A Profile" do
|
44
|
+
setup do
|
45
|
+
afr = AccountFeedRequest.new
|
46
|
+
afr.stubs(:parsed_response).returns(Crack::XML.parse(read_fixture('profile_feed.xml')))
|
47
|
+
|
48
|
+
entry = afr.entries.first
|
49
|
+
@profile = Profile.new(entry, Session)
|
50
|
+
end
|
51
|
+
|
52
|
+
should "have a value for :title" do
|
53
|
+
assert_equal "Historical", @profile.title
|
54
|
+
end
|
55
|
+
|
56
|
+
should "have a value for :table_id" do
|
57
|
+
assert_equal 'ga:12345', @profile.table_id
|
58
|
+
end
|
59
|
+
|
60
|
+
should "have a value for :id" do
|
61
|
+
assert_equal '12345', @profile.id
|
62
|
+
end
|
63
|
+
|
64
|
+
should "have a value for :account_id" do
|
65
|
+
assert_equal '1111', @profile.account_id
|
66
|
+
end
|
67
|
+
|
68
|
+
should "have a value for :account_name" do
|
69
|
+
assert_equal 'Blog Beta', @profile.account_name
|
70
|
+
end
|
71
|
+
|
72
|
+
should "have goals" do
|
73
|
+
assert_equal 4, @profile.goals.size
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|