garb 0.6.0 → 0.7.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.
data/README.md CHANGED
@@ -193,8 +193,9 @@ SSL
193
193
  TODOS
194
194
  -----
195
195
 
196
- * Sessions are currently global, which isn't awesome
197
196
  * Read opensearch header in results
197
+ * Investigate new features from GA to see if they're in the API, implement if so
198
+ * clarify AND/OR filtering behavior in code and documentation
198
199
 
199
200
  Requirements
200
201
  ------------
@@ -8,10 +8,10 @@ module Garb
8
8
  @profiles = profiles
9
9
  end
10
10
 
11
- def self.all
11
+ def self.all(session = Session)
12
12
  # Profile.all.group_to_array{|p| p.account_id}.map{|profiles| new(profiles)}
13
13
 
14
- profile_groups = Profile.all.inject({}) do |hash, profile|
14
+ profile_groups = Profile.all(session).inject({}) do |hash, profile|
15
15
  key = profile.account_id
16
16
 
17
17
  if hash.has_key?(key)
@@ -2,7 +2,8 @@ module Garb
2
2
  class DataRequest
3
3
  class ClientError < StandardError; end
4
4
 
5
- def initialize(base_url, parameters={})
5
+ def initialize(session, base_url, parameters={})
6
+ @session = session
6
7
  @base_url = base_url
7
8
  @parameters = parameters
8
9
  end
@@ -17,9 +18,9 @@ module Garb
17
18
  end
18
19
 
19
20
  def send_request
20
- response = if Session.single_user?
21
+ response = if @session.single_user?
21
22
  single_user_request
22
- elsif Session.oauth_user?
23
+ elsif @session.oauth_user?
23
24
  oauth_user_request
24
25
  end
25
26
 
@@ -31,11 +32,11 @@ module Garb
31
32
  http = Net::HTTP.new(uri.host, uri.port)
32
33
  http.use_ssl = true
33
34
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
34
- http.get("#{uri.path}#{query_string}", 'Authorization' => "GoogleLogin auth=#{Session.auth_token}")
35
+ http.get("#{uri.path}#{query_string}", 'Authorization' => "GoogleLogin auth=#{@session.auth_token}")
35
36
  end
36
37
 
37
38
  def oauth_user_request
38
- Session.access_token.get("#{uri}#{query_string}")
39
+ @session.access_token.get("#{uri}#{query_string}")
39
40
  end
40
41
  end
41
42
  end
@@ -3,7 +3,7 @@ module Garb
3
3
 
4
4
  include ProfileReports
5
5
 
6
- attr_reader :table_id, :title, :account_name, :account_id, :web_property_id
6
+ attr_reader :session, :table_id, :title, :account_name, :account_id, :web_property_id
7
7
 
8
8
  class Property
9
9
  include HappyMapper
@@ -30,7 +30,8 @@ module Garb
30
30
  has_many :properties, Property
31
31
  end
32
32
 
33
- def initialize(entry)
33
+ def initialize(entry, session)
34
+ @session = session
34
35
  @title = entry.title
35
36
  @table_id = entry.tableId
36
37
 
@@ -43,14 +44,14 @@ module Garb
43
44
  Garb.from_google_analytics(@table_id)
44
45
  end
45
46
 
46
- def self.all
47
+ def self.all(session = Session)
47
48
  url = "https://www.google.com/analytics/feeds/accounts/default"
48
- response = DataRequest.new(url).send_request
49
- Entry.parse(response.body).map {|entry| new(entry)}
49
+ response = DataRequest.new(session, url).send_request
50
+ Entry.parse(response.body).map {|entry| new(entry, session)}
50
51
  end
51
52
 
52
- def self.first(id)
53
- all.detect {|profile| profile.id == id || profile.web_property_id == id }
53
+ def self.first(id, session = Session)
54
+ all(session).detect {|profile| profile.id == id || profile.web_property_id == id }
54
55
  end
55
56
  end
56
57
  end
