Skip to content
Browse files

Merge branch 'master' of https://github.com/vigetlabs/garb

  • Loading branch information...
2 parents d7c5b1c + 9b6fb84 commit 68ddaef1d780fe1c06f5d4e1ee51e69b73f60b82 @stevenwilkin committed Jul 28, 2011
Showing with 586 additions and 1,117 deletions.
  1. +1 −2 .bundle/config
  2. +6 −0 CHANGELOG.md
  3. +3 −2 Gemfile
  4. +3 −4 Gemfile.lock
  5. +10 −5 README.md
  6. +1 −1 Rakefile
  7. +5 −6 garb.gemspec
  8. +49 −33 lib/garb.rb
  9. +0 −22 lib/garb/account.rb
  10. +0 −25 lib/garb/account_feed_request.rb
  11. +0 −53 lib/garb/authentication_request.rb
  12. +0 −42 lib/garb/data_request.rb
  13. +14 −22 lib/garb/filter_parameters.rb
  14. +0 −20 lib/garb/goal.rb
  15. +2 −2 lib/garb/management/feed.rb
  16. +2 −4 lib/garb/model.rb
  17. +0 −33 lib/garb/profile.rb
  18. +0 −28 lib/garb/report.rb
  19. +8 −8 lib/garb/report_response.rb
  20. +57 −0 lib/garb/request/authentication.rb
  21. +55 −0 lib/garb/request/data.rb
  22. +0 −115 lib/garb/resource.rb
  23. +1 −1 lib/garb/session.rb
  24. +1 −1 lib/garb/version.rb
  25. +5 −0 lib/support.rb
  26. +49 −0 lib/support/string.rb
  27. +1 −0 test/fixtures/profile_feed.json
  28. +1 −0 test/fixtures/report_feed.json
  29. +1 −2 test/test_helper.rb
  30. +0 −42 test/unit/garb/account_feed_request_test.rb
  31. +0 −53 test/unit/garb/account_test.rb
  32. +0 −121 test/unit/garb/authentication_request_test.rb
  33. +0 −107 test/unit/garb/data_request_test.rb
  34. +0 −28 test/unit/garb/destination_test.rb
  35. +22 −43 test/unit/garb/filter_parameters_test.rb
  36. +0 −24 test/unit/garb/goal_test.rb
  37. +1 −1 test/unit/garb/management/account_test.rb
  38. +4 −4 test/unit/garb/management/feed_test.rb
  39. +1 −1 test/unit/garb/management/profile_test.rb
  40. +1 −1 test/unit/garb/management/web_property_test.rb
  41. +4 −5 test/unit/garb/model_test.rb
  42. +0 −77 test/unit/garb/profile_test.rb
  43. +8 −8 test/unit/garb/report_response_test.rb
  44. +0 −99 test/unit/garb/report_test.rb
  45. +147 −0 test/unit/garb/request/authentication_test.rb
  46. +116 −0 test/unit/garb/request/data_test.rb
  47. +0 −50 test/unit/garb/resource_test.rb
  48. +6 −6 test/unit/garb/session_test.rb
  49. +0 −15 test/unit/garb/step_test.rb
  50. +1 −1 test/unit/garb_test.rb
