garb-no-activesupport 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/README.md +250 -0
  2. data/Rakefile +55 -0
  3. data/lib/garb/account.rb +29 -0
  4. data/lib/garb/authentication_request.rb +53 -0
  5. data/lib/garb/data_request.rb +42 -0
  6. data/lib/garb/filter_parameters.rb +41 -0
  7. data/lib/garb/profile.rb +57 -0
  8. data/lib/garb/profile_reports.rb +15 -0
  9. data/lib/garb/report.rb +26 -0
  10. data/lib/garb/report_parameter.rb +25 -0
  11. data/lib/garb/report_response.rb +62 -0
  12. data/lib/garb/reports/bounces.rb +5 -0
  13. data/lib/garb/reports/exits.rb +5 -0
  14. data/lib/garb/reports/pageviews.rb +5 -0
  15. data/lib/garb/reports/unique_pageviews.rb +5 -0
  16. data/lib/garb/reports/visits.rb +5 -0
  17. data/lib/garb/reports.rb +5 -0
  18. data/lib/garb/resource.rb +92 -0
  19. data/lib/garb/session.rb +25 -0
  20. data/lib/garb/version.rb +13 -0
  21. data/lib/garb.rb +38 -0
  22. data/lib/string_ext.rb +20 -0
  23. data/lib/support.rb +39 -0
  24. data/test/fixtures/cacert.pem +67 -0
  25. data/test/fixtures/profile_feed.xml +40 -0
  26. data/test/fixtures/report_feed.xml +46 -0
  27. data/test/test_helper.rb +18 -0
  28. data/test/unit/garb/account_test.rb +53 -0
  29. data/test/unit/garb/authentication_request_test.rb +121 -0
  30. data/test/unit/garb/data_request_test.rb +106 -0
  31. data/test/unit/garb/filter_parameters_test.rb +59 -0
  32. data/test/unit/garb/oauth_session_test.rb +11 -0
  33. data/test/unit/garb/profile_reports_test.rb +29 -0
  34. data/test/unit/garb/profile_test.rb +87 -0
  35. data/test/unit/garb/report_parameter_test.rb +43 -0
  36. data/test/unit/garb/report_response_test.rb +29 -0
  37. data/test/unit/garb/report_test.rb +91 -0
  38. data/test/unit/garb/resource_test.rb +38 -0
  39. data/test/unit/garb/session_test.rb +84 -0
  40. data/test/unit/garb_test.rb +14 -0
  41. data/test/unit/symbol_operator_test.rb +37 -0
  42. metadata +133 -0