@@ -41,16 +41,20 @@ module Garb
41
41
  end
42
42
 
43
43
  def results(profile, opts = {}, &block)
44
- @profile = profile.is_a?(Profile) ? profile : Profile.first(profile)
44
+ @profile = profile.is_a?(Profile) ? profile : Profile.first(profile, opts.fetch(:session, Session))
45
45
 
46
- @start_date = opts.fetch(:start_date, Time.now - MONTH)
47
- @end_date = opts.fetch(:end_date, Time.now)
48
- @limit = opts.fetch(:limit, nil)
49
- @offset = opts.fetch(:offset, nil)
46
+ if @profile
47
+ @start_date = opts.fetch(:start_date, Time.now - MONTH)
48
+ @end_date = opts.fetch(:end_date, Time.now)
49
+ @limit = opts.fetch(:limit, nil)
50
+ @offset = opts.fetch(:offset, nil)
50
51
 
51
- instance_eval(&block) if block_given?
52
+ instance_eval(&block) if block_given?
52
53
 
53
- ReportResponse.new(send_request_for_body).results
54
+ ReportResponse.new(send_request_for_body).results
55
+ else
56
+ []
57
+ end
54
58
  end
55
59
 
56
60
  def page_params
@@ -80,7 +84,7 @@ module Garb
80
84
  end
81
85
 
82
86
  def send_request_for_body
83
- request = DataRequest.new(URL, params)
87
+ request = DataRequest.new(@profile.session, URL, params)
84
88
  response = request.send_request
85
89
  response.body
86
90
  end
@@ -1,22 +1,25 @@
1
1
  module Garb
2
- module Session
3
- extend self
2
+ class Session
3
+ module Methods
4
+ attr_accessor :auth_token, :access_token, :email
4
5
 
5
- attr_accessor :auth_token, :access_token, :email
6
+ # use only for single user authentication
7
+ def login(email, password, opts={})
8
+ self.email = email
9
+ auth_request = AuthenticationRequest.new(email, password, opts)
10
+ self.auth_token = auth_request.auth_token(opts)
11
+ end
6
12
 
7
- # use only for single user authentication
8
- def login(email, password, opts={})
9
- self.email = email
10
- auth_request = AuthenticationRequest.new(email, password, opts)
11
- self.auth_token = auth_request.auth_token(opts)
12
- end
13
+ def single_user?
14
+ auth_token && auth_token.is_a?(String)
15
+ end
13
16
 
14
- def single_user?
15
- auth_token && auth_token.is_a?(String)
17
+ def oauth_user?
18
+ !access_token.nil?
19
+ end
16
20
  end
17
21
 
18
- def oauth_user?
19
- !access_token.nil?
20
- end
22
+ include Methods
23
+ extend Methods
21
24
  end
22
25
  end
@@ -2,7 +2,7 @@ module Garb
2
2
  module Version
3
3
 
4
4
  MAJOR = 0
5
- MINOR = 6
5
+ MINOR = 7
6
6
  TINY = 0
7
7
 
8
8
  def self.to_s # :nodoc:
@@ -18,13 +18,24 @@ module Garb
18
18
  end
19
19
 
20
20
  context "An instance of the Account class" do
21
- context "when creating a new account from an array of profiles" do
22
- setup do
23
- profile = stub(:account_id => '1111', :account_name => 'Blog 1')
24
- @profiles = [profile,profile]
25
- @account = Account.new(@profiles)
21
+ setup do
22
+ profile = stub(:account_id => '1111', :account_name => 'Blog 1')
23
+ @profiles = [profile,profile]
24
+ @account = Account.new(@profiles)
25
+ end
26
+
27
+ context "all" do
28
+ should "use an optional user session" do
29
+ session = Session.new
30
+ Garb::Profile.expects(:all).with(session).returns(@profiles)
31
+
32
+ accounts = Account.all(session)
33
+ assert_equal 1, accounts.size
34
+ assert_equal @profiles, accounts.first.profiles
26
35
  end
