google-api-client 0.2.0 → 0.3.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 +10 -0
- data/README.md +69 -0
- data/Rakefile +3 -4
- data/bin/google-api +49 -27
- data/lib/google/api_client.rb +164 -134
- data/lib/google/api_client/discovery.rb +4 -562
- data/lib/google/api_client/discovery/api.rb +272 -0
- data/lib/google/api_client/discovery/method.rb +313 -0
- data/lib/google/api_client/discovery/resource.rb +149 -0
- data/lib/google/api_client/discovery/schema.rb +106 -0
- data/lib/google/api_client/environment.rb +5 -2
- data/lib/google/api_client/errors.rb +10 -0
- data/lib/google/api_client/parser.rb +59 -0
- data/lib/google/api_client/parsers/json/error_parser.rb +34 -0
- data/lib/google/api_client/parsers/json/pagination.rb +40 -0
- data/lib/google/api_client/parsers/json_parser.rb +90 -12
- data/lib/google/api_client/reference.rb +202 -0
- data/lib/google/api_client/result.rb +132 -0
- data/lib/google/api_client/version.rb +10 -7
- data/lib/google/inflection.rb +7 -2
- data/spec/google/api_client/discovery_spec.rb +162 -123
- data/spec/google/api_client/parsers/json_parser_spec.rb +27 -23
- data/spec/google/api_client_spec.rb +3 -29
- data/tasks/gem.rake +26 -9
- data/tasks/rdoc.rake +12 -5
- data/tasks/spec.rake +4 -1
- data/tasks/wiki.rake +41 -0
- data/tasks/yard.rake +1 -1
- metadata +48 -95
- data/README +0 -68
@@ -0,0 +1,202 @@
|
|
1
|
+
# Copyright 2010 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'stringio'
|
16
|
+
require 'json'
|
17
|
+
require 'addressable/uri'
|
18
|
+
require 'google/api_client/discovery'
|
19
|
+
|
20
|
+
module Google
|
21
|
+
class APIClient
|
22
|
+
class Reference
|
23
|
+
def initialize(options={})
|
24
|
+
# We only need this to do lookups on method ID String values
|
25
|
+
# It's optional, but method ID lookups will fail if the client is
|
26
|
+
# omitted.
|
27
|
+
@client = options[:client]
|
28
|
+
@version = options[:version] || 'v1'
|
29
|
+
|
30
|
+
self.api_method = options[:api_method]
|
31
|
+
self.parameters = options[:parameters] || {}
|
32
|
+
# These parameters are handled differently because they're not
|
33
|
+
# parameters to the API method, but rather to the API system.
|
34
|
+
self.parameters['key'] ||= options[:key] if options[:key]
|
35
|
+
self.parameters['userIp'] ||= options[:user_ip] if options[:user_ip]
|
36
|
+
self.headers = options[:headers] || []
|
37
|
+
if options[:body]
|
38
|
+
self.body = options[:body]
|
39
|
+
elsif options[:merged_body]
|
40
|
+
self.merged_body = options[:merged_body]
|
41
|
+
elsif options[:body_object]
|
42
|
+
if options[:body_object].respond_to?(:to_json)
|
43
|
+
serialized_body = options[:body_object].to_json
|
44
|
+
elsif options[:body_object].respond_to?(:to_hash)
|
45
|
+
serialized_body = JSON.generate(options[:body_object].to_hash)
|
46
|
+
else
|
47
|
+
raise TypeError,
|
48
|
+
'Could not convert body object to JSON.' +
|
49
|
+
'Must respond to :to_json or :to_hash.'
|
50
|
+
end
|
51
|
+
self.merged_body = serialized_body
|
52
|
+
else
|
53
|
+
self.merged_body = ''
|
54
|
+
end
|
55
|
+
unless self.api_method
|
56
|
+
self.http_method = options[:http_method] || 'GET'
|
57
|
+
self.uri = options[:uri]
|
58
|
+
unless self.parameters.empty?
|
59
|
+
self.uri.query_values =
|
60
|
+
(self.uri.query_values || {}).merge(self.parameters)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def api_method
|
66
|
+
return @api_method
|
67
|
+
end
|
68
|
+
|
69
|
+
def api_method=(new_api_method)
|
70
|
+
if new_api_method.kind_of?(Google::APIClient::Method) ||
|
71
|
+
new_api_method == nil
|
72
|
+
@api_method = new_api_method
|
73
|
+
elsif new_api_method.respond_to?(:to_str) ||
|
74
|
+
new_api_method.kind_of?(Symbol)
|
75
|
+
unless @client
|
76
|
+
raise ArgumentError,
|
77
|
+
"API method lookup impossible without client instance."
|
78
|
+
end
|
79
|
+
new_api_method = new_api_method.to_s
|
80
|
+
# This method of guessing the API is unreliable. This will fail for
|
81
|
+
# APIs where the first segment of the RPC name does not match the
|
82
|
+
# service name. However, this is a fallback mechanism anyway.
|
83
|
+
# Developers should be passing in a reference to the method, rather
|
84
|
+
# than passing in a string or symbol. This should raise an error
|
85
|
+
# in the case of a mismatch.
|
86
|
+
api = new_api_method[/^([^.]+)\./, 1]
|
87
|
+
@api_method = @client.discovered_method(
|
88
|
+
new_api_method, api, @version
|
89
|
+
)
|
90
|
+
if @api_method
|
91
|
+
# Ditch the client reference, we won't need it again.
|
92
|
+
@client = nil
|
93
|
+
else
|
94
|
+
raise ArgumentError, "API method could not be found."
|
95
|
+
end
|
96
|
+
else
|
97
|
+
raise TypeError,
|
98
|
+
"Expected Google::APIClient::Method, got #{new_api_method.class}."
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def parameters
|
103
|
+
return @parameters
|
104
|
+
end
|
105
|
+
|
106
|
+
def parameters=(new_parameters)
|
107
|
+
# No type-checking needed, the Method class handles this.
|
108
|
+
@parameters = new_parameters
|
109
|
+
end
|
110
|
+
|
111
|
+
def body
|
112
|
+
return @body
|
113
|
+
end
|
114
|
+
|
115
|
+
def body=(new_body)
|
116
|
+
if new_body.respond_to?(:each)
|
117
|
+
@body = new_body
|
118
|
+
else
|
119
|
+
raise TypeError, "Expected body to respond to :each."
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def merged_body
|
124
|
+
return (self.body.inject(StringIO.new) do |accu, chunk|
|
125
|
+
accu.write(chunk)
|
126
|
+
accu
|
127
|
+
end).string
|
128
|
+
end
|
129
|
+
|
130
|
+
def merged_body=(new_merged_body)
|
131
|
+
if new_merged_body.respond_to?(:string)
|
132
|
+
new_merged_body = new_merged_body.string
|
133
|
+
elsif new_merged_body.respond_to?(:to_str)
|
134
|
+
new_merged_body = new_merged_body.to_str
|
135
|
+
else
|
136
|
+
raise TypeError,
|
137
|
+
"Expected String or StringIO, got #{new_merged_body.class}."
|
138
|
+
end
|
139
|
+
self.body = [new_merged_body]
|
140
|
+
end
|
141
|
+
|
142
|
+
def headers
|
143
|
+
return @headers ||= []
|
144
|
+
end
|
145
|
+
|
146
|
+
def headers=(new_headers)
|
147
|
+
if new_headers.kind_of?(Array) || new_headers.kind_of?(Hash)
|
148
|
+
@headers = new_headers
|
149
|
+
else
|
150
|
+
raise TypeError, "Expected Hash or Array, got #{new_headers.class}."
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def http_method
|
155
|
+
return @http_method ||= self.api_method.http_method
|
156
|
+
end
|
157
|
+
|
158
|
+
def http_method=(new_http_method)
|
159
|
+
if new_http_method.kind_of?(Symbol)
|
160
|
+
@http_method = new_http_method.to_s.upcase
|
161
|
+
elsif new_http_method.respond_to?(:to_str)
|
162
|
+
@http_method = new_http_method.to_str.upcase
|
163
|
+
else
|
164
|
+
raise TypeError,
|
165
|
+
"Expected String or Symbol, got #{new_http_method.class}."
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def uri
|
170
|
+
return @uri ||= self.api_method.generate_uri(self.parameters)
|
171
|
+
end
|
172
|
+
|
173
|
+
def uri=(new_uri)
|
174
|
+
@uri = Addressable::URI.parse(new_uri)
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_request
|
178
|
+
if self.api_method
|
179
|
+
return self.api_method.generate_request(
|
180
|
+
self.parameters, self.merged_body, self.headers
|
181
|
+
)
|
182
|
+
else
|
183
|
+
return [self.http_method, self.uri, self.headers, self.body]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def to_hash
|
188
|
+
options = {}
|
189
|
+
if self.api_method
|
190
|
+
options[:api_method] = self.api_method
|
191
|
+
options[:parameters] = self.parameters
|
192
|
+
else
|
193
|
+
options[:http_method] = self.http_method
|
194
|
+
options[:uri] = self.uri
|
195
|
+
end
|
196
|
+
options[:headers] = self.headers
|
197
|
+
options[:body] = self.body
|
198
|
+
return options
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# Copyright 2010 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Google
|
16
|
+
class APIClient
|
17
|
+
##
|
18
|
+
# This class wraps a result returned by an API call.
|
19
|
+
class Result
|
20
|
+
def initialize(reference, request, response)
|
21
|
+
@reference = reference
|
22
|
+
@request = request
|
23
|
+
@response = response
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :reference
|
27
|
+
|
28
|
+
attr_reader :request
|
29
|
+
|
30
|
+
attr_reader :response
|
31
|
+
|
32
|
+
def status
|
33
|
+
return @response[0]
|
34
|
+
end
|
35
|
+
|
36
|
+
def headers
|
37
|
+
return @response[1]
|
38
|
+
end
|
39
|
+
|
40
|
+
def body
|
41
|
+
return @body ||= (begin
|
42
|
+
response_body = @response[2]
|
43
|
+
merged_body = (response_body.inject(StringIO.new) do |accu, chunk|
|
44
|
+
accu.write(chunk)
|
45
|
+
accu
|
46
|
+
end).string
|
47
|
+
end)
|
48
|
+
end
|
49
|
+
|
50
|
+
def data
|
51
|
+
return @data ||= (begin
|
52
|
+
_, content_type = self.headers.detect do |h, v|
|
53
|
+
h.downcase == 'Content-Type'.downcase
|
54
|
+
end
|
55
|
+
media_type = content_type[/^([^;]*);?.*$/, 1].strip.downcase
|
56
|
+
data = self.body
|
57
|
+
case media_type
|
58
|
+
when 'application/json'
|
59
|
+
data = ::JSON.parse(data)
|
60
|
+
# Strip data wrapper, if present
|
61
|
+
data = data['data'] if data.has_key?('data')
|
62
|
+
else
|
63
|
+
raise ArgumentError,
|
64
|
+
"Content-Type not supported for parsing: #{media_type}"
|
65
|
+
end
|
66
|
+
if @reference.api_method && @reference.api_method.response_schema
|
67
|
+
# Automatically parse using the schema designated for the
|
68
|
+
# response of this API method.
|
69
|
+
data = @reference.api_method.response_schema.new(data)
|
70
|
+
data
|
71
|
+
else
|
72
|
+
# Otherwise, return the raw unparsed value.
|
73
|
+
# This value must be indexable like a Hash.
|
74
|
+
data
|
75
|
+
end
|
76
|
+
end)
|
77
|
+
end
|
78
|
+
|
79
|
+
def pagination_type
|
80
|
+
return :token
|
81
|
+
end
|
82
|
+
|
83
|
+
def page_token_param
|
84
|
+
return "pageToken"
|
85
|
+
end
|
86
|
+
|
87
|
+
def next_page_token
|
88
|
+
if self.data.respond_to?(:next_page_token)
|
89
|
+
return self.data.next_page_token
|
90
|
+
elsif self.data.respond_to?(:[])
|
91
|
+
return self.data["nextPageToken"]
|
92
|
+
else
|
93
|
+
raise TypeError, "Data object did not respond to #next_page_token."
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def next_page
|
98
|
+
merged_parameters = Hash[self.reference.parameters].merge({
|
99
|
+
self.page_token_param => self.next_page_token
|
100
|
+
})
|
101
|
+
# Because References can be coerced to Hashes, we can merge them,
|
102
|
+
# preserving all context except the API method parameters that we're
|
103
|
+
# using for pagination.
|
104
|
+
return Google::APIClient::Reference.new(
|
105
|
+
Hash[self.reference].merge(:parameters => merged_parameters)
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
def prev_page_token
|
110
|
+
if self.data.respond_to?(:prev_page_token)
|
111
|
+
return self.data.prev_page_token
|
112
|
+
elsif self.data.respond_to?(:[])
|
113
|
+
return self.data["prevPageToken"]
|
114
|
+
else
|
115
|
+
raise TypeError, "Data object did not respond to #next_page_token."
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def prev_page
|
120
|
+
merged_parameters = Hash[self.reference.parameters].merge({
|
121
|
+
self.page_token_param => self.prev_page_token
|
122
|
+
})
|
123
|
+
# Because References can be coerced to Hashes, we can merge them,
|
124
|
+
# preserving all context except the API method parameters that we're
|
125
|
+
# using for pagination.
|
126
|
+
return Google::APIClient::Reference.new(
|
127
|
+
Hash[self.reference].merge(:parameters => merged_parameters)
|
128
|
+
)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -13,14 +13,17 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
-
module
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
# Used to prevent the class/module from being loaded more than once
|
17
|
+
if !defined?(::Google::APIClient::VERSION)
|
18
|
+
module Google
|
19
|
+
class APIClient
|
20
|
+
module VERSION
|
21
|
+
MAJOR = 0
|
22
|
+
MINOR = 3
|
23
|
+
TINY = 0
|
22
24
|
|
23
|
-
|
25
|
+
STRING = [MAJOR, MINOR, TINY].join('.')
|
26
|
+
end
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
data/lib/google/inflection.rb
CHANGED
@@ -17,7 +17,12 @@ module Google
|
|
17
17
|
if defined?(ActiveSupport::Inflector)
|
18
18
|
INFLECTOR = ActiveSupport::Inflector
|
19
19
|
else
|
20
|
-
|
21
|
-
|
20
|
+
begin
|
21
|
+
require 'extlib/inflection'
|
22
|
+
INFLECTOR = Extlib::Inflection
|
23
|
+
rescue LoadError
|
24
|
+
require 'active_support/inflector'
|
25
|
+
INFLECTOR = ActiveSupport::Inflector
|
26
|
+
end
|
22
27
|
end
|
23
28
|
end
|
@@ -14,6 +14,7 @@
|
|
14
14
|
|
15
15
|
require 'spec_helper'
|
16
16
|
|
17
|
+
require 'json'
|
17
18
|
require 'signet/oauth_1/client'
|
18
19
|
require 'httpadapter/adapters/net_http'
|
19
20
|
|
@@ -66,6 +67,9 @@ describe Google::APIClient do
|
|
66
67
|
describe 'with the prediction API' do
|
67
68
|
before do
|
68
69
|
@client.authorization = nil
|
70
|
+
# The prediction API no longer exposes a v1, so we have to be
|
71
|
+
# careful about looking up the wrong API version.
|
72
|
+
@prediction = @client.discovered_api('prediction', 'v1.2')
|
69
73
|
end
|
70
74
|
|
71
75
|
it 'should correctly determine the discovery URI' do
|
@@ -73,46 +77,83 @@ describe Google::APIClient do
|
|
73
77
|
'https://www.googleapis.com/discovery/v1/apis/prediction/v1/rest'
|
74
78
|
end
|
75
79
|
|
80
|
+
it 'should correctly determine the discovery URI if :user_ip is set' do
|
81
|
+
@client.user_ip = '127.0.0.1'
|
82
|
+
request = @client.generate_request(
|
83
|
+
:http_method => 'GET',
|
84
|
+
:uri => @client.discovery_uri('prediction', 'v1.2'),
|
85
|
+
:authenticated => false
|
86
|
+
)
|
87
|
+
http_method, uri, headers, body = request
|
88
|
+
uri.should === (
|
89
|
+
'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
|
90
|
+
'?userIp=127.0.0.1'
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should correctly determine the discovery URI if :key is set' do
|
95
|
+
@client.key = 'qwerty'
|
96
|
+
request = @client.generate_request(
|
97
|
+
:http_method => 'GET',
|
98
|
+
:uri => @client.discovery_uri('prediction', 'v1.2'),
|
99
|
+
:authenticated => false
|
100
|
+
)
|
101
|
+
http_method, uri, headers, body = request
|
102
|
+
uri.should === (
|
103
|
+
'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
|
104
|
+
'?key=qwerty'
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should correctly determine the discovery URI if both are set' do
|
109
|
+
@client.key = 'qwerty'
|
110
|
+
@client.user_ip = '127.0.0.1'
|
111
|
+
request = @client.generate_request(
|
112
|
+
:http_method => 'GET',
|
113
|
+
:uri => @client.discovery_uri('prediction', 'v1.2'),
|
114
|
+
:authenticated => false
|
115
|
+
)
|
116
|
+
http_method, uri, headers, body = request
|
117
|
+
uri.should === (
|
118
|
+
'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
|
119
|
+
'?key=qwerty&userIp=127.0.0.1'
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
76
123
|
it 'should correctly generate API objects' do
|
77
|
-
@client.discovered_api('prediction').name.should == 'prediction'
|
78
|
-
@client.discovered_api('prediction').version.should == 'v1'
|
79
|
-
@client.discovered_api(:prediction).name.should == 'prediction'
|
80
|
-
@client.discovered_api(:prediction).version.should == 'v1'
|
124
|
+
@client.discovered_api('prediction', 'v1.2').name.should == 'prediction'
|
125
|
+
@client.discovered_api('prediction', 'v1.2').version.should == 'v1.2'
|
126
|
+
@client.discovered_api(:prediction, 'v1.2').name.should == 'prediction'
|
127
|
+
@client.discovered_api(:prediction, 'v1.2').version.should == 'v1.2'
|
81
128
|
end
|
82
129
|
|
83
130
|
it 'should discover methods' do
|
84
131
|
@client.discovered_method(
|
85
|
-
'prediction.training.insert', 'prediction'
|
132
|
+
'prediction.training.insert', 'prediction', 'v1.2'
|
86
133
|
).name.should == 'insert'
|
87
134
|
@client.discovered_method(
|
88
|
-
:'prediction.training.insert', :prediction
|
135
|
+
:'prediction.training.insert', :prediction, 'v1.2'
|
89
136
|
).name.should == 'insert'
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'should discover methods' do
|
93
137
|
@client.discovered_method(
|
94
|
-
'prediction.training.delete', 'prediction', 'v1.
|
138
|
+
'prediction.training.delete', 'prediction', 'v1.2'
|
95
139
|
).name.should == 'delete'
|
96
140
|
end
|
97
141
|
|
98
142
|
it 'should not find methods that are not in the discovery document' do
|
99
143
|
@client.discovered_method(
|
100
|
-
'prediction.
|
101
|
-
).should == nil
|
102
|
-
@client.discovered_method(
|
103
|
-
'prediction.bogus', 'prediction', 'v1'
|
144
|
+
'prediction.bogus', 'prediction', 'v1.2'
|
104
145
|
).should == nil
|
105
146
|
end
|
106
147
|
|
107
148
|
it 'should raise an error for bogus methods' do
|
108
149
|
(lambda do
|
109
|
-
@client.discovered_method(42, 'prediction', 'v1')
|
150
|
+
@client.discovered_method(42, 'prediction', 'v1.2')
|
110
151
|
end).should raise_error(TypeError)
|
111
152
|
end
|
112
153
|
|
113
154
|
it 'should raise an error for bogus methods' do
|
114
155
|
(lambda do
|
115
|
-
@client.generate_request(@client.discovered_api('prediction'))
|
156
|
+
@client.generate_request(@client.discovered_api('prediction', 'v1.2'))
|
116
157
|
end).should raise_error(TypeError)
|
117
158
|
end
|
118
159
|
|
@@ -123,49 +164,50 @@ describe Google::APIClient do
|
|
123
164
|
|
124
165
|
it 'should generate valid requests' do
|
125
166
|
request = @client.generate_request(
|
126
|
-
|
127
|
-
{'data' => '12345', }
|
167
|
+
:api_method => @prediction.training.insert,
|
168
|
+
:parameters => {'data' => '12345', }
|
128
169
|
)
|
129
170
|
method, uri, headers, body = request
|
130
171
|
method.should == 'POST'
|
131
172
|
uri.should ==
|
132
|
-
'https://www.googleapis.com/prediction/v1/training?data=12345'
|
173
|
+
'https://www.googleapis.com/prediction/v1.2/training?data=12345'
|
133
174
|
(headers.inject({}) { |h,(k,v)| h[k]=v; h }).should == {}
|
134
175
|
body.should respond_to(:each)
|
135
176
|
end
|
136
177
|
|
137
178
|
it 'should generate requests against the correct URIs' do
|
138
179
|
request = @client.generate_request(
|
139
|
-
:
|
140
|
-
{'data' => '12345'}
|
180
|
+
:api_method => @prediction.training.insert,
|
181
|
+
:parameters => {'data' => '12345'}
|
141
182
|
)
|
142
183
|
method, uri, headers, body = request
|
143
184
|
uri.should ==
|
144
|
-
'https://www.googleapis.com/prediction/v1/training?data=12345'
|
185
|
+
'https://www.googleapis.com/prediction/v1.2/training?data=12345'
|
145
186
|
end
|
146
187
|
|
147
188
|
it 'should generate requests against the correct URIs' do
|
148
|
-
prediction = @client.discovered_api('prediction', 'v1')
|
149
189
|
request = @client.generate_request(
|
150
|
-
prediction.training.insert,
|
151
|
-
{'data' => '12345'}
|
190
|
+
:api_method => @prediction.training.insert,
|
191
|
+
:parameters => {'data' => '12345'}
|
152
192
|
)
|
153
193
|
method, uri, headers, body = request
|
154
194
|
uri.should ==
|
155
|
-
'https://www.googleapis.com/prediction/v1/training?data=12345'
|
195
|
+
'https://www.googleapis.com/prediction/v1.2/training?data=12345'
|
156
196
|
end
|
157
197
|
|
158
198
|
it 'should allow modification to the base URIs for testing purposes' do
|
159
|
-
prediction = @client.discovered_api('prediction', 'v1')
|
199
|
+
prediction = @client.discovered_api('prediction', 'v1.2')
|
160
200
|
prediction.method_base =
|
161
|
-
'https://testing-domain.googleapis.com/prediction/v1/'
|
201
|
+
'https://testing-domain.googleapis.com/prediction/v1.2/'
|
162
202
|
request = @client.generate_request(
|
163
|
-
prediction.training.insert,
|
164
|
-
{'data' => '123'}
|
203
|
+
:api_method => prediction.training.insert,
|
204
|
+
:parameters => {'data' => '123'}
|
165
205
|
)
|
166
206
|
method, uri, headers, body = request
|
167
|
-
uri.should ==
|
168
|
-
'https://testing-domain.googleapis.com/
|
207
|
+
uri.should == (
|
208
|
+
'https://testing-domain.googleapis.com/' +
|
209
|
+
'prediction/v1.2/training?data=123'
|
210
|
+
)
|
169
211
|
end
|
170
212
|
|
171
213
|
it 'should generate OAuth 1 requests' do
|
@@ -173,8 +215,8 @@ describe Google::APIClient do
|
|
173
215
|
@client.authorization.token_credential_key = '12345'
|
174
216
|
@client.authorization.token_credential_secret = '12345'
|
175
217
|
request = @client.generate_request(
|
176
|
-
|
177
|
-
{'data' => '12345'}
|
218
|
+
:api_method => @prediction.training.insert,
|
219
|
+
:parameters => {'data' => '12345'}
|
178
220
|
)
|
179
221
|
method, uri, headers, body = request
|
180
222
|
headers = headers.inject({}) { |h,(k,v)| h[k]=v; h }
|
@@ -186,8 +228,8 @@ describe Google::APIClient do
|
|
186
228
|
@client.authorization = :oauth_2
|
187
229
|
@client.authorization.access_token = '12345'
|
188
230
|
request = @client.generate_request(
|
189
|
-
|
190
|
-
{'data' => '12345'}
|
231
|
+
:api_method => @prediction.training.insert,
|
232
|
+
:parameters => {'data' => '12345'}
|
191
233
|
)
|
192
234
|
method, uri, headers, body = request
|
193
235
|
headers = headers.inject({}) { |h,(k,v)| h[k]=v; h }
|
@@ -199,88 +241,112 @@ describe Google::APIClient do
|
|
199
241
|
@client.authorization = :oauth_1
|
200
242
|
@client.authorization.token_credential_key = '12345'
|
201
243
|
@client.authorization.token_credential_secret = '12345'
|
202
|
-
|
203
|
-
|
244
|
+
result = @client.execute(
|
245
|
+
@prediction.training.insert,
|
204
246
|
{'data' => '12345'}
|
205
247
|
)
|
206
|
-
status, headers, body = response
|
248
|
+
status, headers, body = result.response
|
207
249
|
status.should == 401
|
208
250
|
end
|
209
251
|
|
210
252
|
it 'should not be able to execute improperly authorized requests' do
|
211
253
|
@client.authorization = :oauth_2
|
212
254
|
@client.authorization.access_token = '12345'
|
213
|
-
|
214
|
-
|
255
|
+
result = @client.execute(
|
256
|
+
@prediction.training.insert,
|
215
257
|
{'data' => '12345'}
|
216
258
|
)
|
217
|
-
status, headers, body = response
|
259
|
+
status, headers, body = result.response
|
218
260
|
status.should == 401
|
219
261
|
end
|
262
|
+
|
263
|
+
it 'should not be able to execute improperly authorized requests' do
|
264
|
+
(lambda do
|
265
|
+
@client.authorization = :oauth_1
|
266
|
+
@client.authorization.token_credential_key = '12345'
|
267
|
+
@client.authorization.token_credential_secret = '12345'
|
268
|
+
result = @client.execute!(
|
269
|
+
@prediction.training.insert,
|
270
|
+
{'data' => '12345'}
|
271
|
+
)
|
272
|
+
end).should raise_error(Google::APIClient::ClientError)
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'should not be able to execute improperly authorized requests' do
|
276
|
+
(lambda do
|
277
|
+
@client.authorization = :oauth_2
|
278
|
+
@client.authorization.access_token = '12345'
|
279
|
+
result = @client.execute!(
|
280
|
+
@prediction.training.insert,
|
281
|
+
{'data' => '12345'}
|
282
|
+
)
|
283
|
+
end).should raise_error(Google::APIClient::ClientError)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'should correctly handle unnamed parameters' do
|
287
|
+
@client.authorization = :oauth_2
|
288
|
+
@client.authorization.access_token = '12345'
|
289
|
+
result = @client.execute(
|
290
|
+
@prediction.training.insert,
|
291
|
+
{},
|
292
|
+
JSON.generate({"id" => "bucket/object"}),
|
293
|
+
{'Content-Type' => 'application/json'}
|
294
|
+
)
|
295
|
+
method, uri, headers, body = result.request
|
296
|
+
Hash[headers]['Content-Type'].should == 'application/json'
|
297
|
+
end
|
220
298
|
end
|
221
299
|
|
222
|
-
describe 'with the
|
300
|
+
describe 'with the plus API' do
|
223
301
|
before do
|
224
302
|
@client.authorization = nil
|
225
|
-
@
|
303
|
+
@plus = @client.discovered_api('plus')
|
226
304
|
end
|
227
305
|
|
228
306
|
it 'should correctly determine the discovery URI' do
|
229
|
-
@client.discovery_uri('
|
230
|
-
'https://www.googleapis.com/discovery/v1/apis/
|
307
|
+
@client.discovery_uri('plus').should ===
|
308
|
+
'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
|
231
309
|
end
|
232
310
|
|
233
311
|
it 'should find APIs that are in the discovery document' do
|
234
|
-
@client.discovered_api('
|
235
|
-
@client.discovered_api('
|
236
|
-
@client.discovered_api(:
|
237
|
-
@client.discovered_api(:
|
312
|
+
@client.discovered_api('plus').name.should == 'plus'
|
313
|
+
@client.discovered_api('plus').version.should == 'v1'
|
314
|
+
@client.discovered_api(:plus).name.should == 'plus'
|
315
|
+
@client.discovered_api(:plus).version.should == 'v1'
|
238
316
|
end
|
239
317
|
|
240
318
|
it 'should find methods that are in the discovery document' do
|
241
319
|
# TODO(bobaman) Fix this when the RPC names are correct
|
242
320
|
@client.discovered_method(
|
243
|
-
'
|
321
|
+
'plus.activities.list', 'plus'
|
244
322
|
).name.should == 'list'
|
245
323
|
end
|
246
324
|
|
247
325
|
it 'should not find methods that are not in the discovery document' do
|
248
|
-
@client.discovered_method('
|
249
|
-
end
|
250
|
-
|
251
|
-
it 'should fail for string RPC names that do not match API name' do
|
252
|
-
(lambda do
|
253
|
-
@client.generate_request(
|
254
|
-
'chili.activities.list',
|
255
|
-
{'alt' => 'json'},
|
256
|
-
'',
|
257
|
-
[],
|
258
|
-
{:signed => false}
|
259
|
-
)
|
260
|
-
end).should raise_error(Google::APIClient::TransmissionError)
|
326
|
+
@client.discovered_method('plus.bogus', 'plus').should == nil
|
261
327
|
end
|
262
328
|
|
263
329
|
it 'should generate requests against the correct URIs' do
|
264
330
|
request = @client.generate_request(
|
265
|
-
@
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
331
|
+
:api_method => @plus.activities.list,
|
332
|
+
:parameters => {
|
333
|
+
'userId' => '107807692475771887386', 'collection' => 'public'
|
334
|
+
},
|
335
|
+
:authenticated => false
|
270
336
|
)
|
271
337
|
method, uri, headers, body = request
|
272
|
-
uri.should ==
|
273
|
-
'https://www.googleapis.com/
|
338
|
+
uri.should == (
|
339
|
+
'https://www.googleapis.com/plus/v1/' +
|
340
|
+
'people/107807692475771887386/activities/public'
|
341
|
+
)
|
274
342
|
end
|
275
343
|
|
276
344
|
it 'should correctly validate parameters' do
|
277
345
|
(lambda do
|
278
346
|
@client.generate_request(
|
279
|
-
@
|
280
|
-
{'alt' => 'json'},
|
281
|
-
|
282
|
-
[],
|
283
|
-
{:signed => false}
|
347
|
+
:api_method => @plus.activities.list,
|
348
|
+
:parameters => {'alt' => 'json'},
|
349
|
+
:authenticated => false
|
284
350
|
)
|
285
351
|
end).should raise_error(ArgumentError)
|
286
352
|
end
|
@@ -288,26 +354,14 @@ describe Google::APIClient do
|
|
288
354
|
it 'should correctly validate parameters' do
|
289
355
|
(lambda do
|
290
356
|
@client.generate_request(
|
291
|
-
@
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
357
|
+
:api_method => @plus.activities.list,
|
358
|
+
:parameters => {
|
359
|
+
'userId' => '107807692475771887386', 'collection' => 'bogus'
|
360
|
+
},
|
361
|
+
:authenticated => false
|
296
362
|
)
|
297
363
|
end).should raise_error(ArgumentError)
|
298
364
|
end
|
299
|
-
|
300
|
-
it 'should be able to execute requests without authorization' do
|
301
|
-
response = @client.execute(
|
302
|
-
@buzz.activities.list,
|
303
|
-
{'alt' => 'json', 'userId' => 'hikingfan', 'scope' => '@public'},
|
304
|
-
'',
|
305
|
-
[],
|
306
|
-
{:signed => false}
|
307
|
-
)
|
308
|
-
status, headers, body = response
|
309
|
-
status.should == 200
|
310
|
-
end
|
311
365
|
end
|
312
366
|
|
313
367
|
describe 'with the latitude API' do
|
@@ -338,11 +392,8 @@ describe Google::APIClient do
|
|
338
392
|
|
339
393
|
it 'should generate requests against the correct URIs' do
|
340
394
|
request = @client.generate_request(
|
341
|
-
'latitude.currentLocation.get',
|
342
|
-
|
343
|
-
'',
|
344
|
-
[],
|
345
|
-
{:signed => false}
|
395
|
+
:api_method => 'latitude.currentLocation.get',
|
396
|
+
:authenticated => false
|
346
397
|
)
|
347
398
|
method, uri, headers, body = request
|
348
399
|
uri.should ==
|
@@ -351,11 +402,8 @@ describe Google::APIClient do
|
|
351
402
|
|
352
403
|
it 'should generate requests against the correct URIs' do
|
353
404
|
request = @client.generate_request(
|
354
|
-
@latitude.current_location.get,
|
355
|
-
|
356
|
-
'',
|
357
|
-
[],
|
358
|
-
{:signed => false}
|
405
|
+
:api_method => @latitude.current_location.get,
|
406
|
+
:authenticated => false
|
359
407
|
)
|
360
408
|
method, uri, headers, body = request
|
361
409
|
uri.should ==
|
@@ -363,14 +411,11 @@ describe Google::APIClient do
|
|
363
411
|
end
|
364
412
|
|
365
413
|
it 'should not be able to execute requests without authorization' do
|
366
|
-
|
367
|
-
'latitude.currentLocation.get',
|
368
|
-
|
369
|
-
'',
|
370
|
-
[],
|
371
|
-
{:signed => false}
|
414
|
+
result = @client.execute(
|
415
|
+
:api_method => 'latitude.currentLocation.get',
|
416
|
+
:authenticated => false
|
372
417
|
)
|
373
|
-
status, headers, body = response
|
418
|
+
status, headers, body = result.response
|
374
419
|
status.should == 401
|
375
420
|
end
|
376
421
|
end
|
@@ -403,11 +448,8 @@ describe Google::APIClient do
|
|
403
448
|
|
404
449
|
it 'should generate requests against the correct URIs' do
|
405
450
|
request = @client.generate_request(
|
406
|
-
'moderator.profiles.get',
|
407
|
-
|
408
|
-
'',
|
409
|
-
[],
|
410
|
-
{:signed => false}
|
451
|
+
:api_method => 'moderator.profiles.get',
|
452
|
+
:authenticated => false
|
411
453
|
)
|
412
454
|
method, uri, headers, body = request
|
413
455
|
uri.should ==
|
@@ -416,11 +458,8 @@ describe Google::APIClient do
|
|
416
458
|
|
417
459
|
it 'should generate requests against the correct URIs' do
|
418
460
|
request = @client.generate_request(
|
419
|
-
@moderator.profiles.get,
|
420
|
-
|
421
|
-
'',
|
422
|
-
[],
|
423
|
-
{:signed => false}
|
461
|
+
:api_method => @moderator.profiles.get,
|
462
|
+
:authenticated => false
|
424
463
|
)
|
425
464
|
method, uri, headers, body = request
|
426
465
|
uri.should ==
|
@@ -428,14 +467,14 @@ describe Google::APIClient do
|
|
428
467
|
end
|
429
468
|
|
430
469
|
it 'should not be able to execute requests without authorization' do
|
431
|
-
|
470
|
+
result = @client.execute(
|
432
471
|
'moderator.profiles.get',
|
433
472
|
{},
|
434
473
|
'',
|
435
474
|
[],
|
436
|
-
{:
|
475
|
+
{:authenticated => false}
|
437
476
|
)
|
438
|
-
status, headers, body = response
|
477
|
+
status, headers, body = result.response
|
439
478
|
status.should == 401
|
440
479
|
end
|
441
480
|
end
|