garb 0.9.1 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +95 -0
  5. data/Gemfile +15 -0
  6. data/README.md +47 -25
  7. data/Rakefile +8 -34
  8. data/garb.gemspec +22 -0
  9. data/lib/garb.rb +71 -48
  10. data/lib/garb/attributes.rb +35 -0
  11. data/lib/garb/core_ext/array.rb +13 -0
  12. data/lib/garb/core_ext/string.rb +48 -0
  13. data/lib/garb/core_ext/symbol.rb +59 -0
  14. data/lib/garb/destination.rb +5 -6
  15. data/lib/garb/errors.rb +20 -0
  16. data/lib/garb/filter_parameters.rb +20 -29
  17. data/lib/garb/management/account.rb +10 -16
  18. data/lib/garb/management/feed.rb +4 -5
  19. data/lib/garb/management/goal.rb +10 -15
  20. data/lib/garb/management/profile.rb +11 -20
  21. data/lib/garb/management/segment.rb +9 -15
  22. data/lib/garb/management/web_property.rb +11 -16
  23. data/lib/garb/model.rb +37 -13
  24. data/lib/garb/path_attribute.rb +7 -0
  25. data/lib/garb/report_parameter.rb +5 -5
  26. data/lib/garb/report_response.rb +29 -28
  27. data/lib/garb/reports/bounces.rb +1 -1
  28. data/lib/garb/reports/exits.rb +1 -1
  29. data/lib/garb/reports/pageviews.rb +1 -1
  30. data/lib/garb/reports/unique_pageviews.rb +1 -1
  31. data/lib/garb/reports/visits.rb +1 -1
  32. data/lib/garb/request/authentication.rb +54 -0
  33. data/lib/garb/request/data.rb +98 -0
  34. data/lib/garb/result_set.rb +23 -9
  35. data/lib/garb/session.rb +3 -3
  36. data/lib/garb/step.rb +4 -4
  37. data/lib/garb/support.rb +6 -0
  38. data/lib/garb/version.rb +3 -3
  39. data/test/fixtures/account_management.json +1 -0
  40. data/test/fixtures/ga_profile_management.json +1 -0
  41. data/test/fixtures/ga_segment_management.json +1 -0
  42. data/test/fixtures/ga_webproperty_management.json +1 -0
  43. data/test/fixtures/goal_management.json +1 -0
  44. data/test/fixtures/profile_feed.json +1 -0
  45. data/test/fixtures/report_feed.json +75 -0
  46. data/test/test_helper.rb +6 -10
  47. data/test/unit/garb/filter_parameters_test.rb +15 -46
  48. data/test/unit/garb/management/account_test.rb +8 -16
  49. data/test/unit/garb/management/feed_test.rb +5 -10
  50. data/test/unit/garb/management/goal_test.rb +7 -21
  51. data/test/unit/garb/management/profile_test.rb +11 -26
  52. data/test/unit/garb/management/segment_test.rb +7 -6
  53. data/test/unit/garb/management/web_property_test.rb +10 -12
  54. data/test/unit/garb/model_test.rb +70 -32
  55. data/test/unit/garb/report_parameter_test.rb +6 -6
  56. data/test/unit/garb/report_response_test.rb +23 -13
  57. data/test/unit/garb/request/authentication_test.rb +152 -0
  58. data/test/unit/garb/request/data_test.rb +157 -0
  59. data/test/unit/garb/session_test.rb +13 -13
  60. data/test/unit/garb_test.rb +4 -11
  61. data/test/unit/symbol_operator_test.rb +3 -3
  62. metadata +90 -292
  63. data/lib/garb/account.rb +0 -22
  64. data/lib/garb/account_feed_request.rb +0 -25
  65. data/lib/garb/authentication_request.rb +0 -53
  66. data/lib/garb/data_request.rb +0 -42
  67. data/lib/garb/goal.rb +0 -20
  68. data/lib/garb/profile.rb +0 -33
  69. data/lib/garb/report.rb +0 -28
  70. data/lib/garb/resource.rb +0 -115
  71. data/lib/support.rb +0 -40
  72. data/test/unit/garb/account_feed_request_test.rb +0 -42
  73. data/test/unit/garb/account_test.rb +0 -53
  74. data/test/unit/garb/authentication_request_test.rb +0 -121
  75. data/test/unit/garb/coverage/assets/0.3.9/app.js +0 -66
  76. data/test/unit/garb/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
  77. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
  78. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
  79. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
  80. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
  81. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
  82. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
  83. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
  84. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
  85. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
  86. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
  87. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
  88. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
  89. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
  90. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
  91. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
  92. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
  93. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
  94. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
  95. data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
  96. data/test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +0 -363
  97. data/test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  98. data/test/unit/garb/coverage/assets/0.3.9/favicon.png +0 -0
  99. data/test/unit/garb/coverage/assets/0.3.9/jquery-1.4.2.min.js +0 -155
  100. data/test/unit/garb/coverage/assets/0.3.9/jquery.dataTables.min.js +0 -152
  101. data/test/unit/garb/coverage/assets/0.3.9/jquery.timeago.js +0 -141
  102. data/test/unit/garb/coverage/assets/0.3.9/jquery.url.js +0 -174
  103. data/test/unit/garb/coverage/assets/0.3.9/loading.gif +0 -0
  104. data/test/unit/garb/coverage/assets/0.3.9/magnify.png +0 -0
  105. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  106. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  107. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  108. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  109. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  110. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  111. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  112. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  113. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
  114. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  115. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
  116. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
  117. data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  118. data/test/unit/garb/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  119. data/test/unit/garb/coverage/assets/0.3.9/stylesheet.css +0 -341
  120. data/test/unit/garb/coverage/index.html +0 -100
  121. data/test/unit/garb/coverage/resultset.yml +0 -5
  122. data/test/unit/garb/data_request_test.rb +0 -107
  123. data/test/unit/garb/destination_test.rb +0 -28
  124. data/test/unit/garb/goal_test.rb +0 -24
  125. data/test/unit/garb/management/coverage/assets/0.3.9/app.js +0 -66
  126. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
  127. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
  128. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
  129. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
  130. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
  131. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
  132. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
  133. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
  134. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
  135. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
  136. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
  137. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
  138. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
  139. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
  140. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
  141. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
  142. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
  143. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
  144. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
  145. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
  146. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +0 -363
  147. data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  148. data/test/unit/garb/management/coverage/assets/0.3.9/favicon.png +0 -0
  149. data/test/unit/garb/management/coverage/assets/0.3.9/jquery-1.4.2.min.js +0 -155
  150. data/test/unit/garb/management/coverage/assets/0.3.9/jquery.dataTables.min.js +0 -152
  151. data/test/unit/garb/management/coverage/assets/0.3.9/jquery.timeago.js +0 -141
  152. data/test/unit/garb/management/coverage/assets/0.3.9/jquery.url.js +0 -174
  153. data/test/unit/garb/management/coverage/assets/0.3.9/loading.gif +0 -0
  154. data/test/unit/garb/management/coverage/assets/0.3.9/magnify.png +0 -0
  155. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  156. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  157. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  158. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  159. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  160. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  161. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  162. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  163. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
  164. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  165. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
  166. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
  167. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  168. data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  169. data/test/unit/garb/management/coverage/assets/0.3.9/stylesheet.css +0 -341
  170. data/test/unit/garb/management/coverage/index.html +0 -100
  171. data/test/unit/garb/management/coverage/resultset.yml +0 -5
  172. data/test/unit/garb/profile_test.rb +0 -77
  173. data/test/unit/garb/report_test.rb +0 -99
  174. data/test/unit/garb/resource_test.rb +0 -50
  175. data/test/unit/garb/step_test.rb +0 -15