36
+ end
27
37
 
38
+ context "when creating a new account from an array of profiles" do
28
39
  should "take the account id from the first profile" do
29
40
  assert_equal @profiles.first.account_id, @account.id
30
41
  end
@@ -4,10 +4,14 @@ module Garb
4
4
  class DataRequestTest < MiniTest::Unit::TestCase
5
5
 
6
6
  context "An instance of the DataRequest class" do
7
+ setup do
8
+ @session = Session.new
9
+ @session.auth_token = 'abcdefg123456'
10
+ end
7
11
 
8
12
  should "be able to build the query string from parameters" do
9
13
  parameters = {'ids' => '12345', 'metrics' => 'country'}
10
- data_request = DataRequest.new("", parameters)
14
+ data_request = DataRequest.new(@session, "", parameters)
11
15
 
12
16
  query_string = data_request.query_string
13
17
 
@@ -19,7 +23,7 @@ module Garb
19
23
  end
20
24
 
21
25
  should "return an empty query string if parameters are empty" do
22
- data_request = DataRequest.new("")
26
+ data_request = DataRequest.new(@session, "")
23
27
  assert_equal "", data_request.query_string
24
28
  end
25
29
 
@@ -27,16 +31,16 @@ module Garb
27
31
  url = 'http://example.com'
28
32
  expected = URI.parse('http://example.com')
29
33
 
30
- assert_equal expected, DataRequest.new(url).uri
34
+ assert_equal expected, DataRequest.new(@session, url).uri
31
35
  end
32
36
 
33
37
  should "be able to send a request for a single user" do
34
- Session.stubs(:single_user?).returns(true)
38
+ @session.stubs(:single_user?).returns(true)
35
39
  response = mock('Net::HTTPOK') do |m|
36
40
  m.expects(:kind_of?).with(Net::HTTPSuccess).returns(true)
37
41
  end
38
42
 
39
- data_request = DataRequest.new('https://example.com/data', 'key' => 'value')
43
+ data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
40
44
  data_request.stubs(:single_user_request).returns(response)
41
45
  data_request.send_request
42
46
 
@@ -44,13 +48,13 @@ module Garb
44
48
  end
45
49
 
46
50
  should "be able to send a request for an oauth user" do
47
- Session.stubs(:single_user?).returns(false)
48
- Session.stubs(:oauth_user?).returns(true)
51
+ @session.stubs(:single_user?).returns(false)
52
+ @session.stubs(:oauth_user?).returns(true)
49
53
  response = mock('Net::HTTPOK') do |m|
50
54
  m.expects(:kind_of?).with(Net::HTTPSuccess).returns(true)
51
55
  end
52
56
 
53
- data_request = DataRequest.new('https://example.com/data', 'key' => 'value')
57
+ data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
54
58
  data_request.stubs(:oauth_user_request).returns(response)
55
59
  data_request.send_request
56
60
 
@@ -58,11 +62,11 @@ module Garb
58
62
  end
59
63
 
60
64
  should "raise if the request is unauthorized" do
61
- Session.stubs(:single_user?).returns(false)
62
- Session.stubs(:oauth_user?).returns(true)
65
+ @session.stubs(:single_user?).returns(false)
66
+ @session.stubs(:oauth_user?).returns(true)
63
67
  response = mock('Net::HTTPUnauthorized', :body => 'Error')
64
68
 
65
- data_request = DataRequest.new('https://example.com/data', 'key' => 'value')
69
+ data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
66
70
  data_request.stubs(:oauth_user_request).returns(response)
67
71
 
68
72
  assert_raises(Garb::DataRequest::ClientError) do
@@ -72,17 +76,17 @@ module Garb
72
76
 
73
77
  should "be able to request via the ouath access token" do
74
78
  access_token = stub(:get => "responseobject")
75
- Session.stubs(:access_token).returns(access_token)
79
+ @session.stubs(:access_token).returns(access_token)
76
80
 