View
3 .bundle/config
@@ -1,2 +1 @@
----
-BUNDLE_DISABLE_SHARED_GEMS: "1"
+--- {}
View
6 CHANGELOG.md
@@ -1,3 +1,9 @@
+Version 0.9.2
+
+ * Removed all deprecated features: Garb::Report, Garb::Resource, Garb::Profile, and Garb::Account
+ * Moved the differing types of requests into a module, will refactor to share more code
+ * Fixed OR'ing in :filters option for results
+
Version 0.9.0
* New Garb::Model is solid. Garb::Resource and Garb::Report are deprecated.
View
5 Gemfile
@@ -1,15 +1,16 @@
source :rubygems
source "http://gems.github.com"
+gem 'rake', '~> 0.8.7'
+
gem 'i18n'
-gem 'activesupport'
-gem 'crack'
group :test do
gem 'shoulda'
gem 'simplecov'
gem 'minitest', :require => false
gem 'jferris-mocha', :require => false
+ gem 'yajl-ruby'
end
group :demo do
View
7 Gemfile.lock
@@ -2,8 +2,6 @@ GEM
remote: http://rubygems.org/
remote: http://gems.github.com/
specs:
- activesupport (3.0.3)
- crack (0.1.8)
i18n (0.4.2)
jferris-mocha (0.9.8.20100526112143)
rake
@@ -14,16 +12,17 @@ GEM
simplecov (0.3.7)
simplecov-html (>= 0.3.7)
simplecov-html (0.3.9)
+ yajl-ruby (0.8.2)
PLATFORMS
ruby
DEPENDENCIES
- activesupport
- crack
i18n
jferris-mocha
minitest
oauth
+ rake (~> 0.8.7)
shoulda
simplecov
+ yajl-ruby
View
15 README.md
@@ -6,6 +6,9 @@ Garb
Important Changes
=================
+ It has now been nearly 6 months, I have removed the deprecated features listed below in master.
+ I will release 0.9.2 shortly, with these features removed.
+
With The release of version 0.9.0 I have officially deprecated Garb::Report, Garb::Resource,
Garb::Profile, and Garb::Account. Garb::Report and Garb::Resource should be replaced by Garb::Model.
Garb::Profile and Garb::Account are supplanted by their Garb::Management::* counterparts.
@@ -38,15 +41,15 @@ OAuth Access Token
> Garb::Session.access_token = access_token # assign from oauth gem
Accounts, WebProperties, Profiles, and Goals
---------
+--------------------------------------------
> Garb::Management::Account.all
> Garb::Management::WebProperty.all
> Garb::Management::Profile.all
> Garb::Management::Goal.all
Profiles for a UA- Number (a WebProperty)
---------
+-----------------------------------------
> profile = Garb::Management::Profile.all.detect {|p| p.web_property_id == 'UA-XXXXXXX-X'}
@@ -150,12 +153,13 @@ Requirements for Testing
------------------------
* shoulda
- * jferris-mocha
+ * mocha
+ * bourne
Install
-------
- gem install garb
+ gem install garb OR with bundler: gem 'garb' and `bundle install`
Contributors
------------
@@ -165,13 +169,14 @@ Contributors
* Patrick Reagan
* Justin Marney
* Nick Plante
+ * James Cook
License
-------
(The MIT License)
- Copyright (c) 2010 Viget Labs
+ Copyright (c) 2011 Viget Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
View
2 Rakefile
@@ -15,7 +15,7 @@ spec = Gem::Specification.new do |s|
s.authors = ['Tony Pitale']
s.email = 'tony.pitale@viget.com'
s.homepage = 'http://github.com/vigetlabs/garb'
- s.files = %w(README.md Rakefile) + Dir.glob("lib/**/*")
+ s.files = %w(README.md CHANGELOG.md Rakefile) + Dir.glob("lib/**/*")
s.test_files = Dir.glob("test/**/*")
s.add_dependency("crack", [">= 0.1.6"])
View
11 garb.gemspec
@@ -2,22 +2,21 @@
Gem::Specification.new do |s|
s.name = %q{garb}
- s.version = "0.9.1"
+ s.version = "0.9.2"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Tony Pitale"]
- s.date = %q{2011-01-08}
+ s.date = %q{2011-06-30}
s.email = %q{tony.pitale@viget.com}
- s.files = ["README.md", "Rakefile", "lib/garb", "lib/garb/account.rb", "lib/garb/account_feed_request.rb", "lib/garb/authentication_request.rb", "lib/garb/data_request.rb", "lib/garb/destination.rb", "lib/garb/filter_parameters.rb", "lib/garb/goal.rb", "lib/garb/management", "lib/garb/management/account.rb", "lib/garb/management/feed.rb", "lib/garb/management/goal.rb", "lib/garb/management/profile.rb", "lib/garb/management/segment.rb", "lib/garb/management/web_property.rb", "lib/garb/model.rb", "lib/garb/profile.rb", "lib/garb/profile_reports.rb", "lib/garb/report.rb", "lib/garb/report_parameter.rb", "lib/garb/report_response.rb", "lib/garb/reports", "lib/garb/reports/bounces.rb", "lib/garb/reports/exits.rb", "lib/garb/reports/pageviews.rb", "lib/garb/reports/unique_pageviews.rb", "lib/garb/reports/visits.rb", "lib/garb/reports.rb", "lib/garb/resource.rb", "lib/garb/result_set.rb", "lib/garb/session.rb", "lib/garb/step.rb", "lib/garb/version.rb", "lib/garb.rb", "lib/support.rb", "test/fixtures", "test/fixtures/cacert.pem", "test/fixtures/profile_feed.xml", "test/fixtures/report_feed.xml", "test/test_helper.rb", "test/unit", "test/unit/garb", "test/unit/garb/account_feed_request_test.rb", "test/unit/garb/account_test.rb", "test/unit/garb/authentication_request_test.rb", "test/unit/garb/coverage", "test/unit/garb/coverage/assets", "test/unit/garb/coverage/assets/0.3.9", "test/unit/garb/coverage/assets/0.3.9/app.js", "test/unit/garb/coverage/assets/0.3.9/fancybox", "test/unit/garb/coverage/assets/0.3.9/fancybox/blank.gif", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_close.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_loading.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_left.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_right.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_left.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_main.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_over.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_right.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-x.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-y.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css", "test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js", "test/unit/garb/coverage/assets/0.3.9/favicon.png", "test/unit/garb/coverage/assets/0.3.9/jquery-1.4.2.min.js", "test/unit/garb/coverage/assets/0.3.9/jquery.dataTables.min.js", "test/unit/garb/coverage/assets/0.3.9/jquery.timeago.js", "test/unit/garb/coverage/assets/0.3.9/jquery.url.js", "test/unit/garb/coverage/assets/0.3.9/loading.gif", "test/unit/garb/coverage/assets/0.3.9/magnify.png", "test/unit/garb/coverage/assets/0.3.9/smoothness", "test/unit/garb/coverage/assets/0.3.9/smoothness/images", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css", "test/unit/garb/coverage/assets/0.3.9/stylesheet.css", "test/unit/garb/coverage/index.html", "test/unit/garb/coverage/resultset.yml", "test/unit/garb/data_request_test.rb", "test/unit/garb/destination_test.rb", "test/unit/garb/filter_parameters_test.rb", "test/unit/garb/goal_test.rb", "test/unit/garb/management", "test/unit/garb/management/account_test.rb", "test/unit/garb/management/coverage", "test/unit/garb/management/coverage/assets", "test/unit/garb/management/coverage/assets/0.3.9", "test/unit/garb/management/coverage/assets/0.3.9/app.js", "test/unit/garb/management/coverage/assets/0.3.9/fancybox", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/blank.gif", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_close.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_loading.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_left.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_right.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_left.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_main.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_over.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_right.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-x.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-y.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js", "test/unit/garb/management/coverage/assets/0.3.9/favicon.png", "test/unit/garb/management/coverage/assets/0.3.9/jquery-1.4.2.min.js", "test/unit/garb/management/coverage/assets/0.3.9/jquery.dataTables.min.js", "test/unit/garb/management/coverage/assets/0.3.9/jquery.timeago.js", "test/unit/garb/management/coverage/assets/0.3.9/jquery.url.js", "test/unit/garb/management/coverage/assets/0.3.9/loading.gif", "test/unit/garb/management/coverage/assets/0.3.9/magnify.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css", "test/unit/garb/management/coverage/assets/0.3.9/stylesheet.css", "test/unit/garb/management/coverage/index.html", "test/unit/garb/management/coverage/resultset.yml", "test/unit/garb/management/feed_test.rb", "test/unit/garb/management/goal_test.rb", "test/unit/garb/management/profile_test.rb", "test/unit/garb/management/segment_test.rb", "test/unit/garb/management/web_property_test.rb", "test/unit/garb/model_test.rb", "test/unit/garb/oauth_session_test.rb", "test/unit/garb/profile_reports_test.rb", "test/unit/garb/profile_test.rb", "test/unit/garb/report_parameter_test.rb", "test/unit/garb/report_response_test.rb", "test/unit/garb/report_test.rb", "test/unit/garb/resource_test.rb", "test/unit/garb/session_test.rb", "test/unit/garb/step_test.rb", "test/unit/garb_test.rb", "test/unit/symbol_operator_test.rb"]
+ s.files = ["README.md", "CHANGELOG.md", "Rakefile", "lib/garb", "lib/garb/destination.rb", "lib/garb/filter_parameters.rb", "lib/garb/management", "lib/garb/management/account.rb", "lib/garb/management/feed.rb", "lib/garb/management/goal.rb", "lib/garb/management/profile.rb", "lib/garb/management/segment.rb", "lib/garb/management/web_property.rb", "lib/garb/model.rb", "lib/garb/profile_reports.rb", "lib/garb/report_parameter.rb", "lib/garb/report_response.rb", "lib/garb/reports", "lib/garb/reports/bounces.rb", "lib/garb/reports/exits.rb", "lib/garb/reports/pageviews.rb", "lib/garb/reports/unique_pageviews.rb", "lib/garb/reports/visits.rb", "lib/garb/reports.rb", "lib/garb/request", "lib/garb/request/authentication.rb", "lib/garb/request/data.rb", "lib/garb/result_set.rb", "lib/garb/session.rb", "lib/garb/step.rb", "lib/garb/version.rb", "lib/garb.rb", "lib/support.rb", "test/fixtures", "test/fixtures/cacert.pem", "test/fixtures/profile_feed.xml", "test/fixtures/report_feed.xml", "test/test_helper.rb", "test/unit", "test/unit/garb", "test/unit/garb/filter_parameters_test.rb", "test/unit/garb/management", "test/unit/garb/management/account_test.rb", "test/unit/garb/management/feed_test.rb", "test/unit/garb/management/goal_test.rb", "test/unit/garb/management/profile_test.rb", "test/unit/garb/management/segment_test.rb", "test/unit/garb/management/web_property_test.rb", "test/unit/garb/model_test.rb", "test/unit/garb/oauth_session_test.rb", "test/unit/garb/profile_reports_test.rb", "test/unit/garb/report_parameter_test.rb", "test/unit/garb/report_response_test.rb", "test/unit/garb/request", "test/unit/garb/request/authentication_test.rb", "test/unit/garb/request/data_test.rb", "test/unit/garb/session_test.rb", "test/unit/garb_test.rb", "test/unit/symbol_operator_test.rb"]
s.homepage = %q{http://github.com/vigetlabs/garb}
s.require_paths = ["lib"]
s.rubyforge_project = %q{viget}
- s.rubygems_version = %q{1.3.7}
+ s.rubygems_version = %q{1.6.2}
s.summary = %q{Google Analytics API Ruby Wrapper}
- s.test_files = ["test/fixtures", "test/fixtures/cacert.pem", "test/fixtures/profile_feed.xml", "test/fixtures/report_feed.xml", "test/test_helper.rb", "test/unit", "test/unit/garb", "test/unit/garb/account_feed_request_test.rb", "test/unit/garb/account_test.rb", "test/unit/garb/authentication_request_test.rb", "test/unit/garb/coverage", "test/unit/garb/coverage/assets", "test/unit/garb/coverage/assets/0.3.9", "test/unit/garb/coverage/assets/0.3.9/app.js", "test/unit/garb/coverage/assets/0.3.9/fancybox", "test/unit/garb/coverage/assets/0.3.9/fancybox/blank.gif", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_close.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_loading.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_left.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_right.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_left.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_main.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_over.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_right.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-x.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-y.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox.png", "test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css", "test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js", "test/unit/garb/coverage/assets/0.3.9/favicon.png", "test/unit/garb/coverage/assets/0.3.9/jquery-1.4.2.min.js", "test/unit/garb/coverage/assets/0.3.9/jquery.dataTables.min.js", "test/unit/garb/coverage/assets/0.3.9/jquery.timeago.js", "test/unit/garb/coverage/assets/0.3.9/jquery.url.js", "test/unit/garb/coverage/assets/0.3.9/loading.gif", "test/unit/garb/coverage/assets/0.3.9/magnify.png", "test/unit/garb/coverage/assets/0.3.9/smoothness", "test/unit/garb/coverage/assets/0.3.9/smoothness/images", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png", "test/unit/garb/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css", "test/unit/garb/coverage/assets/0.3.9/stylesheet.css", "test/unit/garb/coverage/index.html", "test/unit/garb/coverage/resultset.yml", "test/unit/garb/data_request_test.rb", "test/unit/garb/destination_test.rb", "test/unit/garb/filter_parameters_test.rb", "test/unit/garb/goal_test.rb", "test/unit/garb/management", "test/unit/garb/management/account_test.rb", "test/unit/garb/management/coverage", "test/unit/garb/management/coverage/assets", "test/unit/garb/management/coverage/assets/0.3.9", "test/unit/garb/management/coverage/assets/0.3.9/app.js", "test/unit/garb/management/coverage/assets/0.3.9/fancybox", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/blank.gif", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_close.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_loading.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_left.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_right.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_left.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_main.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_over.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_right.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-x.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-y.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox.png", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css", "test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js", "test/unit/garb/management/coverage/assets/0.3.9/favicon.png", "test/unit/garb/management/coverage/assets/0.3.9/jquery-1.4.2.min.js", "test/unit/garb/management/coverage/assets/0.3.9/jquery.dataTables.min.js", "test/unit/garb/management/coverage/assets/0.3.9/jquery.timeago.js", "test/unit/garb/management/coverage/assets/0.3.9/jquery.url.js", "test/unit/garb/management/coverage/assets/0.3.9/loading.gif", "test/unit/garb/management/coverage/assets/0.3.9/magnify.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png", "test/unit/garb/management/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css", "test/unit/garb/management/coverage/assets/0.3.9/stylesheet.css", "test/unit/garb/management/coverage/index.html", "test/unit/garb/management/coverage/resultset.yml", "test/unit/garb/management/feed_test.rb", "test/unit/garb/management/goal_test.rb", "test/unit/garb/management/profile_test.rb", "test/unit/garb/management/segment_test.rb", "test/unit/garb/management/web_property_test.rb", "test/unit/garb/model_test.rb", "test/unit/garb/oauth_session_test.rb", "test/unit/garb/profile_reports_test.rb", "test/unit/garb/profile_test.rb", "test/unit/garb/report_parameter_test.rb", "test/unit/garb/report_response_test.rb", "test/unit/garb/report_test.rb", "test/unit/garb/resource_test.rb", "test/unit/garb/session_test.rb", "test/unit/garb/step_test.rb", "test/unit/garb_test.rb", "test/unit/symbol_operator_test.rb"]
+ s.test_files = ["test/fixtures", "test/fixtures/cacert.pem", "test/fixtures/profile_feed.xml", "test/fixtures/report_feed.xml", "test/test_helper.rb", "test/unit", "test/unit/garb", "test/unit/garb/filter_parameters_test.rb", "test/unit/garb/management", "test/unit/garb/management/account_test.rb", "test/unit/garb/management/feed_test.rb", "test/unit/garb/management/goal_test.rb", "test/unit/garb/management/profile_test.rb", "test/unit/garb/management/segment_test.rb", "test/unit/garb/management/web_property_test.rb", "test/unit/garb/model_test.rb", "test/unit/garb/oauth_session_test.rb", "test/unit/garb/profile_reports_test.rb", "test/unit/garb/report_parameter_test.rb", "test/unit/garb/report_response_test.rb", "test/unit/garb/request", "test/unit/garb/request/authentication_test.rb", "test/unit/garb/request/data_test.rb", "test/unit/garb/session_test.rb", "test/unit/garb_test.rb", "test/unit/symbol_operator_test.rb"]
if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
View
82 lib/garb.rb
@@ -3,42 +3,44 @@
require 'cgi'
require 'ostruct'
-require 'crack'
-begin
- require 'active_support/inflector'
- require 'active_support/deprecation'
+begin
+ require 'yajl/json_gem' # JSON.parse
rescue LoadError
- require 'active_support'
+ require 'json'
end
-require 'garb/version'
-require 'garb/authentication_request'
-require 'garb/data_request'
-require 'garb/account_feed_request'
-require 'garb/session'
-require 'garb/profile_reports'
-require 'garb/step'
-require 'garb/destination'
-require 'garb/goal'
-require 'garb/profile'
-require 'garb/account'
-require 'garb/filter_parameters'
-require 'garb/report_parameter'
-require 'garb/result_set'
-require 'garb/report_response'
-require 'garb/resource'
-require 'garb/report'
-
-require 'garb/model'
-
-# management
-require 'garb/management/feed'
-require 'garb/management/segment'
-require 'garb/management/account'
-require 'garb/management/web_property'
-require 'garb/management/profile'
-require 'garb/management/goal'
+module Garb
+ autoload :Destination, 'garb/destination'
+ autoload :FilterParameters, 'garb/filter_parameters'
+ autoload :Model, 'garb/model'
+ autoload :ProfileReports, 'garb/profile_reports'
+ autoload :ReportParameter, 'garb/report_parameter'
+ autoload :ReportResponse, 'garb/report_response'
+ autoload :ResultSet, 'garb/result_set'
+ autoload :Session, 'garb/session'
+ autoload :Step, 'garb/step'
+ autoload :Version, 'garb/version'
+
+ module Management
+ autoload :Account, 'garb/management/account'
+ autoload :Feed, 'garb/management/feed'
+ autoload :Goal, 'garb/management/goal'
+ autoload :Profile, 'garb/management/profile'
+ autoload :Segment, 'garb/management/segment'
+ autoload :WebProperty, 'garb/management/web_property'
+ end
+
+ module Request
+ autoload :Authentication, "garb/request/authentication"
+ autoload :Data, 'garb/request/data'
+ end
+end
+
+# require 'garb/account_feed_request'
+# require 'garb/resource'
+# require 'garb/report'
+
require 'support'
@@ -47,6 +49,15 @@ module Garb
extend self
+ class << self
+ attr_accessor :proxy_address, :proxy_port, :proxy_user, :proxy_password
+ attr_writer :read_timeout
+ end
+
+ def read_timeout
+ @read_timeout || 60
+ end
+
def to_google_analytics(thing)
return thing.to_google_analytics if thing.respond_to?(:to_google_analytics)
@@ -60,10 +71,15 @@ def from_google_analytics(thing)
alias :from_ga :from_google_analytics
def parse_properties(entry)
- Hash[entry['dxp:property'].map {|p| [Garb.from_ga(p['name']),p['value']]}]
+ Hash[entry['dxp$property'].map {|p| [Garb.from_ga(p['name']),p['value']]}]
end
def parse_link(entry, rel)
entry['link'].detect {|link| link["rel"] == rel}['href']
end
+
+ # new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
+
+ # opts => open_timeout, read_timeout, ssl_timeout
+ # probably just support open_timeout
end
View
22 lib/garb/account.rb
@@ -1,22 +0,0 @@
-module Garb
- class Account
- attr_reader :id, :name, :profiles
-
- def initialize(profiles)
- @id = profiles.first.account_id
- @name = profiles.first.account_name
- @profiles = profiles
- end
-
- def self.all(session = Session)
- ActiveSupport::Deprecation.warn("The use of Garb::Account has been deprecated in favor of 'Garb::Management::Account'")
- profiles = {}
-
- Profile.all(session).each do |profile|
- (profiles[profile.account_id] ||= []) << profile
- end
-
- profiles.map {|k,v| v}.map {|profiles| new(profiles)}
- end
- end
-end
View
25 lib/garb/account_feed_request.rb
@@ -1,25 +0,0 @@
-module Garb
- class AccountFeedRequest
- URL = "https://www.google.com/analytics/feeds/accounts/default"
-
- def initialize(session = Session)
- @request = DataRequest.new(session, URL)
- end
-
- def response
- @response ||= @request.send_request
- end
-
- def parsed_response
- @parsed_response ||= Crack::XML.parse(response.body)
- end
-
- def entries
- parsed_response ? Array(parsed_response['feed']['entry']).flatten.compact : []
- end
-
- def segments
- parsed_response ? Array(parsed_response['feed']['dxp:segment']).flatten.compact : []
- end
- end
-end
View
53 lib/garb/authentication_request.rb
@@ -1,53 +0,0 @@
-module Garb
- class AuthenticationRequest
- class AuthError < StandardError;end
-
- URL = 'https://www.google.com/accounts/ClientLogin'
-
- def initialize(email, password, opts={})
- @email = email
- @password = password
- @account_type = opts.fetch(:account_type, 'HOSTED_OR_GOOGLE')
- end
-
- def parameters
- {
- 'Email' => @email,
- 'Passwd' => @password,
- 'accountType' => @account_type,
- 'service' => 'analytics',
- 'source' => 'vigetLabs-garb-001'
- }
- end
-
- def uri
- URI.parse(URL)
- end
-
- def send_request(ssl_mode)
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = true
- http.verify_mode = ssl_mode
-
- if ssl_mode == OpenSSL::SSL::VERIFY_PEER
- http.ca_file = CA_CERT_FILE
- end
-
- http.request(build_request) do |response|
- raise AuthError unless response.is_a?(Net::HTTPOK)
- end
- end
-
- def build_request
- post = Net::HTTP::Post.new(uri.path)
- post.set_form_data(parameters)
- post
- end
-
- def auth_token(opts={})
- ssl_mode = opts[:secure] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
- send_request(ssl_mode).body.match(/^Auth=(.*)$/)[1]
- end
-
- end
-end
View
42 lib/garb/data_request.rb
@@ -1,42 +0,0 @@
-module Garb
- class DataRequest
- class ClientError < StandardError; end
-
- def initialize(session, base_url, parameters={})
- @session = session
- @base_url = base_url
- @parameters = parameters
- end
-
- def query_string
- parameter_list = @parameters.map {|k,v| "#{k}=#{v}" }
- parameter_list.empty? ? '' : "?#{parameter_list.join('&')}"
- end
-
- def uri
- URI.parse(@base_url)
- end
-
- def send_request
- response = if @session.single_user?
- single_user_request
- elsif @session.oauth_user?
- oauth_user_request
- end
-
- raise ClientError, response.body.inspect unless response.kind_of?(Net::HTTPSuccess)
- response
- end
-
- def single_user_request
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = true
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
- http.get("#{uri.path}#{query_string}", {'Authorization' => "GoogleLogin auth=#{@session.auth_token}", 'GData-Version' => '2'})
- end
-
- def oauth_user_request
- @session.access_token.get("#{uri}#{query_string}", {'GData-Version' => '2'})
- end
- end
-end
View
36 lib/garb/filter_parameters.rb
@@ -1,30 +1,22 @@
module Garb
class FilterParameters
- def self.define_operators(*methods)
- methods.each do |method|
- class_eval <<-CODE
- def #{method}(field, value)
- @filter_hash.merge!({SymbolOperator.new(field, :#{method}) => value})
- end
- CODE
- end
- end
-
- define_operators :eql, :not_eql, :gt, :gte, :lt, :lte, :matches,
- :does_not_match, :contains, :does_not_contain, :substring, :not_substring
+ # def self.define_operators(*methods)
+ # methods.each do |method|
+ # class_eval <<-CODE
+ # def #{method}(field, value)
+ # @filter_hash.merge!({SymbolOperator.new(field, :#{method}) => value})
+ # end
+ # CODE
+ # end
+ # end
+
+ # define_operators :eql, :not_eql, :gt, :gte, :lt, :lte, :matches,
+ # :does_not_match, :contains, :does_not_contain, :substring, :not_substring
attr_accessor :parameters
- def initialize
- self.parameters = []
- end
-
- def filters(&block)
- @filter_hash = {}
-
- instance_eval &block
-
- self.parameters << @filter_hash
+ def initialize(parameters)
+ self.parameters = ([parameters].flatten || []).compact
end
def to_params
View
20 lib/garb/goal.rb
@@ -1,20 +0,0 @@
-module Garb
- class Goal
- attr_reader :name, :number, :value, :destination
-
- def initialize(attributes={})
- return unless attributes.is_a?(Hash)
-
- @name = attributes['name']
- @number = attributes['number'].to_i
- @value = attributes['value'].to_f
- @active = (attributes['active'] == 'true')
-
- @destination = Destination.new(attributes[Garb.to_ga('destination')])
- end
-
- def active?
- @active
- end
- end
-end
View
4 lib/garb/management/feed.rb
@@ -6,11 +6,11 @@ class Feed
attr_reader :request
def initialize(session, path)
- @request = DataRequest.new(session, BASE_URL+path)
+ @request = Request::Data.new(session, BASE_URL+path)
end
def parsed_response
- @parsed_response ||= Crack::XML.parse(response.body)
+ @parsed_response ||= JSON.parse(response.body)
end
def entries
View
6 lib/garb/model.rb
@@ -46,7 +46,7 @@ def results(profile, options = {})
private
def send_request_for_data(profile, params)
- request = DataRequest.new(profile.session, URL, params)
+ request = Request::Data.new(profile.session, URL, params)
response = request.send_request
response.body
end
@@ -56,9 +56,7 @@ def build_params(param_set)
end
def parse_filters(options)
- filters = FilterParameters.new
- filters.parameters << options[:filters] if options.has_key?(:filters)
- filters
+ FilterParameters.new(options[:filters])
end
def parse_segment(options)
View
33 lib/garb/profile.rb
@@ -1,33 +0,0 @@
-module Garb
- class Profile
-
- include ProfileReports
-
- attr_reader :session, :table_id, :title, :account_name, :account_id, :web_property_id, :goals
-
- def initialize(entry, session)
- @session = session
- @title = entry['title']
- @table_id = entry['dxp:tableId']
- @goals = (entry[Garb.to_ga('goal')] || []).map {|g| Goal.new(g)}
-
- Garb.parse_properties(entry).each do |k,v|
- instance_variable_set :"@#{k}", v
- end
- end
-
- def id
- Garb.from_ga(@table_id)
- end
-
- def self.all(session = Session)
- ActiveSupport::Deprecation.warn("Garb::Profile.all is deprecated in favor of Garb::Management::Profile.all")
- AccountFeedRequest.new(session).entries.map {|entry| new(entry, session)}
- end
-
- def self.first(id, session = Session)
- ActiveSupport::Deprecation.warn("Garb::Profile.first is deprecated in favor of Garb::Management::WebProperty")
- all(session).detect {|profile| profile.id == id || profile.web_property_id == id }
- end
- end
-end
View
28 lib/garb/report.rb
@@ -1,28 +0,0 @@
-module Garb
- class Report
- include Resource
-
- MONTH = 2592000
- URL = "https://www.google.com/analytics/feeds/data"
-
- def initialize(profile, opts={})
- ActiveSupport::Deprecation.warn("The use of Report will be removed in favor of 'extend Garb::Model'")
-
- @profile = profile
-
- @start_date = opts.fetch(:start_date, Time.now - MONTH)
- @end_date = opts.fetch(:end_date, Time.now)
- @limit = opts.fetch(:limit, nil)
- @offset = opts.fetch(:offset, nil)
-
- metrics opts.fetch(:metrics, [])
- dimensions opts.fetch(:dimensions, [])
- sort opts.fetch(:sort, [])
- end
-
- def results
- ReportResponse.new(send_request_for_body).results
- end
-
- end
-end
View
16 lib/garb/report_response.rb
@@ -1,9 +1,9 @@
module Garb
class ReportResponse
- KEYS = ['dxp:metric', 'dxp:dimension']
+ KEYS = ['dxp$metric', 'dxp$dimension']
def initialize(response_body, instance_klass = OpenStruct)
- @xml = response_body
+ @data = response_body
@instance_klass = instance_klass
end
@@ -30,23 +30,23 @@ def parse
end
def entries
- feed? ? [parsed_xml['feed']['entry']].flatten.compact : []
+ feed? ? [parsed_data['feed']['entry']].flatten.compact : []
end
def parse_total_results
- feed? ? parsed_xml['feed']['openSearch:totalResults'].to_i : 0
+ feed? ? parsed_data['feed']['openSearch:totalResults'].to_i : 0
end
def parse_sampled_flag
- feed? ? (parsed_xml['feed']['dxp:containsSampledData'] == 'true') : false
+ feed? ? (parsed_data['feed']['dxp$containsSampledData'] == 'true') : false
end
- def parsed_xml
- @parsed_xml ||= Crack::XML.parse(@xml)
+ def parsed_data
+ @parsed_data ||= JSON.parse(@data)
end
def feed?
- !parsed_xml['feed'].nil?
+ !parsed_data['feed'].nil?
end
def values_for(entry)
View
57 lib/garb/request/authentication.rb
@@ -0,0 +1,57 @@
+module Garb
+ module Request
+ class Authentication
+ class AuthError < StandardError;end
+
+ URL = 'https://www.google.com/accounts/ClientLogin'
+
+ def initialize(email, password, opts={})
+ @email = email
+ @password = password
+ @account_type = opts.fetch(:account_type, 'HOSTED_OR_GOOGLE')
+ end
+
+ def parameters
+ {
+ 'Email' => @email,
+ 'Passwd' => @password,
+ 'accountType' => @account_type,
+ 'service' => 'analytics',
+ 'source' => 'vigetLabs-garb-001'
+ }
+ end
+
+ def uri
+ URI.parse(URL)
+ end
+
+ def send_request(ssl_mode)
+ http = Net::HTTP.new(uri.host, uri.port, Garb.proxy_address, Garb.proxy_port)
+ http.read_timeout = Garb.read_timeout
+ http.use_ssl = true
+ http.verify_mode = ssl_mode
+
+ if ssl_mode == OpenSSL::SSL::VERIFY_PEER
+ http.ca_file = CA_CERT_FILE
+ end
+
+ http.request(build_request) do |response|
+ raise AuthError unless response.is_a?(Net::HTTPOK)
+ end
+ end
+
+ def build_request
+ post = Net::HTTP::Post.new(uri.path)
+ post.read_timeout = Garb.read_timeout
+ post.set_form_data(parameters)
+ post
+ end
+
+ def auth_token(opts={})
+ ssl_mode = opts[:secure] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
+ send_request(ssl_mode).body.match(/^Auth=(.*)$/)[1]
+ end
+
+ end
+ end
+end
View
55 lib/garb/request/data.rb
@@ -0,0 +1,55 @@
+module Garb
+ module Request
+ class Data
+ class ClientError < StandardError; end
+
+ attr_writer :format
+
+ def initialize(session, base_url, parameters={})
+ @session = session
+ @base_url = base_url
+ @parameters = parameters
+ end
+
+ def parameters
+ @parameters ||= {}
+ end
+
+ def query_string
+ parameters.merge!("alt" => format)
+ parameter_list = @parameters.map {|k,v| "#{k}=#{v}" }
+ parameter_list.empty? ? '' : "?#{parameter_list.join('&')}"
+ end
+
+ def format
+ @format ||= "json" # TODO Support other formats?
+ end
+
+ def uri
+ URI.parse(@base_url)
+ end
+
+ def send_request
+ response = if @session.single_user?
+ single_user_request
+ elsif @session.oauth_user?
+ oauth_user_request
+ end
+
+ raise ClientError, response.body.inspect unless response.kind_of?(Net::HTTPSuccess)
+ response
+ end
+
+ def single_user_request
+ http = Net::HTTP.new(uri.host, uri.port, Garb.proxy_address, Garb.proxy_port)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ http.get("#{uri.path}#{query_string}", {'Authorization' => "GoogleLogin auth=#{@session.auth_token}", 'GData-Version' => '2'})
+ end
+
+ def oauth_user_request
+ @session.access_token.get("#{uri}#{query_string}", {'GData-Version' => '2'})
+ end
+ end
+ end
+end
View
115 lib/garb/resource.rb
@@ -1,115 +0,0 @@
-module Garb
- module Resource
- MONTH = 2592000
- URL = "https://www.google.com/analytics/feeds/data"
-
- def self.extended(base)
- # define a method on a module that gets included into profile
- # Exits would make:
- # to enable profile.exits(options_hash, &block)
- # returns Exits.results(self, options_hash, &block)
- # every class defined which extends Resource will add to the module
-
- ActiveSupport::Deprecation.warn("The use of Garb::Resource will be removed in favor of 'extend Garb::Model'")
- ProfileReports.add_report_method(base)
- end
-
- %w(metrics dimensions sort).each do |parameter|
- class_eval <<-CODE
- def #{parameter}(*fields)
- @#{parameter} ||= ReportParameter.new(:#{parameter})
- @#{parameter} << fields
- end
-
- def clear_#{parameter}
- @#{parameter} = ReportParameter.new(:#{parameter})
- end
- CODE
- end
-
- def filters(*hashes, &block)
- @filter_parameters ||= FilterParameters.new
-
- hashes.each do |hash|
- @filter_parameters.parameters << hash
- end
-
- @filter_parameters.filters(&block) if block_given?
- @filter_parameters
- end
-
- def clear_filters
- @filter_parameters = FilterParameters.new
- end
-
- def set_segment_id(id)
- @segment = "gaid::#{id.to_i}"
- end
-
- def segment
- @segment
- end
-
- def set_instance_klass(klass)
- @instance_klass = klass
- end
-
- def instance_klass
- @instance_klass || OpenStruct
- end
-
- def results(profile, opts = {}, &block)
- @profile = profile.is_a?(Profile) ? profile : Profile.first(profile, opts.fetch(:session, Session))
-
- if @profile
- @start_date = opts.fetch(:start_date, Time.now - MONTH)
- @end_date = opts.fetch(:end_date, Time.now)
- @limit = opts.fetch(:limit, nil)
- @offset = opts.fetch(:offset, nil)
-
- instance_eval(&block) if block_given?
-
- ReportResponse.new(send_request_for_body, instance_klass).results
- else
- []
- end
- end
-
- def page_params
- {'max-results' => @limit, 'start-index' => @offset}.reject{|k,v| v.nil?}
- end
-
- def default_params
- {'ids' => @profile.table_id,
- 'start-date' => format_time(@start_date),
- 'end-date' => format_time(@end_date)}
- end
-
- def segment_params
- segment.nil? ? {} : {'segment' => segment}
- end
-
- def params
- [
- metrics.to_params,
- dimensions.to_params,
- sort.to_params,
- filters.to_params,
- page_params,
- segment_params
- ].inject(default_params) do |p, i|
- p.merge(i)
- end
- end
-
- def format_time(t)
- t.strftime('%Y-%m-%d')
- end
-
- def send_request_for_body
- request = DataRequest.new(@profile.session, URL, params)
- response = request.send_request
- response.body
- end
- end
-end
View
2 lib/garb/session.rb
@@ -6,7 +6,7 @@ module Methods
# use only for single user authentication
def login(email, password, opts={})
self.email = email
- auth_request = AuthenticationRequest.new(email, password, opts)
+ auth_request = Request::Authentication.new(email, password, opts)
self.auth_token = auth_request.auth_token(opts)
end
View
2 lib/garb/version.rb
@@ -3,7 +3,7 @@ module Version
MAJOR = 0
MINOR = 9
- TINY = 1
+ TINY = 2
def self.to_s # :nodoc:
[MAJOR, MINOR, TINY].join('.')
View
5 lib/support.rb
@@ -1,3 +1,7 @@
+unless Object.const_defined?("ActiveSupport")
+ require File.expand_path("./lib/support/string.rb")
+end
+
class SymbolOperator
def initialize(field, operator)
@field, @operator = field, operator
@@ -34,6 +38,7 @@ class Symbol
:substring, :not_substring].each do |operator|
define_method(operator) do
+ warn("The use of SymbolOperator(#{operator}, etc.) has been deprecated. Please use named filters.")
SymbolOperator.new(self, operator)
end unless method_defined?(operator)
end
View
49 lib/support/string.rb
@@ -0,0 +1,49 @@
+# Pull in some AS String utilities (not loaded if AS is available)
+unless Object.const_defined?("ActiveSupport")
+ class String
+ def camelize(first_letter = :upper)
+ case first_letter
+ when :upper then ActiveSupport::Inflector.camelize(self, true)
+ when :lower then ActiveSupport::Inflector.camelize(self, false)
+ end
+ end
+ alias_method :camelcase, :camelize
+
+ def underscore
+ ActiveSupport::Inflector.underscore(self)
+ end
+
+ def demodulize
+ ActiveSupport::Inflector.demodulize(self)
+ end
+ end
+
+
+ module ActiveSupport
+ module Inflector
+ extend self
+
+ def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
+ if first_letter_in_uppercase
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
+ else
+ lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
+ end
+ end
+
+ def underscore(camel_cased_word)
+ word = camel_cased_word.to_s.dup
+ word.gsub!(/::/, '/')
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
+ word.tr!("-", "_")
+ word.downcase!
+ word
+ end
+
+ def demodulize(class_name_in_module)
+ class_name_in_module.to_s.gsub(/^.*::/, '')
+ end
+ end
+ end
+end
View
1 test/fixtures/profile_feed.json
@@ -0,0 +1 @@
+{"feed":{"id":"http://www.google.com/analytics/feeds/accounts/blah@gmail.com","updated":"2010-05-06T19:27:28.028-07:00","title":"Profile list for blah@gmail.com","link":{"rel":"self","type":"application/atom+xml","href":"https://www.google.com/analytics/feeds/accounts/default"},"author":{"name":"Google Analytics"},"generator":"Google Analytics","openSearch:totalResults":"2","openSearch:startIndex":"1","openSearch:itemsPerPage":"2","dxp$segment":[{"dxp$definition":null,"id":"gaid::-1","name":"All Visits"},{"dxp$definition":"ga:visitorType==New Visitor","id":"gaid::-2","name":"New Visitors"},{"dxp$definition":"ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==ppc","id":"gaid::-3","name":"Paid Search Traffic"},{"dxp$definition":"ga:city!=New York","id":"gaid::0","name":"Not New York"}],"entry":[{"id":"http://www.google.com/analytics/feeds/accounts/ga:12345","updated":"2008-07-21T14:05:57.000-07:00","title":"Historical","link":{"rel":"alternate","type":"text/html","href":"http://www.google.com/analytics"},"ga:goal":[{"ga:destination":{"caseSensitive":"false","expression":"/blog.html","matchType":"head","step1Required":"false"},"active":"true","name":"Read Blog","number":"1","value":"10.0"},{"ga:destination":{"caseSensitive":"false","expression":"/support.html","matchType":"head","step1Required":"false"},"active":"true","name":"Go for Support","number":"2","value":"5.0"},{"ga:destination":{"ga:step":{"name":"Contact Form Page","number":"1","path":"/contact.html"},"caseSensitive":"false","expression":"/contact-submit","matchType":"exact","step1Required":"true"},"active":"true","name":"Contact Form Submission","number":"3","value":"100.0"},{"ga:destination":{"caseSensitive":"false","expression":"/newsletter-submit","matchType":"exact","step1Required":"false"},"active":"true","name":"Newsletter Form Submission","number":"4","value":"25.0"}],"dxp$property":[{"name":"ga:accountId","value":"1111"},{"name":"ga:accountName","value":"Blog Beta"},{"name":"ga:profileId","value":"1212"},{"name":"ga:webPropertyId","value":"UA-1111-1"},{"name":"ga:currency","value":"USD"},{"name":"ga:timezone","value":"America/New_York"}],"dxp:tableId":"ga:12345","gd:etag":"W/\"CUcHSXs8fip7I2A9WxBUFUg.\"","gd:kind":"analytics#account"},{"id":"http://www.google.com/analytics/feeds/accounts/ga:12346","updated":"2008-11-24T11:51:07.000-08:00","title":"Presently","link":{"rel":"alternate","type":"text/html","href":"http://www.google.com/analytics"},"ga:goal":[{"ga:destination":{"ga:step":{"name":"Contact Form Page","number":"1","path":"/contact.html"},"caseSensitive":"false","expression":"/contact-submit","matchType":"exact","step1Required":"true"},"active":"true","name":"Contact Form Submission","number":"1","value":"100.0"},{"ga:destination":{"caseSensitive":"false","expression":"/newsletter-submit","matchType":"exact","step1Required":"false"},"active":"true","name":"Newsletter Form Submission","number":"2","value":"25.0"}],"dxp$property":[{"name":"ga:accountId","value":"1111"},{"name":"ga:accountName","value":"Blog Beta"},{"name":"ga:profileId","value":"1213"},{"name":"ga:webPropertyId","value":"UA-1111-2"},{"name":"ga:currency","value":"USD"},{"name":"ga:timezone","value":"America/New_York"}],"dxp:tableId":"ga:12346","gd:etag":"W/\"A0UASX45cCp7I2A9WxFQEUQ.\"","gd:kind":"analytics#account"}],"xmlns":"http://www.w3.org/2005/Atom","xmlns:dxp":"http://schemas.google.com/analytics/2009","xmlns:ga":"http://schemas.google.com/ga/2009","xmlns:openSearch":"http://a9.com/-/spec/opensearch/1.1/","xmlns:gd":"http://schemas.google.com/g/2005","gd:etag":"W/\"A0UASX45cCp7I2A9WxFQEUQ.\"","gd:kind":"analytics#accounts"}}
View
1 test/fixtures/report_feed.json
@@ -0,0 +1 @@
+{"feed":{"id":"http://www.google.com/analytics/feeds/data?ids=ga:123456&dimensions=ga:country,ga:city&metrics=ga:pageViews&start-date=2008-01-01&end-date=2008-01-02","updated":"2008-01-02T15:59:59.999-08:00 ","title":"Google Analytics Data for Profile 123456","link":[{"href":"http://www.google.com/analytics/feeds/data","rel":"http://schemas.google.com/g/2005#feed","type":"application/atom+xml"},{"href":"http://www.google.com/analytics/feeds/data?end-date=2008-01-02&start-date=2008-01-01&metrics=ga%3ApageViews&ids=ga%3A983247&dimensions=ga%3Acountry%2Cga%3Acity","rel":"self","type":"application/atom+xml"},{"href":"http://www.google.com/analytics/feeds/data?start-index=1001&max-results=1000&end-date=2008-01-02&start-date=2008-01-01&metrics=ga%3ApageViews&ids=ga%3A983247&dimensions=ga%3Acountry%2Cga%3Acity","rel":"next","type":"application/atom+xml"}],"author":{"name":"Google Analytics"},"openSearch:startIndex":"3","openSearch:itemsPerPage":"4","openSearch:totalResults":"18","dxp$containsSampledData":"true","ga:webPropertyID":"UA-123456-78","ga:start_date":"2008-01-01","ga:end_date":"2008-01-02","entry":[{"id":" http://www.google.com/analytics/feeds/data?ids=ga:1174&ga:country=%28not%20set%29&ga:city=%28not%20set%29&start-date=2008-01-01&end-date=2008-01-02 ","updated":" 2008-01-01T16:00:00.001-08:00 ","title":" ga:country=(not set) | ga:city=(not set) ","link":{"href":"http://www.google.com/analytics/feeds/data","rel":"self","type":"application/atom+xml"},"dxp$dimension":[{"name":"ga:country","value":"(not set)"},{"name":"ga:city","value":"(not set)"}],"dxp$metric":{"name":"ga:pageviews","value":"33"}},{"id":" http://www.google.com/analytics/feeds/data?ids=ga:1174&ga:country=Afghanistan&ga:city=Kabul&start-date=2008-01-01&end-date=2008-01-02 ","updated":" 2008-01-01T16:00:00.001-08:00 ","title":" ga:country=Afghanistan | ga:city=Kabul ","dxp$dimension":[{"name":"ga:country","value":"Afghanistan"},{"name":"ga:city","value":"Kabul"}],"dxp$metric":{"name":"ga:pageviews","value":"2"}},{"id":" http://www.google.com/analytics/feeds/data?ids=ga:1174&ga:country=Albania&ga:city=Tirana&start-date=2008-01-01&end-date=2008-01-02 ","updated":" 2008-01-01T16:00:00.001-08:00 ","title":" ga:country=Albania | ga:city=Tirana ","dxp$dimension":[{"name":"ga:country","value":"Albania"},{"name":"ga:city","value":"Tirana"}],"dxp$metric":{"name":"ga:pageviews","value":"1"}}],"xmlns":"http://www.w3.org/2005/Atom","xmlns:openSearch":"http://a9.com/-/spec/opensearchrss/1.0/","xmlns:dxp":"http://schemas.google.com/analytics/2009","xmlns:ga":"http://schemas.google.com/analytics/2008"}}
View
3 test/test_helper.rb
@@ -15,7 +15,6 @@
$:.reject! { |e| e.include? 'TextMate' }
-require 'rubygems'
require 'bundler'
Bundler.setup(:default, :test)
@@ -38,7 +37,7 @@ def read_fixture(filename)
end
def assert_data_params(expected)
- assert_received(Garb::DataRequest, :new) {|e| e.with(Garb::Session, Garb::Model::URL, expected)}
+ assert_received(Garb::Request::Data, :new) {|e| e.with(Garb::Session, Garb::Model::URL, expected)}
end
end
View
42 test/unit/garb/account_feed_request_test.rb
@@ -1,42 +0,0 @@
-require 'test_helper'
-
-module Garb
- class AccountFeedRequestTest < MiniTest::Unit::TestCase
- context "An AccountFeedRequest" do
- setup do
- @request = stub
- DataRequest.stubs(:new).returns(@request)
- @feed = AccountFeedRequest.new
- end
-
- should "have a parsed response" do
- Crack::XML.stubs(:parse)
- @feed.stubs(:response).returns(stub(:body => 'response body'))
- @feed.parsed_response
-
- assert_received(Crack::XML, :parse) {|e| e.with('response body')}
- end
-
- should "have entries from the parsed response" do
- @feed.stubs(:parsed_response).returns({'feed' => {'entry' => ['entry1', 'entry2']}})
- assert_equal ['entry1', 'entry2'], @feed.entries
- end
-
- should "have segements from the parsed response" do
- @feed.stubs(:parsed_response).returns({'feed' => {'dxp:segment' => ['segment1', 'segment2']}})
- assert_equal ['segment1', 'segment2'], @feed.segments
- end
-
- should "have an empty array for entries without a response" do
- @feed.stubs(:parsed_response).returns(nil)
- assert_equal [], @feed.entries
- end
-
- should "have a response from the request" do
- @request.stubs(:send_request)
- @feed.response
- assert_received(@request, :send_request)
- end
- end
- end
-end
View
53 test/unit/garb/account_test.rb
@@ -1,53 +0,0 @@
-require 'test_helper'
-
-module Garb
- class AccountTest < MiniTest::Unit::TestCase
- context "The Account class" do
- should "have an array of accounts with all profiles" do
- p1 = stub(:account_id => '1111', :account_name => 'Blog 1')
- p2 = stub(:account_id => '1112', :account_name => 'Blog 2')
-
- Profile.stubs(:all).returns([p1,p2,p1,p2])
- Account.stubs(:new).returns('account1', 'account2')
-
- assert_equal ['account1','account2'], Account.all
- assert_received(Profile, :all)
- assert_received(Account, :new) {|e| e.with([p1,p1])}
- assert_received(Account, :new) {|e| e.with([p2,p2])}
- end
- end
-
- context "An instance of the Account class" do
- setup do
- profile = stub(:account_id => '1111', :account_name => 'Blog 1')
- @profiles = [profile,profile]
- @account = Account.new(@profiles)
- end
-
- context "all" do
- should "use an optional user session" do
- session = Session.new
- Garb::Profile.expects(:all).with(session).returns(@profiles)
-
- accounts = Account.all(session)
- assert_equal 1, accounts.size
- assert_equal @profiles, accounts.first.profiles
- end
- end
-
- context "when creating a new account from an array of profiles" do
- should "take the account id from the first profile" do
- assert_equal @profiles.first.account_id, @account.id
- end
-
- should "take the account name from the first profile" do
- assert_equal @profiles.first.account_name, @account.name
- end
-
- should "store the array of profiles" do
- assert_equal @profiles, @account.profiles
- end
- end
- end
- end
-end
View
121 test/unit/garb/authentication_request_test.rb
@@ -1,121 +0,0 @@
-require 'test_helper'
-
-CA_CERT_FILE = File.join(File.dirname(__FILE__), '..', '/cacert.pem')
-
-module Garb
- class AuthenticationRequestTest < MiniTest::Unit::TestCase
-
- context "An instance of the AuthenticationRequest class" do
-
- setup { @request = AuthenticationRequest.new('email', 'password') }
-
- should "have a collection of parameters that include the email and password" do
- expected =
- {
- 'Email' => 'user@example.com',
- 'Passwd' => 'fuzzybunnies',
- 'accountType' => 'HOSTED_OR_GOOGLE',
- 'service' => 'analytics',
- 'source' => 'vigetLabs-garb-001'
- }
-
- request = AuthenticationRequest.new('user@example.com', 'fuzzybunnies')
- assert_equal expected, request.parameters
- end
-
- should "have a URI" do
- assert_equal URI.parse('https://www.google.com/accounts/ClientLogin'), @request.uri
- end
-
- should "be able to send a request to the GAAPI service with proper ssl" do
- @request.expects(:build_request).returns('post')
-
- response = mock {|m| m.expects(:is_a?).with(Net::HTTPOK).returns(true) }
-
- http = mock do |m|
- m.expects(:use_ssl=).with(true)
- m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
- m.expects(:ca_file=).with(CA_CERT_FILE)
- m.expects(:request).with('post').yields(response)
- end
-
- Net::HTTP.expects(:new).with('www.google.com', 443).returns(http)
-
- @request.send_request(OpenSSL::SSL::VERIFY_PEER)
- end
-
- should "be able to send a request to the GAAPI service with ignoring ssl" do
- @request.expects(:build_request).returns('post')
-
- response = mock {|m| m.expects(:is_a?).with(Net::HTTPOK).returns(true) }
-
- http = mock do |m|
- m.expects(:use_ssl=).with(true)
- m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
- m.expects(:request).with('post').yields(response)
- end
-
- Net::HTTP.expects(:new).with('www.google.com', 443).returns(http)
-
- @request.send_request(OpenSSL::SSL::VERIFY_NONE)
- end
-
- should "be able to build a request for the GAAPI service" do
- params = "param"
- @request.expects(:parameters).with().returns(params)
-
- post = mock
- post.expects(:set_form_data).with(params)
-
- Net::HTTP::Post.expects(:new).with('/accounts/ClientLogin').returns(post)
-
- @request.build_request
- end
-
- should "be able to retrieve an auth_token from the body" do
- response_data =
- "SID=mysid\n" +
- "LSID=mylsid\n" +
- "Auth=auth_token\n"
-
- @request.expects(:send_request).with(OpenSSL::SSL::VERIFY_NONE).returns(stub(:body => response_data))
-
- assert_equal 'auth_token', @request.auth_token
- end
-
- should "use VERIFY_PEER if auth_token needs to be secure" do
- response_data =
- "SID=mysid\n" +
- "LSID=mylsid\n" +
- "Auth=auth_token\n"
-
- @request.expects(:send_request).with(OpenSSL::SSL::VERIFY_PEER).returns(stub(:body => response_data))
-
- assert_equal 'auth_token', @request.auth_token(:secure => true)
- end
-
- should "raise an exception when requesting an auth_token when the authorization fails" do
- @request.stubs(:build_request)
- response = mock do |m|
- m.expects(:is_a?).with(Net::HTTPOK).returns(false)
- end
-
- http = stub do |s|
- s.stubs(:use_ssl=)
- s.stubs(:verify_mode=)
- s.stubs(:request).yields(response)
- end
-
- Net::HTTP.stubs(:new).with('www.google.com', 443).returns(http)
-
- assert_raises(Garb::AuthenticationRequest::AuthError) do
- @request.send_request(OpenSSL::SSL::VERIFY_NONE)
- end
- end
-
- end
-
-
-
- end
-end
View
107 test/unit/garb/data_request_test.rb
@@ -1,107 +0,0 @@
-require 'test_helper'
-
-module Garb
- class DataRequestTest < MiniTest::Unit::TestCase
-
- context "An instance of the DataRequest class" do
- setup do
- @session = Session.new
- @session.auth_token = 'abcdefg123456'
- end
-
- should "be able to build the query string from parameters" do
- parameters = {'ids' => '12345', 'metrics' => 'country'}
- data_request = DataRequest.new(@session, "", parameters)
-
- query_string = data_request.query_string
-
- assert_match(/^\?/, query_string)
-
- query_string.sub!(/^\?/, '')
-
- assert_equal ["ids=12345", "metrics=country"], query_string.split('&').sort
- end
-
- should "return an empty query string if parameters are empty" do
- data_request = DataRequest.new(@session, "")
- assert_equal "", data_request.query_string
- end
-
- should "be able to build a uri" do
- url = 'http://example.com'
- assert_equal URI.parse(url), DataRequest.new(@session, url).uri
- end
-
- should "be able to send a request for a single user" do
- @session.stubs(:single_user?).returns(true)
- response = mock('Net::HTTPOK') do |m|
- m.expects(:kind_of?).with(Net::HTTPSuccess).returns(true)
- end
-
- data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
- data_request.stubs(:single_user_request).returns(response)
- data_request.send_request
-
- assert_received(data_request, :single_user_request)
- end
-
- should "be able to send a request for an oauth user" do
- @session.stubs(:single_user?).returns(false)
- @session.stubs(:oauth_user?).returns(true)
- response = mock('Net::HTTPOK') do |m|
- m.expects(:kind_of?).with(Net::HTTPSuccess).returns(true)
- end
-
- data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
- data_request.stubs(:oauth_user_request).returns(response)
- data_request.send_request
-
- assert_received(data_request, :oauth_user_request)
- end
-
- should "raise if the request is unauthorized" do
- @session.stubs(:single_user?).returns(false)
- @session.stubs(:oauth_user?).returns(true)
- response = mock('Net::HTTPUnauthorized', :body => 'Error')
-
- data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
- data_request.stubs(:oauth_user_request).returns(response)
-
- assert_raises(Garb::DataRequest::ClientError) do
- data_request.send_request
- end
- end
-
- should "be able to request via the ouath access token" do
- access_token = stub(:get => "responseobject")
- @session.stubs(:access_token).returns(access_token)
-
- data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
- assert_equal 'responseobject', data_request.oauth_user_request
-
- assert_received(@session, :access_token)
- assert_received(access_token, :get) {|e| e.with('https://example.com/data?key=value', {'GData-Version' => '2'})}
- end
-
- should "be able to request via http with an auth token" do
- @session.expects(:auth_token).with().returns('toke')
- response = mock
-
- http = mock do |m|
- m.expects(:use_ssl=).with(true)
- m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
- m.expects(:get).with('/data?key=value', {
- 'Authorization' => 'GoogleLogin auth=toke',
- 'GData-Version' => '2'
- }).returns(response)
- end
-
- Net::HTTP.expects(:new).with('example.com', 443).returns(http)
-
- data_request = DataRequest.new(@session, 'https://example.com/data', 'key' => 'value')
- assert_equal response, data_request.single_user_request
- end
- end
-
- end
-end
View
28 test/unit/garb/destination_test.rb
@@ -1,28 +0,0 @@
-require 'test_helper'
-
-module Garb
- class DestinationTest < MiniTest::Unit::TestCase
- context 'A Destination' do
- should "have a match_type and an expression" do
- destination = Destination.new({'matchType' => 'exact', 'expression' => '/contact.html', 'caseSensitive' => 'false'})
- assert_equal 'exact', destination.match_type
- assert_equal '/contact.html', destination.expression
- end
-
- should "know if it's case sensitive" do
- destination = Destination.new({'matchType' => 'exact', 'expression' => '/contact.html', 'caseSensitive' => 'true'})
- assert_equal true, destination.case_sensitive?
- end
-
- should "know if it's not case sensitive" do
- destination = Destination.new({'matchType' => 'exact', 'expression' => '/contact.html', 'caseSensitive' => 'false'})
- assert_equal false, destination.case_sensitive?
- end
-
- should "have steps" do
- destination = Destination.new({'ga:step' => {'name' => 'Contact', 'number' => '1', 'path' => '/'}})
- assert_equal ['Contact'], destination.steps.map(&:name)
- end
- end
- end
-end
View
65 test/unit/garb/filter_parameters_test.rb
@@ -2,65 +2,44 @@
module Garb
class FilterParametersTest < MiniTest::Unit::TestCase
- def self.should_define_operators(*operators)
- operators.each do |operator|
- should "create an operator and add to parameters for the #{operator} method" do
- new_operator = stub
- symbol = :foo
-
- SymbolOperator.expects(:new).with(:bar, operator).returns(new_operator)
- @filter_parameters.filters do
- send(operator.to_sym, :bar, 100)
- end
-
- parameter = {new_operator => 100}
- assert_equal parameter, @filter_parameters.parameters.last
- end
- end
- end
+ # def self.should_define_operators(*operators)
+ # operators.each do |operator|
+ # should "create an operator and add to parameters for the #{operator} method" do
+ # new_operator = stub
+ # symbol = :foo
+ #
+ # SymbolOperator.expects(:new).with(:bar, operator).returns(new_operator)
+ # @filter_parameters.filters do
+ # send(operator.to_sym, :bar, 100)
+ # end
+ #
+ # parameter = {new_operator => 100}
+ # assert_equal parameter, @filter_parameters.parameters.last
+ # end
+ # end
+ # end
context "A FilterParameters" do
- setup do
- @filter_parameters = FilterParameters.new
- end
-
- should_define_operators :eql, :not_eql, :gt, :gte, :lt, :lte,
- :matches, :does_not_match, :contains, :does_not_contain, :substring, :not_substring
-
- should "instance eval for filters" do
- blk = lambda {"in a block"}
-
- @filter_parameters.expects(:instance_eval)
- @filter_parameters.filters(&blk)
- end
-
context "when converting parameters hash into query string parameters" do
should "parameterize hash operators and join elements with AND" do
- @filter_parameters.filters do
- eql(:city, 'New York City')
- eql(:state, 'New York')
- end
+ filters = FilterParameters.new({:city.eql => 'New York City', :state.eql => 'New York'})
params = ['ga:city%3D%3DNew+York+City', 'ga:state%3D%3DNew+York']
- assert_equal params, @filter_parameters.to_params['filters'].split('%3B').sort
+ assert_equal params, filters.to_params['filters'].split('%3B').sort
end
should "properly encode operators" do
- @filter_parameters.filters do
- contains(:page_path, 'New York')
- end
+ filters = FilterParameters.new({:page_path.contains => 'New York'})
params = {'filters' => 'ga:pagePath%3D~New+York'}
- assert_equal params, @filter_parameters.to_params
+ assert_equal params, filters.to_params
end
should "escape comma, semicolon, and backslash in values" do
- @filter_parameters.filters do
- eql(:url, 'this;that,thing\other')
- end
+ filters = FilterParameters.new({:url.eql => 'this;that,thing\other'})
params = {'filters' => 'ga:url%3D%3Dthis%5C%3Bthat%5C%2Cthing%5C%5Cother'}
- assert_equal params, @filter_parameters.to_params
+ assert_equal params, filters.to_params
end
end
end
View
24 test/unit/garb/goal_test.rb
@@ -1,24 +0,0 @@
-require 'test_helper'
-
-module Garb
- class GoalTest < MiniTest::Unit::TestCase
- context "A Goal" do
- should "have a name, number, and value" do
- goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'true'})
- assert_equal 'Read Blog', goal.name
- assert_equal 1, goal.number
- assert_equal 10.0, goal.value
- end
-
- should "know if it is active" do
- goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'true'})
- assert goal.active?
- end
-
- should "know if it is not active" do
- goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'false'})
- assert_equal false, goal.active?
- end
- end
- end
-end
View
2 test/unit/garb/management/account_test.rb
@@ -22,7 +22,7 @@ class AccountTest < MiniTest::Unit::TestCase
entry = {
"title" => "Google Analytics Account Garb",
"link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/123456"}],
- "dxp:property" => [
+ "dxp$property" => [
{"name" => "ga:accountId", "value" => "123456"},
{"name" => "ga:accountName", "value" => "Garb"}
]
View
8 test/unit/garb/management/feed_test.rb
@@ -6,16 +6,16 @@ class FeedTest < MiniTest::Unit::TestCase
context "a Feed" do
setup do
@request = stub
- DataRequest.stubs(:new).returns(@request)
+ Request::Data.stubs(:new).returns(@request)
@feed = Feed.new(Garb::Session.new, '/accounts')
end
should "have a parsed response" do
- Crack::XML.stubs(:parse)
+ JSON.stubs(:parse)
@feed.stubs(:response).returns(stub(:body => 'response body'))
@feed.parsed_response
- assert_received(Crack::XML, :parse) {|e| e.with('response body')}
+ assert_received(JSON, :parse) {|e| e.with('response body')}
end
should "have entries from the parsed response" do
@@ -41,4 +41,4 @@ class FeedTest < MiniTest::Unit::TestCase
end
end
end
-end
+end
View
2 test/unit/garb/management/profile_test.rb
@@ -33,7 +33,7 @@ class ProfileTest < MiniTest::Unit::TestCase
setup do
entry = {
"link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/1189765/webproperties/UA-1189765-1/profiles/98765"}],
- "dxp:property" => [
+ "dxp$property" => [
{"name" => "ga:profileId", "value" => "98765"},
{"name" => "ga:accountId", "value" => "1189765"},
{"name" => "ga:webPropertyId", "value" => 'UA-1189765-1'},
View
2 test/unit/garb/management/web_property_test.rb
@@ -30,7 +30,7 @@ class WebPropertyTest < MiniTest::Unit::TestCase
setup do
entry = {
"link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/1189765/webproperties/UA-1189765-1"}],
- "dxp:property" => [
+ "dxp$property" => [
{"name" => "ga:accountId", "value" => "1189765"},
{"name" => "ga:webPropertyId", "value" => 'UA-1189765-1'}
]
View
9 test/unit/garb/model_test.rb
@@ -44,7 +44,7 @@ class ModelTest < MiniTest::Unit::TestCase
entry = {
"title" => "Google Analytics Profile example.com",
"link" => [{"rel" => "self", "href" => Garb::Management::Feed::BASE_URL+"/accounts/1189765/webproperties/UA-1189765-1/profiles/98765"}],
- "dxp:property" => [
+ "dxp$property" => [
{"name" => "ga:profileId", "value" => "98765"},
{"name" => "ga:accountId", "value" => "1189765"},
{"name" => "ga:webPropertyId", "value" => 'UA-1189765-1'}
@@ -57,7 +57,7 @@ class ModelTest < MiniTest::Unit::TestCase
context "when getting results" do
setup do
@response = stub(:body => "raw report data")
- DataRequest.stubs(:new).returns(stub(:send_request => @response))
+ Request::Data.stubs(:new).returns(stub(:send_request => @response))
ReportResponse.stubs(:new).returns(stub(:results => ['result']))
@test_model.stubs(:metrics).returns(stub(:to_params => {'metrics' => 'ga:visits'}))
@@ -82,12 +82,11 @@ class ModelTest < MiniTest::Unit::TestCase
end
should "be able to filter" do
- filter_parameters = stub(:<<)
- FilterParameters.stubs(:new).returns(stub(:parameters => filter_parameters, :to_params => {'filters' => "params"}))
+ FilterParameters.stubs(:new).returns(stub(:to_params => {'filters' => "params"}))
assert_equal ['result'], @test_model.results(@profile, :filters => {:page_path => '/'})
assert_data_params(@params.merge({'filters' => 'params'}))
- assert_received(filter_parameters, :<<) {|e| e.with({:page_path => '/'})}
+ assert_received(FilterParameters, :new) {|e| e.with({:page_path => '/'})}
end
should "be able to set the filter segment by id" do
View
77 test/unit/garb/profile_test.rb
@@ -1,77 +0,0 @@
-require 'test_helper'
-
-module Garb
- class ProfileTest < MiniTest::Unit::TestCase
-
- context "The Profile class" do
- setup {@session = Session.new}
-
- should "be able to return a list of all profiles" do
- afr = AccountFeedRequest.new
- afr.stubs(:parsed_response).returns(Crack::XML.parse(read_fixture('profile_feed.xml')))
- AccountFeedRequest.stubs(:new).returns(afr)
-
- assert_equal ['12345', '12346'], Profile.all(@session).map(&:id)
- assert_received(AccountFeedRequest, :new) {|e| e.with(@session)}
- end
-
- should "return the first profile for a given web property id" do
- profile1 = stub(:web_property_id => '12345', :id => 'abcdef')
- profile2 = stub(:web_property_id => '67890', :id => 'ghijkl')
- entries = [profile1, profile2]
-
- Profile.stubs(:all).returns(entries)
-
- assert_equal profile1, Profile.first('12345', @session)
-
- assert_received(Profile, :all) {|e| e.with(@session)}
- end
-
- should "return the first profile for a given table id" do
- profile1 = stub(:id => '12345', :web_property_id => 'abcdef')
- profile2 = stub(:id => '67890', :web_property_id => 'ghijkl')
- entries = [profile1, profile2]
-
- Profile.stubs(:all).returns(entries)
-
- assert_equal profile2, Profile.first('67890', @session)
-
- assert_received(Profile, :all) {|e| e.with(@session)}
- end
- end
-
- context "A Profile" do
- setup do
- afr = AccountFeedRequest.new
- afr.stubs(:parsed_response).returns(Crack::XML.parse(read_fixture('profile_feed.xml')))
-
- entry = afr.entries.first
- @profile = Profile.new(entry, Session)
- end
-
- should "have a value for :title" do
- assert_equal "Historical", @profile.title
- end
-
- should "have a value for :table_id" do
- assert_equal 'ga:12345', @profile.table_id
- end
-
- should "have a value for :id" do
- assert_equal '12345', @profile.id
- end
-
- should "have a value for :account_id" do
- assert_equal '1111', @profile.account_id
- end
-
- should "have a value for :account_name" do
- assert_equal 'Blog Beta', @profile.account_name
- end
-
- should "have goals" do
- assert_equal 4, @profile.goals.size
- end
- end
- end
-end
View
16 test/unit/garb/report_response_test.rb
@@ -7,38 +7,38 @@ class ReportResponseTest < MiniTest::Unit::TestCase
context "A ReportResponse" do
context "with a report feed" do
setup do
- @xml = File.read(File.join(File.dirname(__FILE__), '..', '..', "/fixtures/report_feed.xml"))
+ @json = File.read(File.join(File.dirname(__FILE__), '..', '..', "/fixtures/report_feed.json"))
end
should "parse results from atom xml" do
- response = ReportResponse.new(@xml)
+ response = ReportResponse.new(@json)
assert_equal ['33', '2', '1'], response.results.map(&:pageviews)
end
should "default to returning an array of OpenStruct objects" do
- response = ReportResponse.new(@xml)
+ response = ReportResponse.new(@json)
assert_equal [OpenStruct, OpenStruct, OpenStruct], response.results.map(&:class)
end
should "return an array of instances of a specified class" do
- response = ReportResponse.new(@xml, SpecialKlass)
+ response = ReportResponse.new(@json, SpecialKlass)
assert_equal [SpecialKlass, SpecialKlass, SpecialKlass], response.results.map(&:class)
end
should "know the total number of results" do
- response = ReportResponse.new(@xml)
+ response = ReportResponse.new(@json)
assert_equal 18, response.results.total_results
end
should "know if the data has been sampled" do
- response = ReportResponse.new(@xml)
+ response = ReportResponse.new(@json)
assert_equal true, response.results.sampled?
end
end
should "return an empty array if there are no results" do
- response = ReportResponse.new("result xml")
- Crack::XML.stubs(:parse).with("result xml").returns({'feed' => {'entry' => nil}})
+ response = ReportResponse.new("result json")
+ JSON.stubs(:parse).with("result json").returns({'feed' => {'entry' => nil}})
assert_equal [], response.results.to_a
end
View
99 test/unit/garb/report_test.rb
@@ -1,99 +0,0 @@
-require 'test_helper'
-
-module Garb
- # Also tests Garb::Resource, which is the basis for Garb::Report
- class ReportTest < MiniTest::Unit::TestCase
- context "An instance of the Report class" do
- setup do
- @now = Time.now
- Time.stubs(:now).returns(@now)
- @profile = stub(:table_id => 'ga:1234', :session => Session)
- @report = Report.new(@profile)
- end
-
- %w(metrics dimensions sort).each do |param|
- should "have parameters for #{param}" do
- assert @report.send(:"#{param}").is_a?(ReportParameter)
- end
-
- should "clear parameters for #{param}" do
- assert_equal({}, @report.send(:"clear_#{param}").to_params)
- end
- end
-
- should "have filter parameters for filters" do
- assert @report.filters.is_a?(FilterParameters)
- end
-
- should "add new filters to filter parameters" do
- @report.clear_filters
- hash = {:thing.gt => 'val'}
- @report.filters hash
-
- assert_equal hash, @report.filters.parameters.first
- end
-
- should "clear filter parameters for filters" do
- assert_equal({}, @report.clear_filters.to_params)
- end
-
- should "have default parameters" do
- @report.stubs(:format_time).returns('2009-08-01')
- params = {'ids' => 'ga:1234', 'start-date' => '2009-08-01', 'end-date' => '2009-08-01'}
- assert_equal params, @report.default_params
- end
-
- should "allow setting a segment id to the segment params" do
- @report.set_segment_id 121
- assert_equal({'segment' => 'gaid::121'}, @report.segment_params)
- end
-
- should "collect params from metrics, dimensions, filters, sort, and defaults" do
- @report.stubs(:metrics).returns(stub(:to_params => {'metrics' => 6}))
- @report.stubs(:dimensions).returns(stub(:to_params => {'dimensions' => 5}))
- @report.stubs(:filters).returns(stub(:to_params => {'filters' => 4}))
- @report.stubs(:sort).returns(stub(:to_params => {'sort' => 3}))
- @report.stubs(:page_params).returns({'page_params' => 2})
- @report.stubs(:default_params).returns({'default_params' => 1})
- @report.stubs(:segment_params).returns({'segment' => 'gaid::10'})
-
- expected_params = {'metrics' => 6,'dimensions' => 5, 'filters' => 4, 'sort' => 3,
- 'page_params' => 2, 'default_params' => 1, 'segment' => 'gaid::10'}
-
- assert_equal expected_params, @report.params
- end
-
- should "format time" do
- assert_equal @now.strftime('%Y-%m-%d'), @report.format_time(@now)
- end
-
- should "send a data request to GA" do
- response = mock {|m| m.expects(:body).returns('response body') }
- request = mock {|m| m.expects(:send_request).returns(response) }
- @report.expects(:params).returns('params')
-
- DataRequest.expects(:new).with(Session, Garb::Report::URL, 'params').returns(request)
- assert_equal 'response body', @report.send_request_for_body
- end
-
- should "fetch and parse results from GA" do
- @report.expects(:send_request_for_body).with().returns('xml')
- ReportResponse.expects(:new).with('xml').returns(mock(:results => ['entry']))
- assert_equal ['entry'], @report.results
- end
- end
-
- context "An instance of the Report class with initial options" do
- setup do
- @profile = stub(:table_id => 'ga:1234')
- @report = Report.new(@profile, :limit => 10, :offset => 20)
- end
-
- should "have page paramaters" do
- params = {'max-results' => 10, 'start-index' => 20}
- assert_equal params, @report.page_params
- end
- end
-
- end
-end
View
147 test/unit/garb/request/authentication_test.rb
@@ -0,0 +1,147 @@
+require 'test_helper'
+
+CA_CERT_FILE = File.join(File.dirname(__FILE__), '..', '/cacert.pem')
+
+module Garb
+ module Request
+ class AuthenticationTest < MiniTest::Unit::TestCase
+
+ context "An instance of the Request::Authentication class" do
+
+ setup { @request = Request::Authentication.new('email', 'password') }
+ teardown do
+ Garb.proxy_address = nil
+ Garb.proxy_port = nil
+ end
+
+ should "have a collection of parameters that include the email and password" do
+ expected =
+ {
+ 'Email' => 'user@example.com',
+ 'Passwd' => 'fuzzybunnies',
+ 'accountType' => 'HOSTED_OR_GOOGLE',
+ 'service' => 'analytics',
+ 'source' => 'vigetLabs-garb-001'
+ }
+
+ request = Request::Authentication.new('user@example.com', 'fuzzybunnies')
+ assert_equal expected, request.parameters
+ end
+
+ should "have a URI" do
+ assert_equal URI.parse('https://www.google.com/accounts/ClientLogin'), @request.uri
+ end
+
+ should "be able to send a request to the GAAPI service with proper ssl" do
+ @request.expects(:build_request).returns('post')
+
+ response = mock {|m| m.expects(:is_a?).with(Net::HTTPOK).returns(true) }
+
+ http = mock do |m|
+ m.expects(:read_timeout=).with(Garb.read_timeout)
+ m.expects(:use_ssl=).with(true)
+ m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
+ m.expects(:ca_file=).with(CA_CERT_FILE)
+ m.expects(:request).with('post').yields(response)
+ end
+
+ Net::HTTP.expects(:new).with('www.google.com', 443, nil, nil).returns(http)
+
+ @request.send_request(OpenSSL::SSL::VERIFY_PEER)
+ end
+
+ should "be able to send a request to the GAAPI service with ignoring ssl" do
+ @request.expects(:build_request).returns('post')
+
+ response = mock {|m| m.expects(:is_a?).with(Net::HTTPOK).returns(true) }
+
+ http = mock do |m|
+ m.expects(:read_timeout=).with(Garb.read_timeout)
+ m.expects(:use_ssl=).with(true)
+ m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
+ m.expects(:request).with('post').yields(response)
+ end
+
+ Net::HTTP.expects(:new).with('www.google.com', 443, nil, nil).returns(http)
+
+ @request.send_request(OpenSSL::SSL::VERIFY_NONE)
+ end
+
+ should "be able to build a request for the GAAPI service" do
+ params = "param"
+ @request.expects(:parameters).with().returns(params)
+
+ post = mock
+ post.expects(:set_form_data).with(params)
+ post.expects(:read_timeout=).with(Garb.read_timeout)
+
+ Net::HTTP::Post.expects(:new).with('/accounts/ClientLogin').returns(post)
+
+ @request.build_request
+ end
+
+ should "be able to retrieve an auth_token from the body" do
+ response_data =
+ "SID=mysid\n" +
+ "LSID=mylsid\n" +
+ "Auth=auth_token\n"
+
+ @request.expects(:send_request).with(OpenSSL::SSL::VERIFY_NONE).returns(stub(:body => response_data))
+
+ assert_equal 'auth_token', @request.auth_token
+ end
+
+ should "use VERIFY_PEER if auth_token needs to be secure" do
+ response_data =
+ "SID=mysid\n" +
+ "LSID=mylsid\n" +
+ "Auth=auth_token\n"
+
+ @request.expects(:send_request).with(OpenSSL::SSL::VERIFY_PEER).returns(stub(:body => response_data))
+
+ assert_equal 'auth_token', @request.auth_token(:secure => true)
+ end
+
+ should "raise an exception when requesting an auth_token when the authorization fails" do