google-ads-common 0.7.3 → 0.8.0
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.
- data/ChangeLog +3 -0
- data/lib/ads_common/api.rb +12 -6
- data/lib/ads_common/auth/oauth2_handler.rb +18 -4
- data/lib/ads_common/build/savon_registry.rb +1 -6
- data/lib/ads_common/build/savon_registry_generator.rb +1 -1
- data/lib/ads_common/config.rb +10 -5
- data/lib/ads_common/credential_handler.rb +24 -32
- data/lib/ads_common/results_extractor.rb +69 -8
- data/lib/ads_common/savon_headers/base_header_handler.rb +12 -8
- data/lib/ads_common/version.rb +1 -1
- data/test/test_credential_handler.rb +44 -4
- data/test/test_results_extractor.rb +55 -0
- metadata +63 -83
data/ChangeLog
CHANGED
data/lib/ads_common/api.rb
CHANGED
@@ -136,7 +136,10 @@ module AdsCommon
|
|
136
136
|
# - auth handler
|
137
137
|
#
|
138
138
|
def get_auth_handler()
|
139
|
-
@auth_handler
|
139
|
+
if @auth_handler.nil?
|
140
|
+
@auth_handler = create_auth_handler()
|
141
|
+
@credential_handler.set_auth_handler(@auth_handler)
|
142
|
+
end
|
140
143
|
return @auth_handler
|
141
144
|
end
|
142
145
|
|
@@ -167,12 +170,13 @@ module AdsCommon
|
|
167
170
|
# - auth_handler: instance of an AdsCommon::Auth::BaseHandler subclass to
|
168
171
|
# handle authentication
|
169
172
|
# - version: intended API version
|
170
|
-
# -
|
173
|
+
# - header_ns: header namespace
|
174
|
+
# - default_ns: default namespace
|
171
175
|
#
|
172
176
|
# Returns:
|
173
|
-
# - a
|
177
|
+
# - a SOAP header handler
|
174
178
|
#
|
175
|
-
def soap_header_handler(auth_handler, version,
|
179
|
+
def soap_header_handler(auth_handler, version, header_ns, default_ns)
|
176
180
|
raise NotImplementedError, 'soap_header_handler not overridden.'
|
177
181
|
end
|
178
182
|
|
@@ -228,8 +232,10 @@ module AdsCommon
|
|
228
232
|
|
229
233
|
wrapper = class_for_path(interface_class_name).new(@config, endpoint)
|
230
234
|
auth_handler = get_auth_handler()
|
231
|
-
|
232
|
-
|
235
|
+
header_ns =
|
236
|
+
api_config.environment_config(environment, :header_ns) + version.to_s
|
237
|
+
soap_handler = soap_header_handler(auth_handler, version, header_ns,
|
238
|
+
wrapper.namespace)
|
233
239
|
wrapper.header_handler = soap_handler
|
234
240
|
|
235
241
|
return wrapper
|
@@ -70,7 +70,8 @@ module AdsCommon
|
|
70
70
|
# Overrides base get_token method to account for the token expiration.
|
71
71
|
def get_token(credentials = nil)
|
72
72
|
refresh_token! if !@token.nil? && @token.expired?
|
73
|
-
|
73
|
+
token = super(credentials)
|
74
|
+
return oauth_token_to_hash(token)
|
74
75
|
end
|
75
76
|
|
76
77
|
# Refreshes access token from refresh token.
|
@@ -92,7 +93,7 @@ module AdsCommon
|
|
92
93
|
#
|
93
94
|
def generate_oauth2_parameters_string(credentials)
|
94
95
|
token = get_token(credentials)
|
95
|
-
return OAUTH2_HEADER % token
|
96
|
+
return OAUTH2_HEADER % token[:access_token]
|
96
97
|
end
|
97
98
|
|
98
99
|
# Auxiliary method to validate the credentials for token generation.
|
@@ -173,8 +174,8 @@ module AdsCommon
|
|
173
174
|
access_token = nil
|
174
175
|
oauth2_token_hash = credentials[:oauth2_token]
|
175
176
|
if !oauth2_token_hash.nil? && oauth2_token_hash.kind_of?(Hash)
|
176
|
-
|
177
|
-
|
177
|
+
token_data = oauth2_token_hash.dup()
|
178
|
+
access_token = OAuth2::AccessToken.from_hash(client, token_data)
|
178
179
|
end
|
179
180
|
return access_token
|
180
181
|
end
|
@@ -214,6 +215,19 @@ module AdsCommon
|
|
214
215
|
end
|
215
216
|
return token
|
216
217
|
end
|
218
|
+
|
219
|
+
# Converts OAuth token object into hash structure.
|
220
|
+
def oauth_token_to_hash(token)
|
221
|
+
return token.nil? ? nil :
|
222
|
+
{
|
223
|
+
:access_token => token.token,
|
224
|
+
:refresh_token => token.refresh_token,
|
225
|
+
:expires_in => token.expires_in,
|
226
|
+
:expires_at => token.expires_at,
|
227
|
+
:params => token.params,
|
228
|
+
:options => token.options
|
229
|
+
}
|
230
|
+
end
|
217
231
|
end
|
218
232
|
end
|
219
233
|
end
|
@@ -69,14 +69,9 @@ module AdsCommon
|
|
69
69
|
simple_types = get_simple_types(schema)
|
70
70
|
(complex_types + simple_types).each do |ctype|
|
71
71
|
ctype_name = get_element_name(ctype)
|
72
|
+
@soap_types << extract_type(ctype, ns_index)
|
72
73
|
if ctype_name.match('.+Exception$')
|
73
74
|
@soap_exceptions << extract_exception(ctype)
|
74
|
-
elsif ctype_name.match('.+Error$')
|
75
|
-
# We don't use it at the moment.
|
76
|
-
elsif ctype_name.match('.+\.Reason$')
|
77
|
-
# We don't use it at the moment.
|
78
|
-
else
|
79
|
-
@soap_types << extract_type(ctype, ns_index)
|
80
75
|
end
|
81
76
|
end
|
82
77
|
end
|
data/lib/ads_common/config.rb
CHANGED
@@ -79,12 +79,17 @@ module AdsCommon
|
|
79
79
|
# - <b>Errno::ENOENT</b> if the file does not exist.
|
80
80
|
#
|
81
81
|
def load(filename)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
begin
|
83
|
+
new_config = YAML::load_file(filename)
|
84
|
+
if new_config.kind_of?(Hash)
|
85
|
+
@config = new_config
|
86
|
+
else
|
87
|
+
raise AdsCommon::Errors::Error,
|
88
|
+
"Incorrect configuration file: %s" % filename
|
89
|
+
end
|
90
|
+
rescue TypeError => e
|
86
91
|
raise AdsCommon::Errors::Error,
|
87
|
-
"
|
92
|
+
"Error parsing configuration file: %s" % filename
|
88
93
|
end
|
89
94
|
return nil
|
90
95
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Encoding: utf-8
|
2
2
|
#
|
3
|
-
# Authors:: api.
|
3
|
+
# Authors:: api.dklimkin@gmail.com (Danial Klimkin)
|
4
4
|
#
|
5
5
|
# Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
|
6
6
|
#
|
@@ -27,6 +27,7 @@ module AdsCommon
|
|
27
27
|
# Initializes CredentialHandler.
|
28
28
|
def initialize(config)
|
29
29
|
@config = config
|
30
|
+
@auth_handler = nil
|
30
31
|
load_from_config(config)
|
31
32
|
end
|
32
33
|
|
@@ -39,61 +40,52 @@ module AdsCommon
|
|
39
40
|
|
40
41
|
# Set the credentials hash to a new one. Calculate difference, and call the
|
41
42
|
# AuthHandler callback appropriately.
|
42
|
-
# TODO(dklimkin): re-write this with inject.
|
43
43
|
def credentials=(new_credentials)
|
44
44
|
# Find new and changed properties.
|
45
|
-
diff = new_credentials.
|
46
|
-
value != @credentials[key]
|
45
|
+
diff = new_credentials.inject([]) do |result, (key, value)|
|
46
|
+
result << [key, value] if value != @credentials[key]
|
47
|
+
result
|
47
48
|
end
|
48
49
|
|
49
50
|
# Find removed properties.
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if removed
|
54
|
-
removed = removed.map { |entry| [entry[0], nil] }
|
55
|
-
diff += removed
|
51
|
+
diff = @credentials.inject(diff) do |result, (key, value)|
|
52
|
+
result << [key, nil] unless new_credentials.include?(key)
|
53
|
+
result
|
56
54
|
end
|
57
55
|
|
58
56
|
# Set each property.
|
59
|
-
diff.each
|
60
|
-
|
61
|
-
|
57
|
+
diff.each { |entry| set_credential(entry[0], entry[1]) }
|
58
|
+
|
59
|
+
return nil
|
62
60
|
end
|
63
61
|
|
64
62
|
# Set a single credential to a new value. Call the AuthHandler callback
|
65
63
|
# appropriately.
|
66
64
|
def set_credential(credential, value)
|
67
65
|
@credentials[credential] = value
|
68
|
-
# TODO(dklimkin): @auth_handler is never defined.
|
69
66
|
@auth_handler.property_changed(credential, value) if @auth_handler
|
70
67
|
end
|
71
68
|
|
72
|
-
# Generates string for UserAgent to put into
|
73
|
-
def
|
74
|
-
return generate_user_agent(extra_ids, agent_app)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Generates string for UserAgent to put into SOAP headers.
|
78
|
-
def generate_soap_user_agent(extra_ids = [], agent_app = nil)
|
79
|
-
return generate_user_agent(extra_ids, agent_app)
|
80
|
-
end
|
81
|
-
|
82
|
-
private
|
83
|
-
|
84
|
-
# Generates user-agent.
|
85
|
-
def generate_user_agent(extra_ids, agent_app)
|
69
|
+
# Generates string for UserAgent to put into headers.
|
70
|
+
def generate_user_agent(extra_ids = [], agent_app = nil)
|
86
71
|
agent_app ||= $0
|
87
72
|
agent_data = extra_ids
|
88
|
-
agent_data <<
|
89
|
-
agent_data <<
|
73
|
+
agent_data << 'Common-Ruby/%s' % AdsCommon::ApiConfig::CLIENT_LIB_VERSION
|
74
|
+
agent_data << 'Savon/%s' % Savon::VERSION
|
90
75
|
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
91
76
|
agent_data << [ruby_engine, RUBY_VERSION].join('/')
|
92
|
-
agent_data <<
|
77
|
+
agent_data << 'HTTPI/%s' % HTTPI::VERSION
|
93
78
|
agent_data << HTTPI::Adapter.use.to_s
|
94
|
-
return
|
79
|
+
return '%s (%s)' % [agent_app, agent_data.join(', ')]
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sets authorization handler to notify about credential changes.
|
83
|
+
def set_auth_handler(auth_handler)
|
84
|
+
@auth_handler = auth_handler
|
95
85
|
end
|
96
86
|
|
87
|
+
private
|
88
|
+
|
97
89
|
# Loads the credentials from the config data.
|
98
90
|
def load_from_config(config)
|
99
91
|
@credentials = config.read('authentication')
|
@@ -40,7 +40,6 @@ module AdsCommon
|
|
40
40
|
result = result[action] if result.include?(action)
|
41
41
|
result = normalize_output(result, method)
|
42
42
|
return result[:rval] || result
|
43
|
-
return result
|
44
43
|
end
|
45
44
|
|
46
45
|
# Extracts misc data from response header.
|
@@ -52,6 +51,14 @@ module AdsCommon
|
|
52
51
|
return headers
|
53
52
|
end
|
54
53
|
|
54
|
+
# Extracts misc data from SOAP fault.
|
55
|
+
def extract_exception_data(soap_fault, exception_name)
|
56
|
+
exception_type = get_full_type_signature(exception_name)
|
57
|
+
process_attributes(soap_fault, false)
|
58
|
+
soap_fault = normalize_fields(soap_fault, exception_type[:fields])
|
59
|
+
return soap_fault
|
60
|
+
end
|
61
|
+
|
55
62
|
private
|
56
63
|
|
57
64
|
# Normalizes output starting with root output node.
|
@@ -94,7 +101,17 @@ module AdsCommon
|
|
94
101
|
|
95
102
|
# Normalizes every item of an Array.
|
96
103
|
def normalize_array_field(data, field_def)
|
97
|
-
|
104
|
+
result = data
|
105
|
+
# Convert a specific structure to a handy hash if detected.
|
106
|
+
if check_key_value_struct(result)
|
107
|
+
result = convert_key_value_to_hash(result).inject({}) do |result, (k,v)|
|
108
|
+
result[k] = normalize_output_field(v, field_def)
|
109
|
+
result
|
110
|
+
end
|
111
|
+
else
|
112
|
+
result = data.map {|item| normalize_output_field(item, field_def)}
|
113
|
+
end
|
114
|
+
return result
|
98
115
|
end
|
99
116
|
|
100
117
|
# Normalizes every item of a Hash.
|
@@ -111,6 +128,8 @@ module AdsCommon
|
|
111
128
|
normalize_fields(field, field_def[:fields])
|
112
129
|
end
|
113
130
|
|
131
|
+
result = field
|
132
|
+
|
114
133
|
# Now checking for choice options from wsdl.
|
115
134
|
choice_type_override = determine_choice_type_override(field, field_def)
|
116
135
|
unless choice_type_override.nil?
|
@@ -122,13 +141,54 @@ module AdsCommon
|
|
122
141
|
if !field_def.nil? and field_data.kind_of?(Hash)
|
123
142
|
field_data = normalize_fields(field_data, field_def[:fields])
|
124
143
|
end
|
125
|
-
|
144
|
+
result = {field_key => field_data}
|
145
|
+
else
|
146
|
+
# Otherwise using the best we have.
|
147
|
+
unless field_def.nil?
|
148
|
+
result = normalize_fields(field, field_def[:fields])
|
149
|
+
end
|
126
150
|
end
|
127
151
|
|
128
|
-
#
|
129
|
-
|
152
|
+
# Convert a single key-value hash to a proper hash if detected.
|
153
|
+
if check_key_value_struct(result)
|
154
|
+
result = convert_key_value_to_hash(result)
|
155
|
+
end
|
130
156
|
|
131
|
-
return
|
157
|
+
return result
|
158
|
+
end
|
159
|
+
|
160
|
+
# Checks if all elements of the array or hash passed are hashes and have
|
161
|
+
# ':key' and ':value' keys only.
|
162
|
+
def check_key_value_struct(data)
|
163
|
+
if data.kind_of?(Hash)
|
164
|
+
return check_key_value_hash(data)
|
165
|
+
end
|
166
|
+
if data.kind_of?(Array) && !data.empty?
|
167
|
+
data.each do |item|
|
168
|
+
return false if !check_key_value_hash(item)
|
169
|
+
end
|
170
|
+
return true
|
171
|
+
end
|
172
|
+
return false
|
173
|
+
end
|
174
|
+
|
175
|
+
# Checks if the argument is hash and has exactly ':key' and ':value' keys.
|
176
|
+
def check_key_value_hash(item)
|
177
|
+
return (item.kind_of?(Hash) && item.include?(:key) &&
|
178
|
+
item.include?(:value) && (item.keys.size == 2))
|
179
|
+
end
|
180
|
+
|
181
|
+
# Converts an array containing hashes or a hash with ':key' and ':value'
|
182
|
+
# keys only into a key -> value hash.
|
183
|
+
def convert_key_value_to_hash(data)
|
184
|
+
return case data
|
185
|
+
when Hash then {data[:key] => data[:value]}
|
186
|
+
when Array then
|
187
|
+
data.inject({}) do |result, item|
|
188
|
+
result[item[:key]] = item[:value]
|
189
|
+
result
|
190
|
+
end
|
191
|
+
end
|
132
192
|
end
|
133
193
|
|
134
194
|
# Determines an xsi:type override for for the field. Returns nil if no
|
@@ -183,9 +243,10 @@ module AdsCommon
|
|
183
243
|
# even for a signle item.
|
184
244
|
def check_array_collapse(data, field_def)
|
185
245
|
result = data
|
186
|
-
if !field_def[:min_occurs].nil?
|
246
|
+
if !field_def[:min_occurs].nil? &&
|
187
247
|
(field_def[:max_occurs] == :unbounded ||
|
188
|
-
(!field_def[:max_occurs].nil?
|
248
|
+
(!field_def[:max_occurs].nil? && field_def[:max_occurs] > 1)) &&
|
249
|
+
!(field_def[:type] =~ /MapEntry$/)
|
189
250
|
result = arrayize(result)
|
190
251
|
end
|
191
252
|
return result
|
@@ -34,12 +34,15 @@ module AdsCommon
|
|
34
34
|
# Args:
|
35
35
|
# - credential_handler: a header with credential data
|
36
36
|
# - auth_handler: a header with auth data
|
37
|
+
# - header_ns: namespace to use for headers
|
37
38
|
# - namespace: default namespace to use
|
38
39
|
# - version: services version
|
39
40
|
#
|
40
|
-
def initialize(credential_handler, auth_handler, namespace,
|
41
|
+
def initialize(credential_handler, auth_handler, header_ns, namespace,
|
42
|
+
version)
|
41
43
|
@credential_handler = credential_handler
|
42
44
|
@auth_handler = auth_handler
|
45
|
+
@header_ns = header_ns
|
43
46
|
@namespace = namespace
|
44
47
|
@version = version
|
45
48
|
end
|
@@ -62,7 +65,13 @@ module AdsCommon
|
|
62
65
|
soap.input[2] = {:xmlns => @namespace}
|
63
66
|
# Sets User-Agent in the HTTP header.
|
64
67
|
request.headers['User-Agent'] =
|
65
|
-
@credential_handler.
|
68
|
+
@credential_handler.generate_user_agent()
|
69
|
+
# Set headers namespace.
|
70
|
+
header_name = prepend_namespace(get_header_element_name())
|
71
|
+
soap.header[:attributes!] ||= {}
|
72
|
+
soap.header[:attributes!][header_name] ||= {}
|
73
|
+
soap.header[:attributes!][header_name]['xmlns'] = @header_ns
|
74
|
+
# Generate headers.
|
66
75
|
generate_headers(request, soap)
|
67
76
|
end
|
68
77
|
|
@@ -93,12 +102,7 @@ module AdsCommon
|
|
93
102
|
|
94
103
|
# Generates SOAP default request header with all requested headers.
|
95
104
|
def generate_request_header()
|
96
|
-
|
97
|
-
extra_headers = credentials[:extra_headers]
|
98
|
-
return extra_headers.inject({}) do |result, (header, value)|
|
99
|
-
result[prepend_namespace(header)] = value
|
100
|
-
result
|
101
|
-
end
|
105
|
+
return @credential_handler.credentials[:extra_headers]
|
102
106
|
end
|
103
107
|
end
|
104
108
|
end
|
data/lib/ads_common/version.rb
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
# Tests credential handler methods.
|
22
22
|
|
23
23
|
require 'logger'
|
24
|
-
require '
|
24
|
+
require 'minitest/mock'
|
25
25
|
|
26
26
|
require 'ads_common/config'
|
27
27
|
require 'ads_common/credential_handler'
|
@@ -54,9 +54,49 @@ class TestCredentialHandler < Test::Unit::TestCase
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def test_generate_user_agent_simple()
|
57
|
-
result1 = @handler.
|
57
|
+
result1 = @handler.generate_user_agent()
|
58
58
|
assert_kind_of(String, result1)
|
59
|
-
|
60
|
-
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_generate_user_agent_chained()
|
62
|
+
test_str = 'Tester/0.2.0'
|
63
|
+
result1 = @handler.generate_user_agent([test_str])
|
64
|
+
assert_kind_of(String, result1)
|
65
|
+
assert_match(/#{Regexp.escape(test_str)}/, result1)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_auth_handler_callback_once()
|
69
|
+
mock = MiniTest::Mock.new()
|
70
|
+
mock.expect(:property_changed, nil, [:foo, 'bar'])
|
71
|
+
@handler.set_auth_handler(mock)
|
72
|
+
@handler.set_credential(:foo, 'bar')
|
73
|
+
assert(mock.verify)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_auth_handler_callback_compare()
|
77
|
+
credentials = @handler.credentials
|
78
|
+
|
79
|
+
credentials[:foo] = 'bar'
|
80
|
+
credentials[:baz] = 42
|
81
|
+
mock1 = MiniTest::Mock.new()
|
82
|
+
mock1.expect(:property_changed, nil, [:foo, 'bar'])
|
83
|
+
mock1.expect(:property_changed, nil, [:baz, 42])
|
84
|
+
@handler.set_auth_handler(mock1)
|
85
|
+
@handler.credentials = credentials
|
86
|
+
assert(mock1.verify)
|
87
|
+
|
88
|
+
credentials.delete(:baz)
|
89
|
+
mock2 = MiniTest::Mock.new()
|
90
|
+
mock2.expect(:property_changed, nil, [:baz, nil])
|
91
|
+
@handler.set_auth_handler(mock2)
|
92
|
+
@handler.credentials = credentials
|
93
|
+
assert(mock2.verify)
|
94
|
+
|
95
|
+
credentials[:foo] = nil
|
96
|
+
mock3 = MiniTest::Mock.new()
|
97
|
+
mock3.expect(:property_changed, nil, [:foo, nil])
|
98
|
+
@handler.set_auth_handler(mock3)
|
99
|
+
@handler.credentials = credentials
|
100
|
+
assert(mock3.verify)
|
61
101
|
end
|
62
102
|
end
|
@@ -29,6 +29,9 @@ module AdsCommon
|
|
29
29
|
|
30
30
|
public :check_array_collapse
|
31
31
|
public :normalize_item
|
32
|
+
public :check_key_value_struct
|
33
|
+
public :check_key_value_hash
|
34
|
+
public :convert_key_value_to_hash
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -174,6 +177,18 @@ class TestResultsExtractor < Test::Unit::TestCase
|
|
174
177
|
assert_equal([{}], result7)
|
175
178
|
end
|
176
179
|
|
180
|
+
def test_check_array_collapse_exception()
|
181
|
+
result1 = @extractor.check_array_collapse(
|
182
|
+
42.0, {:min_occurs => '0', :max_occurs => 2, :type => 'FloatMapEntry'})
|
183
|
+
assert_kind_of(Float, result1)
|
184
|
+
assert_equal(42.0, result1)
|
185
|
+
|
186
|
+
result2 = @extractor.check_array_collapse(
|
187
|
+
42.0, {:min_occurs => '0', :max_occurs => 2, :type => 'MapEntryTest'})
|
188
|
+
assert_kind_of(Array, result2)
|
189
|
+
assert_equal(42.0, result2[0])
|
190
|
+
end
|
191
|
+
|
177
192
|
def test_extract_headers_empty()
|
178
193
|
headers = {}
|
179
194
|
response = StubResponse.new()
|
@@ -200,4 +215,44 @@ class TestResultsExtractor < Test::Unit::TestCase
|
|
200
215
|
result = @extractor.extract_header_data(response)
|
201
216
|
assert_equal(expected, result)
|
202
217
|
end
|
218
|
+
|
219
|
+
def test_check_key_value_struct()
|
220
|
+
assert(!@extractor.check_key_value_struct([]))
|
221
|
+
assert(!@extractor.check_key_value_struct({}))
|
222
|
+
|
223
|
+
test1 = [{:key => 'foo', :value => 'bar'}]
|
224
|
+
assert(@extractor.check_key_value_struct(test1))
|
225
|
+
test2 = [{:key => 'foo'}]
|
226
|
+
assert(!@extractor.check_key_value_struct(test2))
|
227
|
+
test3 = [{:key => 'foo', :value => 'bar', :extra => 42}]
|
228
|
+
assert(!@extractor.check_key_value_struct(test3))
|
229
|
+
test4 = [{:key => 'foo', :value => 'bar'}, {:baz => 'bar'}]
|
230
|
+
assert(!@extractor.check_key_value_struct(test4))
|
231
|
+
test5 = [
|
232
|
+
{:key => 'foo', :value => 'bar'},
|
233
|
+
{:key => 'bar', :value => {:bar => 'baz'}}
|
234
|
+
]
|
235
|
+
assert(@extractor.check_key_value_struct(test5))
|
236
|
+
test6 = {:key => 'foo', :value => 'bar'}
|
237
|
+
assert(@extractor.check_key_value_struct(test6))
|
238
|
+
test7 = {:key => 'foo'}
|
239
|
+
assert(!@extractor.check_key_value_struct(test7))
|
240
|
+
test8 = {:value => 'baz', :key => 'foo'}
|
241
|
+
assert(@extractor.check_key_value_struct(test8))
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_convert_key_value_to_hash()
|
245
|
+
result1 = @extractor.convert_key_value_to_hash(
|
246
|
+
[{:key => 'foo', :value => 'bar'}, {:key => 42, :value => 88.2}])
|
247
|
+
assert_kind_of(Hash, result1)
|
248
|
+
assert(result1.include?('foo'))
|
249
|
+
assert(result1.include?(42))
|
250
|
+
assert_equal('bar', result1['foo'])
|
251
|
+
assert_equal(88.2, result1[42])
|
252
|
+
result2 = @extractor.convert_key_value_to_hash(
|
253
|
+
{:key => 'foo', :value => 'bar'})
|
254
|
+
assert_kind_of(Hash, result2)
|
255
|
+
assert_equal(['foo'], result2.keys)
|
256
|
+
assert_equal('bar', result2['foo'])
|
257
|
+
end
|
203
258
|
end
|
metadata
CHANGED
@@ -1,97 +1,88 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: google-ads-common
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 7
|
9
|
-
- 3
|
10
|
-
version: 0.7.3
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Sergio Gomes
|
14
9
|
- Danial Klimkin
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2012-08-17 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
22
16
|
name: savon
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
|
-
requirements:
|
19
|
+
requirements:
|
27
20
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 23
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 0
|
33
|
-
- 0
|
21
|
+
- !ruby/object:Gem::Version
|
34
22
|
version: 1.0.0
|
35
23
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: httpi
|
39
24
|
prerelease: false
|
40
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 1.0.0
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: httpi
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
41
34
|
none: false
|
42
|
-
requirements:
|
35
|
+
requirements:
|
43
36
|
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
hash: 23
|
46
|
-
segments:
|
47
|
-
- 1
|
48
|
-
- 0
|
49
|
-
- 0
|
37
|
+
- !ruby/object:Gem::Version
|
50
38
|
version: 1.0.0
|
51
39
|
type: :runtime
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: oauth
|
55
40
|
prerelease: false
|
56
|
-
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.0.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: oauth
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
57
50
|
none: false
|
58
|
-
requirements:
|
51
|
+
requirements:
|
59
52
|
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
hash: 5
|
62
|
-
segments:
|
63
|
-
- 0
|
64
|
-
- 4
|
65
|
-
- 5
|
53
|
+
- !ruby/object:Gem::Version
|
66
54
|
version: 0.4.5
|
67
55
|
type: :runtime
|
68
|
-
version_requirements: *id003
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: oauth2
|
71
56
|
prerelease: false
|
72
|
-
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.4.5
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: oauth2
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
73
66
|
none: false
|
74
|
-
requirements:
|
67
|
+
requirements:
|
75
68
|
- - ~>
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
hash: 1
|
78
|
-
segments:
|
79
|
-
- 0
|
80
|
-
- 7
|
81
|
-
- 1
|
69
|
+
- !ruby/object:Gem::Version
|
82
70
|
version: 0.7.1
|
83
71
|
type: :runtime
|
84
|
-
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 0.7.1
|
85
79
|
description: Essential utilities shared by all Ads Ruby client libraries
|
86
|
-
email:
|
80
|
+
email:
|
87
81
|
- api.dklimkin@gmail.com
|
88
82
|
executables: []
|
89
|
-
|
90
83
|
extensions: []
|
91
|
-
|
92
84
|
extra_rdoc_files: []
|
93
|
-
|
94
|
-
files:
|
85
|
+
files:
|
95
86
|
- lib/ads_common/api.rb
|
96
87
|
- lib/ads_common/utils.rb
|
97
88
|
- lib/ads_common/version.rb
|
@@ -130,40 +121,29 @@ files:
|
|
130
121
|
- ChangeLog
|
131
122
|
homepage: http://code.google.com/p/google-api-ads-ruby/
|
132
123
|
licenses: []
|
133
|
-
|
134
124
|
post_install_message:
|
135
125
|
rdoc_options: []
|
136
|
-
|
137
|
-
require_paths:
|
126
|
+
require_paths:
|
138
127
|
- lib
|
139
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
129
|
none: false
|
141
|
-
requirements:
|
142
|
-
- -
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
|
145
|
-
|
146
|
-
- 0
|
147
|
-
version: "0"
|
148
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
135
|
none: false
|
150
|
-
requirements:
|
151
|
-
- -
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
hash: 23
|
154
|
-
segments:
|
155
|
-
- 1
|
156
|
-
- 3
|
157
|
-
- 6
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
158
139
|
version: 1.3.6
|
159
140
|
requirements: []
|
160
|
-
|
161
141
|
rubyforge_project: google-ads-common
|
162
142
|
rubygems_version: 1.8.24
|
163
143
|
signing_key:
|
164
144
|
specification_version: 3
|
165
145
|
summary: Common code for Google Ads APIs
|
166
|
-
test_files:
|
146
|
+
test_files:
|
167
147
|
- test/test_savon_service.rb
|
168
148
|
- test/test_results_extractor.rb
|
169
149
|
- test/test_credential_handler.rb
|