77
- data_request = DataRequest.new('https://example.com/data', 'key' => 'value')
81
+ data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
78
82
  assert_equal 'responseobject', data_request.oauth_user_request
79
83
 
80
- assert_received(Session, :access_token)
84
+ assert_received(@session, :access_token)
81
85
  assert_received(access_token, :get) {|e| e.with('https://example.com/data?key=value')}
82
86
  end
83
87
 
84
88
  should "be able to request via http with an auth token" do
85
- Session.expects(:auth_token).with().returns('toke')
89
+ @session.expects(:auth_token).with().returns('toke')
86
90
  response = mock
87
91
 
88
92
  http = mock do |m|
@@ -93,7 +97,7 @@ module Garb
93
97
 
94
98
  Net::HTTP.expects(:new).with('example.com', 443).returns(http)
95
99
 
96
- data_request = DataRequest.new('https://example.com/data', 'key' => 'value')
100
+ data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
97
101
  assert_equal response, data_request.single_user_request
98
102
  end
99
103
  end
@@ -4,6 +4,7 @@ module Garb
4
4
  class ProfileTest < MiniTest::Unit::TestCase
5
5
 
6
6
  context "The Profile class" do
7
+ setup {@session = Session.new}
7
8
 
8
9
  should "be able to return a list of all profiles" do
9
10
  url = 'https://www.google.com/analytics/feeds/accounts/default'
@@ -13,7 +14,7 @@ module Garb
13
14
  data_request = mock
14
15
  data_request.expects(:send_request).with().returns(stub(:body => xml))
15
16
 
16
- DataRequest.expects(:new).with(url).returns(data_request)
17
+ DataRequest.expects(:new).with(@session, url).returns(data_request)
17
18
 
18
19
  entries = [stub]
19
20
 
@@ -23,10 +24,10 @@ module Garb
23
24
  entries.each do |entry|
24
25
  profile = stub
25
26
  profiles << profile
26
- Garb::Profile.expects(:new).with(entry).returns(profile)
27
+ Garb::Profile.expects(:new).with(entry, @session).returns(profile)
27
28
  end
28
29
 
29
- assert_equal profiles, Profile.all
30
+ assert_equal profiles, Profile.all(@session)
30
31
  end
31
32
 
32
33
  should "return the first profile for a given web property id" do
@@ -36,7 +37,9 @@ module Garb
36
37
 
37
38
  Garb::Profile.stubs(:all).returns(entries)
38
39
 
39
- assert_equal profile1, Garb::Profile.first('12345')
40
+ assert_equal profile1, Garb::Profile.first('12345', @session)
41
+
42
+ assert_received(Garb::Profile, :all) {|e| e.with(@session)}
40
43
  end
41
44
 
42
45
  should "return the first profile for a given table id" do
@@ -46,25 +49,27 @@ module Garb
46
49
 
47
50
  Garb::Profile.stubs(:all).returns(entries)
48
51
 
49
- assert_equal profile2, Garb::Profile.first('67890')
52
+ assert_equal profile2, Garb::Profile.first('67890', @session)
53
+
54
+ assert_received(Garb::Profile, :all) {|e| e.with(@session)}
50
55
  end
51
56
  end
52
-
57
+
53
58
  context "An instance of the Profile class" do
54
-
59
+
55
60
  setup do
56
61
  @entry = (Profile::Entry.parse(read_fixture('profile_feed.xml'))).first
57
- @profile = Profile.new(@entry)
62
+ @profile = Profile.new(@entry, Session)
58
63
  end
59
-
64
+
60
65
  should "have a value for :title" do
61
66
  assert_equal "Historical", @profile.title
62
67
  end
63
-
68
+
64
69
  should "have a value for :table_id" do
65
70
  assert_equal 'ga:12345', @profile.table_id
66
71
  end
67
-
72
+
68
73
  should "have a value for :id" do
69
74
  assert_equal '12345', @profile.id
70
75
  end
@@ -76,7 +81,6 @@ module Garb
76
81
  should "have a value for :account_name" do