@@ -1,21 +1,35 @@
1
+ require 'forwardable'
2
+
1
3
  module Garb
2
4
  class ResultSet
3
5
  include Enumerable
6
+ include Comparable
7
+ extend Forwardable
4
8
 
5
- attr_accessor :total_results, :sampled
6
-
7
- alias :sampled? :sampled
9
+ attr_accessor :results, :total_results, :sampled
10
+ alias_method :sampled?, :sampled
11
+
12
+ def_delegators :results, :each, :to_a, :count, :size, :empty?
8
13
 
9
14
  def initialize(results)
10
15
  @results = results
11
16
  end
12
-
13
- def each(&block)
14
- @results.each(&block)
17
+
18
+ def <=>(other)
19
+ results <=> other.results
15
20
  end
16
-
17
- def to_a
18
- @results
21
+
22
+ def +(other)
23
+ copy = self.dup
24
+ copy.results = @results + other.to_a
25
+ copy
26
+ end
27
+
28
+ def [](*args)
29
+ return @results[*args] if args.size == 1 && args.first.is_a?(Integer)
30
+ copy = self.dup
31
+ copy.results = @results[*args]
32
+ copy
19
33
  end
20
34
  end
21
35
  end
@@ -1,12 +1,12 @@
1
1
  module Garb