@@ -0,0 +1,92 @@
1
+ module Garb
2
+ module Resource
3
+ MONTH = 2592000
4
+ URL = "https://www.google.com/analytics/feeds/data"
5
+
6
+ def self.extended(base)
7
+ # define a method on a module that gets included into profile
8
+ # Exits would make:
9
+ # to enable profile.exits(options_hash, &block)
10
+ # returns Exits.results(self, options_hash, &block)
11
+ # every class defined which extends Resource will add to the module
12
+ ProfileReports.add_report_method(base)
13
+ end
14
+
15
+ %w(metrics dimensions sort).each do |parameter|
16
+ class_eval <<-CODE
17
+ def #{parameter}(*fields)
18
+ @#{parameter} ||= ReportParameter.new(:#{parameter})
19
+ @#{parameter} << fields
20
+ end
21
+
22
+ def clear_#{parameter}
23
+ @#{parameter} = ReportParameter.new(:#{parameter})
24
+ end
25
+ CODE
26
+ end
27
+
28
+ def filters(*hashes, &block)
29
+ @filter_parameters ||= FilterParameters.new
30
+
31
+ hashes.each do |hash|
32
+ @filter_parameters.parameters << hash
33
+ end
34
+
35
+ @filter_parameters.filters(&block) if block_given?
36
+ @filter_parameters
37
+ end
38
+
39
+ def clear_filters
40
+ @filter_parameters = FilterParameters.new
41
+ end
42
+
43
+ def results(profile, opts = {}, &block)
44
+ @profile = profile.is_a?(Profile) ? profile : Profile.first(profile, opts.fetch(:session, Session))
45
+
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)
51
+
52
+ instance_eval(&block) if block_given?
53
+
54
+ ReportResponse.new(send_request_for_body).results
55
+ else
56
+ []
57
+ end
58
+ end
59
+
60
+ def page_params
61
+ {'max-results' => @limit, 'start-index' => @offset}.reject{|k,v| v.nil?}
62
+ end
63
+
64
+ def default_params
65
+ {'ids' => @profile.table_id,
66
+ 'start-date' => format_time(@start_date),
67
+ 'end-date' => format_time(@end_date)}
68
+ end
69
+
70
+ def params
71
+ [
72
+ metrics.to_params,
73
+ dimensions.to_params,
74
+ sort.to_params,
75
+ filters.to_params,
76
+ page_params
77
+ ].inject(default_params) do |p, i|
78
+ p.merge(i)
79
+ end
80
+ end
81
+
82
+ def format_time(t)
83
+ t.strftime('%Y-%m-%d')
84
+ end
85
+
86
+ def send_request_for_body
87
+ request = DataRequest.new(@profile.session, URL, params)
88
+ response = request.send_request
89
+ response.body
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,25 @@
1
+ module Garb
2
+ class Session
3
+ module Methods
4
+ attr_accessor :auth_token, :access_token, :email
5
+
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
12
+
13
+ def single_user?
14
+ auth_token && auth_token.is_a?(String)
15
+ end
16
+
17
+ def oauth_user?
18
+ !access_token.nil?
19
+ end
20
+ end
21
+
22
+ include Methods
23
+ extend Methods
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ module Garb
2
+ module Version
3
+
4
+ MAJOR = 0
5
+ MINOR = 7
6
+ TINY = 3
7
+
8
+ def self.to_s # :nodoc:
9
+ [MAJOR, MINOR, TINY].join('.')
10
+ end
11
+
12
+ end
13
+ end
data/lib/garb.rb ADDED
@@ -0,0 +1,38 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'net/http'
4
+ require 'net/https'
5
+
6
+ require 'cgi'
7
+ require 'ostruct'
8
+ require 'happymapper'
9
+
10
+ require 'string_ext'
11
+ require 'garb/version'
12
+ require 'garb/authentication_request'
13
+ require 'garb/data_request'
14
+ require 'garb/session'
15
+ require 'garb/profile_reports'
16
+ require 'garb/profile'
17
+ require 'garb/account'
18
+ require 'garb/filter_parameters'
19
+ require 'garb/report_parameter'
20
+ require 'garb/report_response'
21
+ require 'garb/resource'
22
+ require 'garb/report'
23
+
24
+ require 'support'
25
+
26
+ module Garb
27
+ GA = "http://schemas.google.com/analytics/2008"
28
+
29
+ def self.to_google_analytics(thing)
30
+ return thing.to_google_analytics if thing.respond_to?(:to_google_analytics)
31
+
32
+ "ga:#{thing.to_s.camelize(:lower)}"
33
+ end
34
+
35
+ def self.from_google_analytics(thing)
36
+ thing.to_s.gsub(/^ga\:/, '').underscore
37
+ end
38
+ end
data/lib/string_ext.rb ADDED
@@ -0,0 +1,20 @@
1
+ # These are pulled out of ActiveSupport
2
+
3
+ class String
4
+ def camelize(first_letter_in_uppercase = :upper)
5
+ if first_letter_in_uppercase == :upper
6
+ gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
7
+ else
8
+ self[0..0].downcase + camelize[1..-1]
9
+ end
10
+ end
11
+
12
+ def underscore
13
+ gsub(/::/, '/').
14
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
15
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
16
+ tr("-", "_").
17
+ downcase
18
+ end
19
+ end
20
+
data/lib/support.rb ADDED
@@ -0,0 +1,39 @@
1
+ class SymbolOperator
2
+ def initialize(field, operator)
3
+ @field, @operator = field, operator
4
+ end unless method_defined?(:initialize)
5
+
6
+ def to_google_analytics
7
+ operators = {
8
+ :eql => '==',
9
+ :not_eql => '!=',
10
+ :gt => '>',
11
+ :gte => '>=',
12
+ :lt => '<',
13
+ :lte => '<=',
14
+ :matches => '==',
15
+ :does_not_match => '!=',
16
+ :contains => '=~',
17
+ :does_not_contain => '!~',
18
+ :substring => '=@',
19
+ :not_substring => '!@',
20
+ :desc => '-'
21
+ }
22
+
23
+ target = Garb.to_google_analytics(@field)
24
+ operator = operators[@operator]
25
+
26
+ @operator == :desc ? "#{operator}#{target}" : "#{target}#{operator}"
27
+ end
28
+ end
29
+
30
+ class Symbol
31
+ [:eql, :not_eql, :gt, :gte, :lt, :lte, :desc,
32
+ :matches, :does_not_match, :contains, :does_not_contain,
33
+ :substring, :not_substring].each do |operator|
34
+
35
+ define_method(operator) do
36
+ SymbolOperator.new(self, operator)
37
+ end unless method_defined?(operator)
38
+ end
39
+ end
@@ -0,0 +1,67 @@
1
+ ##
2
+ ## cacert.pem-foo -- Bundle of CA Root Certificates
3
+ ##
4
+ ## Converted at: Thu Mar 26 21:23:06 2009 UTC
5
+ ##
6
+ ## This is a bundle of X.509 certificates of public Certificate Authorities
7
+ ## (CA). These were automatically extracted from Mozilla's root certificates
8
+ ## file (certdata.txt). This file can be found in the mozilla source tree:
9
+ ## '/mozilla/security/nss/lib/ckfw/builtins/certdata.txt'
10
+ ##
11
+ ## It contains the certificates in PEM format and therefore
12
+ ## can be directly used with curl / libcurl / php_curl, or with
13
+ ## an Apache+mod_ssl webserver for SSL client authentication.
14
+ ## Just configure this file as the SSLCACertificateFile.
15
+ ##
16
+
17
+ # ***** BEGIN LICENSE BLOCK *****
18
+ # Version: MPL 1.1/GPL 2.0/LGPL 2.1
19
+ #
20
+ # The contents of this file are subject to the Mozilla Public License Version
21
+ # 1.1 (the "License"); you may not use this file except in compliance with
22
+ # the License. You may obtain a copy of the License at
23
+ # http://www.mozilla.org/MPL/
24
+ #
25
+ # Software distributed under the License is distributed on an "AS IS" basis,
26
+ # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
27
+ # for the specific language governing rights and limitations under the
28
+ # License.
29
+ #
30
+ # The Original Code is the Netscape security libraries.
31
+ #
32
+ # The Initial Developer of the Original Code is
33
+ # Netscape Communications Corporation.
34
+ # Portions created by the Initial Developer are Copyright (C) 1994-2000
35
+ # the Initial Developer. All Rights Reserved.
36
+ #
37
+ # Contributor(s):
38
+ #
39
+ # Alternatively, the contents of this file may be used under the terms of
40
+ # either the GNU General Public License Version 2 or later (the "GPL"), or
41
+ # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
42
+ # in which case the provisions of the GPL or the LGPL are applicable instead
43
+ # of those above. If you wish to allow use of your version of this file only
44
+ # under the terms of either the GPL or the LGPL, and not to allow others to
45
+ # use your version of this file under the terms of the MPL, indicate your
46
+ # decision by deleting the provisions above and replace them with the notice
47
+ # and other provisions required by the GPL or the LGPL. If you do not delete
48
+ # the provisions above, a recipient may use your version of this file under
49
+ # the terms of any one of the MPL, the GPL or the LGPL.
50
+ #
51
+ # ***** END LICENSE BLOCK *****
52
+ # @(#) $RCSfile: certdata.txt,v $ $Revision: 1.51 $ $Date: 2009/01/15 22:35:15 $
53
+
54
+ Verisign/RSA Secure Server CA
55
+ =============================
56
+ -----BEGIN CERTIFICATE-----
57
+ MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
58
+ IDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy
59
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVow
60
+ XzELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQL
61
+ EyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUA
62
+ A4GJADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII0haGN1Xp
63
+ sSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphIuR2nKRoTLkoRWZweFdVJ
64
+ VCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZIhvcNAQECBQADfgBl3X7hsuyw4jrg7HFG
65
+ mhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2
66
+ qUtN8iD3zV9/ZHuO3ABc1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
67
+ -----END CERTIFICATE-----
@@ -0,0 +1,40 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <feed xmlns='http://www.w3.org/2005/Atom' xmlns:dxp='http://schemas.google.com/analytics/2009' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'>
3
+ <id>http://www.google.com/analytics/feeds/accounts/tpitale@gmail.com</id>
4
+ <updated>2009-10-02T07:47:35.000-07:00</updated>
5
+ <title type='text'>Profile list for tpitale@gmail.com</title><link rel='self' type='application/atom+xml' href='http://www.google.com/analytics/feeds/accounts/default'/>
6
+ <author>
7
+ <name>Google Analytics</name>
8
+ </author>
9
+ <generator version='1.0'>Google Analytics</generator>
10
+ <openSearch:totalResults>2</openSearch:totalResults>
11
+ <openSearch:startIndex>1</openSearch:startIndex>
12
+ <openSearch:itemsPerPage>2</openSearch:itemsPerPage>
13
+ <entry>
14
+ <id>http://www.google.com/analytics/feeds/accounts/ga:12345</id>
15
+ <updated>2008-07-21T14:05:57.000-07:00</updated>
16
+ <title type='text'>Historical</title>
17
+ <link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
18
+ <dxp:property name='ga:accountId' value='1111'/>
19
+ <dxp:property name='ga:accountName' value='Blog Beta'/>
20
+ <dxp:property name='ga:profileId' value='1212'/>
21
+ <dxp:property name='ga:webPropertyId' value='UA-1111-1'/>
22
+ <dxp:property name='ga:currency' value='USD'/>
23
+ <dxp:property name='ga:timezone' value='America/New_York'/>
24
+ <dxp:tableId>ga:12345</dxp:tableId>
25
+ </entry>
26
+ <entry>
27
+ <id>http://www.google.com/analytics/feeds/accounts/ga:12346</id>
28
+ <updated>2008-11-24T11:51:07.000-08:00</updated>
29
+ <title type='text'>Presently</title>
30
+ <link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
31
+ <dxp:property name='ga:accountId' value='1111'/>
32
+ <dxp:property name='ga:accountName' value='Blog Beta'/>
33
+ <dxp:property name='ga:profileId' value='1213'/>
34
+ <dxp:property name='ga:webPropertyId' value='UA-1111-2'/>
35
+ <dxp:property name='ga:currency' value='USD'/>
36
+ <dxp:property name='ga:timezone' value='America/New_York'/>
37
+ <dxp:tableId>ga:12346</dxp:tableId>
38
+ </entry>
39
+ </feed>
40
+
@@ -0,0 +1,46 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <feed xmlns='http://www.w3.org/2005/Atom'
3
+ xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
4
+ xmlns:dxp='http://schemas.google.com/analytics/2009'
5
+ xmlns:ga='http://schemas.google.com/analytics/2008'>
6
+ <id>http://www.google.com/analytics/feeds/data?ids=ga:983247&amp;dimensions=ga:country,ga:city&amp;metrics=ga:pageViews&amp;start-date=2008-01-01&amp;end-date=2008-01-02</id>
7
+ <updated>2008-01-02T15:59:59.999-08:00 </updated>
8
+ <title type="text">Google Analytics Data for Profile 983247</title>
9
+ <link href="http://www.google.com/analytics/feeds/data" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
10
+ <link href="http://www.google.com/analytics/feeds/data?end-date=2008-01-02&amp;start-date=2008-01-01&amp;metrics=ga%3ApageViews&amp;ids=ga%3A983247&amp;dimensions=ga%3Acountry%2Cga%3Acity" rel="self" type="application/atom+xml"/>
11
+ <link href="http://www.google.com/analytics/feeds/data?start-index=1001&amp;max-results=1000&amp;end-date=2008-01-02&amp;start-date=2008-01-01&amp;metrics=ga%3ApageViews&amp;ids=ga%3A983247&amp;dimensions=ga%3Acountry%2Cga%3Acity" rel="next" type="application/atom+xml"/>
12
+ <author>
13
+ <name>Google Analytics</name>
14
+ </author>
15
+ <openSearch:startIndex>3</openSearch:startIndex>
16
+ <openSearch:itemsPerPage>4</openSearch:itemsPerPage>
17
+ <ga:webPropertyID>UA-983247-67</ga:webPropertyID>
18
+ <ga:start-date>2008-01-01</ga:start-date>
19
+ <ga:end-date>2008-01-02</ga:end-date>
20
+
21
+ <entry>
22
+ <id> http://www.google.com/analytics/feeds/data?ids=ga:1174&amp;ga:country=%28not%20set%29&amp;ga:city=%28not%20set%29&amp;start-date=2008-01-01&amp;end-date=2008-01-02 </id>
23
+ <updated> 2008-01-01T16:00:00.001-08:00 </updated>
24
+ <title type="text"> ga:country=(not set) | ga:city=(not set) </title>
25
+ <link href="http://www.google.com/analytics/feeds/data" rel="self" type="application/atom+xml"/>
26
+ <dxp:dimension name="ga:country" value="(not set)" />
27
+ <dxp:dimension name="ga:city" value="(not set)" />
28
+ <dxp:metric name="ga:pageviews" value="33" />
29
+ </entry>
30
+ <entry>
31
+ <id> http://www.google.com/analytics/feeds/data?ids=ga:1174&amp;ga:country=Afghanistan&amp;ga:city=Kabul&amp;start-date=2008-01-01&amp;end-date=2008-01-02 </id>
32
+ <updated> 2008-01-01T16:00:00.001-08:00 </updated>
33
+ <title type="text"> ga:country=Afghanistan | ga:city=Kabul </title>
34
+ <dxp:dimension name="ga:country" value="Afghanistan" />
35
+ <dxp:dimension name="ga:city" value="Kabul" />
36
+ <dxp:metric name="ga:pageviews" value="2" />
37
+ </entry>
38
+ <entry>
39
+ <id> http://www.google.com/analytics/feeds/data?ids=ga:1174&amp;ga:country=Albania&amp;ga:city=Tirana&amp;start-date=2008-01-01&amp;end-date=2008-01-02 </id>
40
+ <updated> 2008-01-01T16:00:00.001-08:00 </updated>
41
+ <title type="text"> ga:country=Albania | ga:city=Tirana </title>
42
+ <dxp:dimension name="ga:country" value="Albania" />
43
+ <dxp:dimension name="ga:city" value="Tirana" />
44
+ <dxp:metric name="ga:pageviews" value="1" />
45
+ </entry>
46
+ </feed>
@@ -0,0 +1,18 @@
1
+ $:.reject! { |e| e.include? 'TextMate' }
2
+
3
+ require 'rubygems'
4
+ require 'minitest/unit'
5
+ require 'shoulda'
6
+ require 'mocha'
7
+
8
+ require File.dirname(__FILE__) + '/../lib/garb'
9
+
10
+ class MiniTest::Unit::TestCase
11
+
12
+ def read_fixture(filename)
13
+ File.read(File.dirname(__FILE__) + "/fixtures/#{filename}")
14
+ end
15
+
16
+ end
17
+
18
+ MiniTest::Unit.autorun
@@ -0,0 +1,53 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
2
+
3
+ module Garb
4
+ class AccountTest < MiniTest::Unit::TestCase
5
+ context "The Account class" do
6
+ should "have an array of accounts with all profiles" do
7
+ p1 = stub(:account_id => '1111', :account_name => 'Blog 1')
8
+ p2 = stub(:account_id => '1112', :account_name => 'Blog 2')
9
+
10
+ Profile.stubs(:all).returns([p1,p2,p1,p2])
11
+ Account.stubs(:new).returns('account1', 'account2')
12
+
13
+ assert_equal ['account1','account2'], Account.all
14
+ assert_received(Profile, :all)
15
+ assert_received(Account, :new) {|e| e.with([p1,p1])}
16
+ assert_received(Account, :new) {|e| e.with([p2,p2])}
17
+ end
18
+ end
19
+
20
+ context "An instance of the Account class" do
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
35
+ end
36
+ end
37
+
38
+ context "when creating a new account from an array of profiles" do
39
+ should "take the account id from the first profile" do
40
+ assert_equal @profiles.first.account_id, @account.id
41
+ end
42
+
43
+ should "take the account name from the first profile" do
44
+ assert_equal @profiles.first.account_name, @account.name
45
+ end
46
+
47
+ should "store the array of profiles" do
48
+ assert_equal @profiles, @account.profiles
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,121 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
2
+
3
+ CA_CERT_FILE = File.join(File.dirname(__FILE__), '..', '/cacert.pem')
4
+
5
+ module Garb
6
+ class AuthenticationRequestTest < MiniTest::Unit::TestCase
7
+
8
+ context "An instance of the AuthenticationRequest class" do
9
+
10
+ setup { @request = AuthenticationRequest.new('email', 'password') }
11
+
12
+ should "have a collection of parameters that include the email and password" do
13
+ expected =
14
+ {
15
+ 'Email' => 'user@example.com',
16
+ 'Passwd' => 'fuzzybunnies',
17
+ 'accountType' => 'HOSTED_OR_GOOGLE',
18
+ 'service' => 'analytics',
19
+ 'source' => 'vigetLabs-garb-001'
20
+ }
21
+
22
+ request = AuthenticationRequest.new('user@example.com', 'fuzzybunnies')
23
+ assert_equal expected, request.parameters
24
+ end
25
+
26
+ should "have a URI" do
27
+ assert_equal URI.parse('https://www.google.com/accounts/ClientLogin'), @request.uri
28
+ end
29
+
30
+ should "be able to send a request to the GAAPI service with proper ssl" do
31
+ @request.expects(:build_request).returns('post')
32
+
33
+ response = mock {|m| m.expects(:is_a?).with(Net::HTTPOK).returns(true) }
34
+
35
+ http = mock do |m|
36
+ m.expects(:use_ssl=).with(true)
37
+ m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
38
+ m.expects(:ca_file=).with(CA_CERT_FILE)
39
+ m.expects(:request).with('post').yields(response)
40
+ end
41
+
42
+ Net::HTTP.expects(:new).with('www.google.com', 443).returns(http)
43
+
44
+ @request.send_request(OpenSSL::SSL::VERIFY_PEER)
45
+ end
46
+
47
+ should "be able to send a request to the GAAPI service with ignoring ssl" do
48
+ @request.expects(:build_request).returns('post')
49
+
50
+ response = mock {|m| m.expects(:is_a?).with(Net::HTTPOK).returns(true) }
51
+
52
+ http = mock do |m|
53
+ m.expects(:use_ssl=).with(true)
54
+ m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
55
+ m.expects(:request).with('post').yields(response)
56
+ end
57
+
58
+ Net::HTTP.expects(:new).with('www.google.com', 443).returns(http)
59
+
60
+ @request.send_request(OpenSSL::SSL::VERIFY_NONE)
61
+ end
62
+
63
+ should "be able to build a request for the GAAPI service" do
64
+ params = "param"
65
+ @request.expects(:parameters).with().returns(params)
66
+
67
+ post = mock
68
+ post.expects(:set_form_data).with(params)
69
+
70
+ Net::HTTP::Post.expects(:new).with('/accounts/ClientLogin').returns(post)
71
+
72
+ @request.build_request
73
+ end
74
+
75
+ should "be able to retrieve an auth_token from the body" do
76
+ response_data =
77
+ "SID=mysid\n" +
78
+ "LSID=mylsid\n" +
79
+ "Auth=auth_token\n"
80
+
81
+ @request.expects(:send_request).with(OpenSSL::SSL::VERIFY_NONE).returns(stub(:body => response_data))
82
+
83
+ assert_equal 'auth_token', @request.auth_token
84
+ end
85
+
86
+ should "use VERIFY_PEER if auth_token needs to be secure" do
87
+ response_data =
88
+ "SID=mysid\n" +
89
+ "LSID=mylsid\n" +
90
+ "Auth=auth_token\n"
91
+
92
+ @request.expects(:send_request).with(OpenSSL::SSL::VERIFY_PEER).returns(stub(:body => response_data))
93
+
94
+ assert_equal 'auth_token', @request.auth_token(:secure => true)
95
+ end
96
+
97
+ should "raise an exception when requesting an auth_token when the authorization fails" do
98
+ @request.stubs(:build_request)
99
+ response = mock do |m|
100
+ m.expects(:is_a?).with(Net::HTTPOK).returns(false)
101
+ end
102
+
103
+ http = stub do |s|
104
+ s.stubs(:use_ssl=)
105
+ s.stubs(:verify_mode=)
106
+ s.stubs(:request).yields(response)
107
+ end
108
+
109
+ Net::HTTP.stubs(:new).with('www.google.com', 443).returns(http)
110
+
111
+ assert_raises(Garb::AuthenticationRequest::AuthError) do
112
+ @request.send_request(OpenSSL::SSL::VERIFY_NONE)
113
+ end
114
+ end
115
+
116
+ end
117
+
118
+
119
+
120
+ end
121
+ end