77
82
  assert_equal 'Blog Beta', @profile.account_name
78
83
  end
79
-
80
84
  end
81
85
 
82
86
  end
@@ -7,7 +7,7 @@ module Garb
7
7
  setup do
8
8
  @now = Time.now
9
9
  Time.stubs(:now).returns(@now)
10
- @profile = stub(:table_id => 'ga:1234')
10
+ @profile = stub(:table_id => 'ga:1234', :session => Session)
11
11
  @report = Report.new(@profile)
12
12
  end
13
13
 
@@ -64,7 +64,7 @@ module Garb
64
64
  request = mock {|m| m.expects(:send_request).returns(response) }
65
65
  @report.expects(:params).returns('params')
66
66
 
67
- DataRequest.expects(:new).with(Garb::Report::URL, 'params').returns(request)
67
+ DataRequest.expects(:new).with(Session, Garb::Report::URL, 'params').returns(request)
68
68
  assert_equal 'response body', @report.send_request_for_body
69
69
  end
70
70
 
@@ -15,5 +15,24 @@ class ResourceTest < MiniTest::Unit::TestCase
15
15
 
16
16
  assert_equal 'analytics', TestReport.results(profile)
17
17
  end
18
+
19
+ should "get results from GA using a specific user session" do
20
+ profile = '123'
21
+ session = Garb::Session.new
22
+ TestReport.expects(:send_request_for_body).returns('xml')
23
+ Garb::ReportResponse.expects(:new).with('xml').returns(mock(:results => 'analytics'))
24
+ Garb::Profile.expects(:first).with(profile, session).returns(mock('Garb::Profile'))
25
+
26
+ assert_equal 'analytics', TestReport.results(profile, :session => session)
27
+ end
28
+
29
+ should "return an empty result set if profile is invalid" do
30
+ profile = '123'
31
+ TestReport.expects(:send_request_for_body).never
32
+ Garb::ReportResponse.expects(:new).never
33
+
34
+ Garb::Profile.expects(:first).returns(nil)
35
+ assert_equal [], TestReport.results(profile)
36
+ end
18
37
  end
19
38
  end
@@ -40,5 +40,45 @@ module Garb
40
40
  end
41
41
  end
42
42
 
43
+ context "A Session" do
44
+ setup do
45
+ @session = Session.new
46
+ end
47
+
48
+ should "be able retrieve an auth_token for a user" do
49
+ auth_request = mock {|m| m.expects(:auth_token).with({}).returns('toke') }
50
+ AuthenticationRequest.expects(:new).with('email', 'password', {}).returns(auth_request)
51
+
52
+ @session.login('email', 'password')
53
+ assert_equal 'toke', @session.auth_token
54
+ end
55
+
56
+ should "be able retrieve an auth_token for a user with secure ssl" do
57
+ opts = {:secure => true, :account_type => 'GOOGLE'}
58
+ auth_request = mock {|m| m.expects(:auth_token).with(opts).returns('toke') }
59
+ AuthenticationRequest.expects(:new).with('email', 'password', opts).returns(auth_request)
60
+
61
+ @session.login('email', 'password', opts)
62
+ assert_equal 'toke', @session.auth_token
63
+ end
64
+
65
+ should "retain the email address for this session" do
66
+ AuthenticationRequest.stubs(:new).returns(stub(:auth_token => 'toke'))
67
+
68
+ @session.login('email', 'password')
69
+ assert_equal 'email', @session.email
70
+ end
71
+
72
+ should "know if the Session is for a single user" do
73
+ @session.auth_token = "abcdefg1234567"
74
+ assert_equal true, @session.single_user?
75
+ end
76
+
77
+ should "know if the Session is for oauth" do
78
+ @session.access_token = 'some_oauth_access_token'
79
+ assert_equal true, @session.oauth_user?
80
+ end
81
+ end
82
+
43
83
  end
44
84
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: garb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Pitale
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-10 00:00:00 -05:00
12
+ date: 2010-02-16 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency