garb 0.9.1 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
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