2
2
  class Session
3
3
  module Methods
4
- attr_accessor :auth_token, :access_token, :email
4
+ attr_accessor :auth_token, :access_token, :email, :api_key
5
5
 
6
6
  # use only for single user authentication
7
- def login(email, password, opts={})
7
+ def login(email, password, opts = {})
8
8
  self.email = email
9
- auth_request = AuthenticationRequest.new(email, password, opts)
9
+ auth_request = Request::Authentication.new(email, password, opts)
10
10
  self.auth_token = auth_request.auth_token(opts)
11
11
  end
12
12
 
@@ -1,13 +1,13 @@
1
1
  module Garb
2
2
  class Step
3
- attr_reader :name, :number, :path
3
+ attr_reader :name, :number, :url
4
4
 
5
5
  def initialize(attributes)
6
- return unless attributes.is_a?(Hash)
6
+ return unless attributes.is_a? Hash
7
7
 
8
8
  @name = attributes['name']
9
- @number = attributes['number'].to_i
10
- @path = attributes['path']
9
+ @number = attributes['number']
10
+ @url = attributes['url']
11
11
  end
12
12
  end
13
13
  end
@@ -0,0 +1,6 @@
1
+ unless Object.const_defined? 'ActiveSupport'
2
+ require 'garb/core_ext/string'
3
+ require 'garb/core_ext/array'
4
+ end
5
+
6
+ require 'garb/core_ext/symbol'
@@ -1,12 +1,12 @@
1
1
  module Garb
2
- module Version
2
+ module VERSION
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 9
6
- TINY = 1
6
+ TINY = 7
7
7
 
8
8
  def self.to_s # :nodoc:
9
- [MAJOR, MINOR, TINY].join('.')
9
+ [MAJOR, MINOR, TINY].join '.'
10
10
  end
11
11
 
12
12
  end
