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,22 +0,0 @@
1
- module Garb
2
- class Account
3
- attr_reader :id, :name, :profiles
4
-
5
- def initialize(profiles)
6
- @id = profiles.first.account_id
7
- @name = profiles.first.account_name
8
- @profiles = profiles
9
- end
10
-
11
- def self.all(session = Session)
12
- ActiveSupport::Deprecation.warn("The use of Garb::Account has been deprecated in favor of 'Garb::Management::Account'")
13
- profiles = {}
14
-
15
- Profile.all(session).each do |profile|
16
- (profiles[profile.account_id] ||= []) << profile
17
- end
18
-
19
- profiles.map {|k,v| v}.map {|profiles| new(profiles)}
20
- end
21
- end
22
- end
@@ -1,25 +0,0 @@
1
- module Garb
2
- class AccountFeedRequest
3
- URL = "https://www.google.com/analytics/feeds/accounts/default"
4
-
5
- def initialize(session = Session)
6
- @request = DataRequest.new(session, URL)
7
- end
8
-
9
- def response
10
- @response ||= @request.send_request
11
- end
12
-
13
- def parsed_response
14
- @parsed_response ||= Crack::XML.parse(response.body)
15
- end
16
-
17
- def entries
18
- parsed_response ? Array(parsed_response['feed']['entry']).flatten.compact : []
19
- end
20
-
21
- def segments
22
- parsed_response ? Array(parsed_response['feed']['dxp:segment']).flatten.compact : []
23
- end
24
- end
25
- end
@@ -1,53 +0,0 @@
1
- module Garb
2
- class AuthenticationRequest
3
- class AuthError < StandardError;end
4
-
5
- URL = 'https://www.google.com/accounts/ClientLogin'
6
-
7
- def initialize(email, password, opts={})
8
- @email = email
9
- @password = password
10
- @account_type = opts.fetch(:account_type, 'HOSTED_OR_GOOGLE')
11
- end
12
-
13
- def parameters
14
- {
15
- 'Email' => @email,
16
- 'Passwd' => @password,
17
- 'accountType' => @account_type,
18
- 'service' => 'analytics',
19
- 'source' => 'vigetLabs-garb-001'
20
- }
21
- end
22
-
23
- def uri
24
- URI.parse(URL)
25
- end
26
-
27
- def send_request(ssl_mode)
28
- http = Net::HTTP.new(uri.host, uri.port)
29
- http.use_ssl = true
30
- http.verify_mode = ssl_mode
31
-
32
- if ssl_mode == OpenSSL::SSL::VERIFY_PEER
33
- http.ca_file = CA_CERT_FILE
34
- end
35
-
36
- http.request(build_request) do |response|
37
- raise AuthError unless response.is_a?(Net::HTTPOK)
38
- end
39
- end
40
-
41
- def build_request
42
- post = Net::HTTP::Post.new(uri.path)
43
- post.set_form_data(parameters)
44
- post
45
- end
46
-
47
- def auth_token(opts={})
48
- ssl_mode = opts[:secure] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
49
- send_request(ssl_mode).body.match(/^Auth=(.*)$/)[1]
50
- end
51
-
52
- end
53
- end
@@ -1,42 +0,0 @@
1
- module Garb
2
- class DataRequest
3
- class ClientError < StandardError; end
4
-
5
- def initialize(session, base_url, parameters={})
6
- @session = session
7
- @base_url = base_url
8
- @parameters = parameters
9
- end
10
-
11
- def query_string
12
- parameter_list = @parameters.map {|k,v| "#{k}=#{v}" }
13
- parameter_list.empty? ? '' : "?#{parameter_list.join('&')}"
14
- end
15
-
16
- def uri
17
- URI.parse(@base_url)
18
- end
19
-
20
- def send_request
21
- response = if @session.single_user?
22
- single_user_request
23
- elsif @session.oauth_user?
24
- oauth_user_request
25
- end
26
-
27
- raise ClientError, response.body.inspect unless response.kind_of?(Net::HTTPSuccess)
28
- response
29
- end
30
-
31
- def single_user_request
32
- http = Net::HTTP.new(uri.host, uri.port)
33
- http.use_ssl = true
34
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
35
- http.get("#{uri.path}#{query_string}", {'Authorization' => "GoogleLogin auth=#{@session.auth_token}", 'GData-Version' => '2'})
36
- end
37
-
38
- def oauth_user_request
39
- @session.access_token.get("#{uri}#{query_string}", {'GData-Version' => '2'})
40
- end
41
- end
42
- end
@@ -1,20 +0,0 @@
1
- module Garb
2
- class Goal
3
- attr_reader :name, :number, :value, :destination
4
-
5
- def initialize(attributes={})
6
- return unless attributes.is_a?(Hash)
7
-
8
- @name = attributes['name']
9
- @number = attributes['number'].to_i
10
- @value = attributes['value'].to_f
11
- @active = (attributes['active'] == 'true')
12
-
13
- @destination = Destination.new(attributes[Garb.to_ga('destination')])
14
- end
15
-
16
- def active?
17
- @active
18
- end
19
- end
20
- end
@@ -1,33 +0,0 @@
1
- module Garb
2
- class Profile
3
-
4
- include ProfileReports
5
-
6
- attr_reader :session, :table_id, :title, :account_name, :account_id, :web_property_id, :goals
7
-
8
- def initialize(entry, session)
9
- @session = session
10
- @title = entry['title']
11
- @table_id = entry['dxp:tableId']
12
- @goals = (entry[Garb.to_ga('goal')] || []).map {|g| Goal.new(g)}
13
-
14
- Garb.parse_properties(entry).each do |k,v|
15
- instance_variable_set :"@#{k}", v
16
- end
17
- end
18
-
19
- def id
20
- Garb.from_ga(@table_id)
21
- end
22
-
23
- def self.all(session = Session)
24
- ActiveSupport::Deprecation.warn("Garb::Profile.all is deprecated in favor of Garb::Management::Profile.all")
25
- AccountFeedRequest.new(session).entries.map {|entry| new(entry, session)}
26
- end
27
-
28
- def self.first(id, session = Session)
29
- ActiveSupport::Deprecation.warn("Garb::Profile.first is deprecated in favor of Garb::Management::WebProperty")
30
- all(session).detect {|profile| profile.id == id || profile.web_property_id == id }
31
- end
32
- end
33
- end
@@ -1,28 +0,0 @@
1
- module Garb
2
- class Report
3
- include Resource
4
-
5
- MONTH = 2592000
6
- URL = "https://www.google.com/analytics/feeds/data"
7
-
8
- def initialize(profile, opts={})
9
- ActiveSupport::Deprecation.warn("The use of Report will be removed in favor of 'extend Garb::Model'")
10
-
11
- @profile = profile
12
-
13
- @start_date = opts.fetch(:start_date, Time.now - MONTH)
14
- @end_date = opts.fetch(:end_date, Time.now)
15
- @limit = opts.fetch(:limit, nil)
16
- @offset = opts.fetch(:offset, nil)
17
-
18
- metrics opts.fetch(:metrics, [])
19
- dimensions opts.fetch(:dimensions, [])
20
- sort opts.fetch(:sort, [])
21
- end
22
-
23
- def results
24
- ReportResponse.new(send_request_for_body).results
25
- end
26
-
27
- end
28
- end
@@ -1,115 +0,0 @@
1
- module Garb
2
- module Resource
3
- MONTH = 2592000
4
- URL = "https://www.google.com/analytics/feeds/data"
5
-
6
- def self.extended(base)
7
- # define a method on a module that gets included into profile
8
- # Exits would make:
9
- # to enable profile.exits(options_hash, &block)
10
- # returns Exits.results(self, options_hash, &block)
11
- # every class defined which extends Resource will add to the module
12
-
13
- ActiveSupport::Deprecation.warn("The use of Garb::Resource will be removed in favor of 'extend Garb::Model'")
14
- ProfileReports.add_report_method(base)
15
- end
16
-
17
- %w(metrics dimensions sort).each do |parameter|
18
- class_eval <<-CODE
19
- def #{parameter}(*fields)
20
- @#{parameter} ||= ReportParameter.new(:#{parameter})
21
- @#{parameter} << fields
22
- end
23
-
24
- def clear_#{parameter}
25
- @#{parameter} = ReportParameter.new(:#{parameter})
26
- end
27
- CODE
28
- end
29
-
30
- def filters(*hashes, &block)
31
- @filter_parameters ||= FilterParameters.new
32
-
33
- hashes.each do |hash|
34
- @filter_parameters.parameters << hash
35
- end
36
-
37
- @filter_parameters.filters(&block) if block_given?
38
- @filter_parameters
39
- end
40
-
41
- def clear_filters
42
- @filter_parameters = FilterParameters.new
43
- end
44
-
45
- def set_segment_id(id)
46
- @segment = "gaid::#{id.to_i}"
47
- end
48
-
49
- def segment
50
- @segment
51
- end
52
-
53
- def set_instance_klass(klass)
54
- @instance_klass = klass
55
- end
56
-
57
- def instance_klass
58
- @instance_klass || OpenStruct
59
- end
60
-
61
- def results(profile, opts = {}, &block)
62
- @profile = profile.is_a?(Profile) ? profile : Profile.first(profile, opts.fetch(:session, Session))
63
-
64
- if @profile
65
- @start_date = opts.fetch(:start_date, Time.now - MONTH)
66
- @end_date = opts.fetch(:end_date, Time.now)
67
- @limit = opts.fetch(:limit, nil)
68
- @offset = opts.fetch(:offset, nil)
69
-
70
- instance_eval(&block) if block_given?
71
-
72
- ReportResponse.new(send_request_for_body, instance_klass).results
73
- else
74
- []
75
- end
76
- end
77
-
78
- def page_params
79
- {'max-results' => @limit, 'start-index' => @offset}.reject{|k,v| v.nil?}
80
- end
81
-
82
- def default_params
83
- {'ids' => @profile.table_id,
84
- 'start-date' => format_time(@start_date),
85
- 'end-date' => format_time(@end_date)}
86
- end
87
-
88
- def segment_params
89
- segment.nil? ? {} : {'segment' => segment}
90
- end
91
-
92
- def params
93
- [
94
- metrics.to_params,
95
- dimensions.to_params,
96
- sort.to_params,
97
- filters.to_params,
98
- page_params,
99
- segment_params
100
- ].inject(default_params) do |p, i|
101
- p.merge(i)
102
- end
103
- end
104
-
105
- def format_time(t)
106
- t.strftime('%Y-%m-%d')
107
- end
108
-
109
- def send_request_for_body
110
- request = DataRequest.new(@profile.session, URL, params)
111
- response = request.send_request
112
- response.body
113
- end
114
- end
115
- end
@@ -1,40 +0,0 @@
1
- class SymbolOperator
2
- def initialize(field, operator)
3
- @field, @operator = field, operator
4
- end unless method_defined?(:initialize)
5
-
6
- def to_google_analytics
7
- operators = {
8
- :eql => '==',
9
- :not_eql => '!=',
10
- :gt => '>',
11
- :gte => '>=',
12
- :lt => '<',
13
- :lte => '<=',
14
- :matches => '==',
15
- :does_not_match => '!=',
16
- :contains => '=~',
17
- :does_not_contain => '!~',
18
- :substring => '=@',
19
- :not_substring => '!@',
20
- :desc => '-',
21
- :descending => '-'
22
- }
23
-
24
- target = Garb.to_google_analytics(@field)
25
- operator = operators[@operator]
26
-
27
- [:desc, :descending].include?(@operator) ? "#{operator}#{target}" : "#{target}#{operator}"
28
- end
29
- end
30
-
31
- class Symbol
32
- [:eql, :not_eql, :gt, :gte, :lt, :lte, :desc, :descending,
33
- :matches, :does_not_match, :contains, :does_not_contain,
34
- :substring, :not_substring].each do |operator|
35
-
36
- define_method(operator) do
37
- SymbolOperator.new(self, operator)
38
- end unless method_defined?(operator)
39
- end
40
- end
@@ -1,42 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Garb
4
- class AccountFeedRequestTest < MiniTest::Unit::TestCase
5
- context "An AccountFeedRequest" do
6
- setup do
7
- @request = stub
8
- DataRequest.stubs(:new).returns(@request)
9
- @feed = AccountFeedRequest.new
10
- end
11
-
12
- should "have a parsed response" do
13
- Crack::XML.stubs(:parse)
14
- @feed.stubs(:response).returns(stub(:body => 'response body'))
15
- @feed.parsed_response
16
-
17
- assert_received(Crack::XML, :parse) {|e| e.with('response body')}
18
- end
19
-
20
- should "have entries from the parsed response" do
21
- @feed.stubs(:parsed_response).returns({'feed' => {'entry' => ['entry1', 'entry2']}})
22
- assert_equal ['entry1', 'entry2'], @feed.entries
23
- end
24
-
25
- should "have segements from the parsed response" do
26
- @feed.stubs(:parsed_response).returns({'feed' => {'dxp:segment' => ['segment1', 'segment2']}})
27
- assert_equal ['segment1', 'segment2'], @feed.segments
28
- end
29
-
30
- should "have an empty array for entries without a response" do
31
- @feed.stubs(:parsed_response).returns(nil)
32
- assert_equal [], @feed.entries
33
- end
34
-
35
- should "have a response from the request" do
36
- @request.stubs(:send_request)
37
- @feed.response
38
- assert_received(@request, :send_request)
39
- end
40
- end
41
- end
42
- end
@@ -1,53 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Garb
4
- class AccountTest < MiniTest::Unit::TestCase
5
- context "The Account class" do
6
- should "have an array of accounts with all profiles" do
7
- p1 = stub(:account_id => '1111', :account_name => 'Blog 1')
8
- p2 = stub(:account_id => '1112', :account_name => 'Blog 2')
9
-
10
- Profile.stubs(:all).returns([p1,p2,p1,p2])
11
- Account.stubs(:new).returns('account1', 'account2')
12
-
13
- assert_equal ['account1','account2'], Account.all
14
- assert_received(Profile, :all)
15
- assert_received(Account, :new) {|e| e.with([p1,p1])}
16
- assert_received(Account, :new) {|e| e.with([p2,p2])}
17
- end
18
- end
19
-
20
- context "An instance of the Account class" do
21
- setup do
22
- profile = stub(:account_id => '1111', :account_name => 'Blog 1')
23
- @profiles = [profile,profile]
24
- @account = Account.new(@profiles)
25
- end
26
-
27
- context "all" do
28
- should "use an optional user session" do
29
- session = Session.new
30
- Garb::Profile.expects(:all).with(session).returns(@profiles)
31
-
32
- accounts = Account.all(session)
33
- assert_equal 1, accounts.size
34
- assert_equal @profiles, accounts.first.profiles
35
- end
36
- end
37
-
38
- context "when creating a new account from an array of profiles" do
39
- should "take the account id from the first profile" do
40
- assert_equal @profiles.first.account_id, @account.id
41
- end
42
-
43
- should "take the account name from the first profile" do
44
- assert_equal @profiles.first.account_name, @account.name
45
- end
46
-
47
- should "store the array of profiles" do
48
- assert_equal @profiles, @account.profiles
49
- end
50
- end
51
- end
52
- end
53
- end