@@ -0,0 +1 @@
1
+ {"kind":"analytics#accounts","username":"someone@somewhere.com","totalResults":1,"startIndex":1,"itemsPerPage":1000,"items":[{"id":"1234","kind":"analytics#account","selfLink":"https://www.googleapis.com/analytics/v3/management/accounts/1234","name":"www.google.com","created":"2012-1-01T17:52:03.000Z","updated":"2012-01-01T18:52:11.747Z","childLink":{"type":"analytics#webproperties","href":"https://www.googleapis.com/analytics/v3/management/accounts/1234/webproperties"}}]}
@@ -0,0 +1 @@
1
+ {"kind":"analytics#profiles","username":"someone@somewhere.com","totalResults":1,"startIndex":1,"itemsPerPage":1000,"nextLink":"https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles?start-index=1001&max-results=1000","items":[{"id":"2","kind":"analytics#profile","selfLink":"https://www.googleapis.com/analytics/v3/management/accounts/1234/webproperties/UA-5555-1/profiles/2","accountId":"1234","webPropertyId":"UA-5555-1","internalWebPropertyId":"7777","name":"the profile name","currency":"USD","timezone":"America/Los_Angeles","defaultPage":"index.html","siteSearchQueryParameters":"q,term","created":"2012-01-01T18:04:04.000Z","updated":"2012-01-01T18:55:51.046Z","parentLink":{"type":"analytics#webproperty","href":"https://www.googleapis.com/analytics/v3/management/accounts/1234/webproperties/UA-5555-1"},"childLink":{"type":"analytics#goals","href":"https://www.googleapis.com/analytics/v3/management/accounts/1234/webproperties/UA-5555-1/profiles/2/goals"}}]}
@@ -0,0 +1 @@
1
+ {"kind":"analytics#segments","username":"someone@somewhere.com","totalResults":1,"startIndex":1,"itemsPerPage":1000,"items":[{"id":"1","kind":"analytics#segment","selfLink":"https://www.googleapis.com/analytics/v3/management/segments/gaid::1","segmentId":"gaid::1","name":"derpy","definition":"ga:pagePath=@derpy","created":"2012-01-01T15:07:11.815Z","updated":"2012-01-01T15:07:11.815Z"}]}
@@ -0,0 +1 @@
1
+ {"kind":"analytics#webproperties","username":"someone@somewhere.com","totalResults":1,"startIndex":1,"itemsPerPage":1000,"items":[{"id":"UA-7777-1","kind":"analytics#webproperty","selfLink":"https://www.googleapis.com/analytics/v3/management/accounts/1/webproperties/UA-7777-1","accountId":"1","internalWebPropertyId":"7777","name":"google","websiteUrl":"http://www.google.com","created":"2012-01-01T17:52:03.000Z","updated":"2012-01-01T16:05:57.532Z","parentLink":{"type":"analytics#account","href":"https://www.googleapis.com/analytics/v3/management/accounts/1"},"childLink":{"type":"analytics#profiles","href":"https://www.googleapis.com/analytics/v3/management/accounts/1/webproperties/UA-7777-1/profiles"}}]}
@@ -0,0 +1 @@
1
+ {"kind":"analytics#goals","username":"someone@somewhere.com","totalResults":1,"startIndex":1,"itemsPerPage":1000,"nextLink":"https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles/~all/goals?start-index=1001&max-results=1000","items":[{"id":"1","kind":"analytics#goal","selfLink":"https://www.googleapis.com/analytics/v3/management/accounts/1234/webproperties/UA-55555-1/profiles/1234/goals/1","accountId":"1234","webPropertyId":"UA-5555-1","internalWebPropertyId":"7777","profileId":"1234","name":"the goal","value":1.0,"active":true,"type":"URL_DESTINATION","created":"2012-01-01T17:32:10.000Z","updated":"2012-01-01T15:54:41.781Z","parentLink":{"type":"analytics#profile","href":"https://www.googleapis.com/analytics/v3/management/accounts/1234/webproperties/UA-5555-1/profiles/1234"},"urlDestinationDetails":{"url":"^/somewhere/results","caseSensitive":false,"matchType":"REGEX","firstStepRequired":false,"steps":[{"number":1,"name":"Intro Page","url":"^/somewhere/index"},{"number":2,"name":"Select A Thing","url":"^/somewhere/select_a_thing"},{"number":3,"name":"Results","url":"^/somewhere/results"}]}}]}
@@ -0,0 +1 @@
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"}}
@@ -0,0 +1,75 @@
1
+ {
2
+ "kind":"analytics#gaData",
3
+ "id":"https://www.googleapis.com/analytics/v3/data/ga?ids=ga:123456&dimensions=ga:country,ga:city&metrics=ga:pageViews&start-date=2011-12-01&end-date=2011-12-31&start-index=1&max-results=5",
4
+ "query":{
5
+ "start-date":"2011-12-01",
6
+ "end-date":"2011-12-31",
7
+ "ids":"ga:123456",
8
+ "dimensions":"ga:country,ga:city",
9
+ "metrics":[
10
+ "ga:pageViews"
11
+ ],
12
+ "start-index":1,
13
+ "max-results":5
14
+ },
15
+ "itemsPerPage":5,
16
+ "totalResults":1261,
17
+ "selfLink":"https://www.googleapis.com/analytics/v3/data/ga?ids=ga:123456&dimensions=ga:country,ga:city&metrics=ga:pageViews&start-date=2011-12-01&end-date=2011-12-31&start-index=1&max-results=5",
18
+ "nextLink":"https://www.googleapis.com/analytics/v3/data/ga?ids=ga:123456&dimensions=ga:country,ga:city&metrics=ga:pageViews&start-date=2011-12-01&end-date=2011-12-31&start-index=6&max-results=5",
19
+ "profileInfo":{
20
+ "profileId":"123456",
21
+ "accountId":"123456",
22
+ "webPropertyId":"UA-123456-1",
23
+ "internalWebPropertyId":"123456",
24
+ "profileName":"example.com",
25
+ "tableId":"ga:123456"
26
+ },
27
+ "containsSampledData":true,
28
+ "columnHeaders":[
29
+ {
30
+ "name":"ga:country",
31
+ "columnType":"DIMENSION",
32
+ "dataType":"STRING"
33
+ },
34
+ {
35
+ "name":"ga:city",
36
+ "columnType":"DIMENSION",
37
+ "dataType":"STRING"
38
+ },
39
+ {
40
+ "name":"ga:pageviews",
41
+ "columnType":"METRIC",
42
+ "dataType":"INTEGER"
43
+ }
44
+ ],
45
+ "totalsForAllResults":{
46
+ "ga:pageviews":"38817"
47
+ },
48
+ "rows":[
49
+ [
50
+ "(not set)",
51
+ "(not set)",
52
+ "4"
53
+ ],
54
+ [
55
+ "Australia",
56
+ "Adelaide",
57
+ "4"
58
+ ],
59
+ [
60
+ "Australia",
61
+ "Brisbane",
62
+ "17"
63
+ ],
64
+ [
65
+ "Australia",
66
+ "Geelong",
67
+ "1"
68
+ ],
69
+ [
70
+ "Australia",
71
+ "Melbourne",
72
+ "5"
73
+ ]
74
+ ]
75
+ }
@@ -10,35 +10,31 @@ begin
10
10
 
11
11
  SimpleCov.start 'garb'
12
12
  rescue LoadError
13
- puts "Install simplecov if you use 1.9 and want coverage metrics"
13
+ puts 'Install simplecov if you use 1.9 and want coverage metrics'
14
14
  end
15
15
 
16
- $:.reject! { |e| e.include? 'TextMate' }
17
-
18
- require 'rubygems'
19
16
  require 'bundler'
20
17
  Bundler.setup(:default, :test)
21
18
 
22
19
  require 'shoulda'
23
20
  require 'minitest/unit'
21
+ require 'minitest/autorun'
24
22
  require 'mocha'
25
23
 
26
24
  $:.unshift File.expand_path('../../lib', __FILE__)
27
25
  require 'garb'
28
26
 
29
27
  class MiniTest::Unit::TestCase
30
- include Shoulda::InstanceMethods
31
- extend Shoulda::ClassMethods
32
- include Shoulda::Assertions
33
- extend Shoulda::Macros
34
- include Shoulda::Helpers
28
+ include Shoulda::Context::Assertions
29
+ include Shoulda::Context::InstanceMethods
30
+ extend Shoulda::Context::ClassMethods
35
31
 
36
32
  def read_fixture(filename)
37
33
  File.read(File.dirname(__FILE__) + "/fixtures/#{filename}")
38
34
  end
39
35
 
40
36
  def assert_data_params(expected)
41
- assert_received(Garb::DataRequest, :new) {|e| e.with(Garb::Session, Garb::Model::URL, expected)}
37
+ assert_received(Garb::Request::Data, :new) {|e| e.with(Garb::Session, Garb::Model::URL, expected)}
42
38
  end
43
39
  end
44
40
 
@@ -2,65 +2,34 @@ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class FilterParametersTest < MiniTest::Unit::TestCase
5
- def self.should_define_operators(*operators)
6
- operators.each do |operator|
7
- should "create an operator and add to parameters for the #{operator} method" do
8
- new_operator = stub
9
- symbol = :foo
10
-
11
- SymbolOperator.expects(:new).with(:bar, operator).returns(new_operator)
12
- @filter_parameters.filters do
13
- send(operator.to_sym, :bar, 100)
14
- end
15
-
16
- parameter = {new_operator => 100}
17
- assert_equal parameter, @filter_parameters.parameters.last
18
- end
19
- end
20
- end
21
-
22
5
  context "A FilterParameters" do
23
- setup do
24
- @filter_parameters = FilterParameters.new
25
- end
26
-
27
- should_define_operators :eql, :not_eql, :gt, :gte, :lt, :lte,
28
- :matches, :does_not_match, :contains, :does_not_contain, :substring, :not_substring
29
-
30
- should "instance eval for filters" do
31
- blk = lambda {"in a block"}
32
-
33
- @filter_parameters.expects(:instance_eval)
34
- @filter_parameters.filters(&blk)
35
- end
36
-
37
6
  context "when converting parameters hash into query string parameters" do
38
7
  should "parameterize hash operators and join elements with AND" do
39
- @filter_parameters.filters do
40
- eql(:city, 'New York City')
41
- eql(:state, 'New York')
42
- end
8
+ filters = FilterParameters.new({:city.eql => 'New York City', :state.eql => 'New York'})
43
9
 
44
10
  params = ['ga:city%3D%3DNew+York+City', 'ga:state%3D%3DNew+York']
45
- assert_equal params, @filter_parameters.to_params['filters'].split('%3B').sort
11
+ assert_equal params, filters.to_params['filters'].split('%3B').sort
46
12
  end
47
13
 
48
14
  should "properly encode operators" do
49
- @filter_parameters.filters do
50
- contains(:page_path, 'New York')
51
- end
15
+ filters = FilterParameters.new({:page_path.contains => 'New York'})
52
16
 
53
17
  params = {'filters' => 'ga:pagePath%3D~New+York'}
54
- assert_equal params, @filter_parameters.to_params
18
+ assert_equal params, filters.to_params
19
+ end
20
+
21
+ should "escape comma, semicolon in values" do
22
+ filters = FilterParameters.new({:url.eql => 'this;that,thing\other'})
23
+
24
+ params = {'filters' => 'ga:url%3D%3Dthis%5C%3Bthat%5C%2Cthing%5Cother'}
25
+ assert_equal params, filters.to_params
55
26
  end
56
27
 
57
- should "escape comma, semicolon, and backslash in values" do
58
- @filter_parameters.filters do
59
- eql(:url, 'this;that,thing\other')
60
- end
28
+ should "handle nested arrays mixed with hashes" do
29
+ filters = FilterParameters.new([{:page_path.contains => 'NYC'}, [{:city.eql => 'New York City'}, {:state.eql => 'New York'}]])
61
30
 
62
- params = {'filters' => 'ga:url%3D%3Dthis%5C%3Bthat%5C%2Cthing%5C%5Cother'}
63
- assert_equal params, @filter_parameters.to_params
31
+ params = ['ga:pagePath%3D~NYC,ga:city%3D%3DNew+York+City,ga:state%3D%3DNew+York']
32
+ assert_equal params, filters.to_params['filters'].split('%3B').sort
64
33
  end
65
34
  end
66
35
  end
@@ -8,39 +8,31 @@ module Garb
8
8
  feed = stub(:entries => ["entry1"])
9
9
  Feed.stubs(:new).returns(feed)
10
10
 
11
- Account.stubs(:new_from_entry)
11
+ Account.stubs(:new)
12
12
  Account.all
13
13
 
14
14
  assert_received(Feed, :new) {|e| e.with(Session, '/accounts')}
15
15
  assert_received(feed, :entries)
16
- assert_received(Account, :new_from_entry) {|e| e.with("entry1", Session)}
16
+ assert_received(Account, :new) {|e| e.with("entry1", Session)}
17
17
  end
18
18
  end
19
19
 
20
20
  context "an Account" do
21
21
  setup do
22
- entry = {
23
- "title" => "Google Analytics Account Garb",
24
- "link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/123456"}],
25
- "dxp:property" => [
26
- {"name" => "ga:accountId", "value" => "123456"},
27
- {"name" => "ga:accountName", "value" => "Garb"}
28
- ]
29
- }
30
- @account = Account.new_from_entry(entry, Session)
22
+ entry = MultiJson.load(read_fixture("account_management.json"))['items'].first
23
+ @account = Account.new(entry, Session)
31
24
  end
32
25
 
33
- should "extract id and title from GA entry" do
34
- assert_equal "Garb", @account.title
35
- assert_equal "123456", @account.id
26
+ should "extract id from GA entry" do
27
+ assert_equal "1234", @account.id
36
28
  end
37
29
 
38
30
  should "extract a name from GA entry properties" do
39
- assert_equal "Garb", @account.name
31
+ assert_equal "www.google.com", @account.name
40
32
  end
41
33
 
42
34
  should "combine the Account.path and the id into an new path" do
43
- assert_equal "/accounts/123456", @account.path
35
+ assert_equal "/accounts/1234", @account.path
44
36
  end
45
37
 
46
38
  should "have a reference to the session it was created with" do
@@ -6,28 +6,23 @@ module Garb
6
6
  context "a Feed" do
7
7
  setup do
8
8
  @request = stub
9
- DataRequest.stubs(:new).returns(@request)
9
+ Request::Data.stubs(:new).returns(@request)
10
10
  @feed = Feed.new(Garb::Session.new, '/accounts')
11
11
  end
12
12
 
13
13
  should "have a parsed response" do
14
- Crack::XML.stubs(:parse)
14
+ MultiJson.stubs(:load)
15
15
  @feed.stubs(:response).returns(stub(:body => 'response body'))
16
16
  @feed.parsed_response
17
17
 
18
- assert_received(Crack::XML, :parse) {|e| e.with('response body')}
18
+ assert_received(MultiJson, :load) {|e| e.with('response body')}
19
19
  end
20
20
 
21
21
  should "have entries from the parsed response" do
22
- @feed.stubs(:parsed_response).returns({'feed' => {'entry' => ['entry1', 'entry2']}})
22
+ @feed.stubs(:parsed_response).returns({'items' => ['entry1', 'entry2']})
23
23
  assert_equal ['entry1', 'entry2'], @feed.entries
24
24
  end
25
25
 
26
- should "handle case of a single entry" do
27
- @feed.stubs(:parsed_response).returns({'feed' => {'entry' => {'profile_id' => '12345'}}})
28
- assert_equal [{'profile_id' => '12345'}], @feed.entries
29
- end
30
-
31
26
  should "have an empty array for entries without a response" do
32
27
  @feed.stubs(:parsed_response).returns(nil)
33
28
  assert_equal [], @feed.entries
@@ -41,4 +36,4 @@ module Garb
41
36
  end
42
37
  end
43
38
  end
44
- end
39
+ end
@@ -8,12 +8,12 @@ module Garb
8
8
  feed = stub(:entries => ["entry1"])
9
9
  Feed.stubs(:new).returns(feed)
10
10
 
11
- Goal.stubs(:new_from_entry)
11
+ Goal.stubs(:new)
12
12
  Goal.all
13
13
 
14
14
  assert_received(Feed, :new) {|e| e.with(Session, '/accounts/~all/webproperties/~all/profiles/~all/goals')}
15
15
  assert_received(feed, :entries)
16
- assert_received(Goal, :new_from_entry) {|e| e.with("entry1", Session)}
16
+ assert_received(Goal, :new) {|e| e.with("entry1", Session)}
17
17
  end
18
18
 
19
19
  should "find all goals for a given account" do
@@ -37,30 +37,16 @@ module Garb
37
37
 
38
38
  context "a Goal" do
39
39
  setup do
40
- entry = {
41
- "link" => [{"rel" => "self", "href" => Feed::BASE_URL+"/accounts/1189765/webproperties/UA-1189765-1/profiles/98765"}],
42
- "ga:goal" => {
43
- "ga:destination"=>{"caseSensitive"=>"false","expression"=>"/blog.html","matchType"=>"head"},
44
- "active"=>"true",
45
- "name"=>"Read Blog",
46
- "number"=>"1",
47
- "value"=>"10.0"
48
- }
49
- }
50
-
51
- @goal = Goal.new_from_entry(entry, Session)
40
+ entry = MultiJson.load(read_fixture("goal_management.json"))["items"].first
41
+ @goal = Goal.new(entry, Session)
52
42
  end
53
43
 
54
44
  should "have a name" do
55
- assert_equal "Read Blog", @goal.name
56
- end
57
-
58
- should "have a number" do
59
- assert_equal 1, @goal.number
45
+ assert_equal "the goal", @goal.name
60
46
  end
61
47
 
62
48
  should "have a value" do
63
- assert_equal 10.0, @goal.value
49
+ assert_equal 1.0, @goal.value
64
50
  end
65
51
 
66
52
  should "know if it is active" do
@@ -68,7 +54,7 @@ module Garb
68
54
  end
69
55
 
70
56
  should "know if it is not active" do
71
- @goal.active = false
57
+ @goal.instance_variable_set("@active", false)
72
58
  assert_equal false, @goal.active?
73
59
  end
74
60