jomz-google-api-client 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/CHANGELOG.md +144 -0
  2. data/CONTRIBUTING.md +32 -0
  3. data/Gemfile +41 -0
  4. data/LICENSE +202 -0
  5. data/README.md +192 -0
  6. data/Rakefile +46 -0
  7. data/lib/cacerts.pem +2183 -0
  8. data/lib/compat/multi_json.rb +16 -0
  9. data/lib/google/api_client.rb +672 -0
  10. data/lib/google/api_client/auth/compute_service_account.rb +28 -0
  11. data/lib/google/api_client/auth/file_storage.rb +87 -0
  12. data/lib/google/api_client/auth/installed_app.rb +122 -0
  13. data/lib/google/api_client/auth/jwt_asserter.rb +126 -0
  14. data/lib/google/api_client/auth/key_utils.rb +93 -0
  15. data/lib/google/api_client/auth/pkcs12.rb +41 -0
  16. data/lib/google/api_client/batch.rb +323 -0
  17. data/lib/google/api_client/client_secrets.rb +176 -0
  18. data/lib/google/api_client/discovery.rb +19 -0
  19. data/lib/google/api_client/discovery/api.rb +300 -0
  20. data/lib/google/api_client/discovery/media.rb +77 -0
  21. data/lib/google/api_client/discovery/method.rb +363 -0
  22. data/lib/google/api_client/discovery/resource.rb +156 -0
  23. data/lib/google/api_client/discovery/schema.rb +121 -0
  24. data/lib/google/api_client/environment.rb +42 -0
  25. data/lib/google/api_client/errors.rb +60 -0
  26. data/lib/google/api_client/gzip.rb +28 -0
  27. data/lib/google/api_client/logging.rb +32 -0
  28. data/lib/google/api_client/media.rb +259 -0
  29. data/lib/google/api_client/railtie.rb +16 -0
  30. data/lib/google/api_client/reference.rb +27 -0
  31. data/lib/google/api_client/request.rb +351 -0
  32. data/lib/google/api_client/result.rb +253 -0
  33. data/lib/google/api_client/service.rb +233 -0
  34. data/lib/google/api_client/service/batch.rb +103 -0
  35. data/lib/google/api_client/service/request.rb +144 -0
  36. data/lib/google/api_client/service/resource.rb +40 -0
  37. data/lib/google/api_client/service/result.rb +162 -0
  38. data/lib/google/api_client/service/simple_file_store.rb +151 -0
  39. data/lib/google/api_client/service/stub_generator.rb +59 -0
  40. data/lib/google/api_client/service_account.rb +18 -0
  41. data/lib/google/api_client/version.rb +31 -0
  42. data/lib/google/inflection.rb +28 -0
  43. data/spec/fixtures/files/privatekey.p12 +0 -0
  44. data/spec/fixtures/files/sample.txt +33 -0
  45. data/spec/fixtures/files/secret.pem +19 -0
  46. data/spec/google/api_client/batch_spec.rb +249 -0
  47. data/spec/google/api_client/discovery_spec.rb +652 -0
  48. data/spec/google/api_client/gzip_spec.rb +86 -0
  49. data/spec/google/api_client/media_spec.rb +179 -0
  50. data/spec/google/api_client/request_spec.rb +30 -0
  51. data/spec/google/api_client/result_spec.rb +203 -0
  52. data/spec/google/api_client/service_account_spec.rb +164 -0
  53. data/spec/google/api_client/service_spec.rb +586 -0
  54. data/spec/google/api_client/simple_file_store_spec.rb +137 -0
  55. data/spec/google/api_client_spec.rb +253 -0
  56. data/spec/spec_helper.rb +56 -0
  57. data/tasks/gem.rake +97 -0
  58. data/tasks/git.rake +45 -0
  59. data/tasks/metrics.rake +22 -0
  60. data/tasks/spec.rake +57 -0
  61. data/tasks/wiki.rake +82 -0
  62. data/tasks/yard.rake +29 -0
  63. metadata +309 -0
@@ -0,0 +1,137 @@
1
+ # encoding:utf-8
2
+
3
+ # Copyright 2013 Google Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'spec_helper'
18
+
19
+ require 'google/api_client/service/simple_file_store'
20
+
21
+ describe Google::APIClient::Service::SimpleFileStore do
22
+
23
+ FILE_NAME = 'test.cache'
24
+
25
+ before(:all) do
26
+ File.delete(FILE_NAME) if File.exists?(FILE_NAME)
27
+ end
28
+
29
+ describe 'with no cache file' do
30
+ before(:each) do
31
+ File.delete(FILE_NAME) if File.exists?(FILE_NAME)
32
+ @cache = Google::APIClient::Service::SimpleFileStore.new(FILE_NAME)
33
+ end
34
+
35
+ it 'should return nil when asked if a key exists' do
36
+ @cache.exist?('invalid').should be_nil
37
+ File.exists?(FILE_NAME).should be_false
38
+ end
39
+
40
+ it 'should return nil when asked to read a key' do
41
+ @cache.read('invalid').should be_nil
42
+ File.exists?(FILE_NAME).should be_false
43
+ end
44
+
45
+ it 'should return nil when asked to fetch a key' do
46
+ @cache.fetch('invalid').should be_nil
47
+ File.exists?(FILE_NAME).should be_false
48
+ end
49
+
50
+ it 'should create a cache file when asked to fetch a key with a default' do
51
+ @cache.fetch('new_key') do
52
+ 'value'
53
+ end.should == 'value'
54
+ File.exists?(FILE_NAME).should be_true
55
+ end
56
+
57
+ it 'should create a cache file when asked to write a key' do
58
+ @cache.write('new_key', 'value')
59
+ File.exists?(FILE_NAME).should be_true
60
+ end
61
+
62
+ it 'should return nil when asked to delete a key' do
63
+ @cache.delete('invalid').should be_nil
64
+ File.exists?(FILE_NAME).should be_false
65
+ end
66
+ end
67
+
68
+ describe 'with an existing cache' do
69
+ before(:each) do
70
+ File.delete(FILE_NAME) if File.exists?(FILE_NAME)
71
+ @cache = Google::APIClient::Service::SimpleFileStore.new(FILE_NAME)
72
+ @cache.write('existing_key', 'existing_value')
73
+ end
74
+
75
+ it 'should return true when asked if an existing key exists' do
76
+ @cache.exist?('existing_key').should be_true
77
+ end
78
+
79
+ it 'should return false when asked if a nonexistent key exists' do
80
+ @cache.exist?('invalid').should be_false
81
+ end
82
+
83
+ it 'should return the value for an existing key when asked to read it' do
84
+ @cache.read('existing_key').should == 'existing_value'
85
+ end
86
+
87
+ it 'should return nil for a nonexistent key when asked to read it' do
88
+ @cache.read('invalid').should be_nil
89
+ end
90
+
91
+ it 'should return the value for an existing key when asked to read it' do
92
+ @cache.read('existing_key').should == 'existing_value'
93
+ end
94
+
95
+ it 'should return nil for a nonexistent key when asked to fetch it' do
96
+ @cache.fetch('invalid').should be_nil
97
+ end
98
+
99
+ it 'should return and save the default value for a nonexistent key when asked to fetch it with a default' do
100
+ @cache.fetch('new_key') do
101
+ 'value'
102
+ end.should == 'value'
103
+ @cache.read('new_key').should == 'value'
104
+ end
105
+
106
+ it 'should remove an existing value and return true when asked to delete it' do
107
+ @cache.delete('existing_key').should be_true
108
+ @cache.read('existing_key').should be_nil
109
+ end
110
+
111
+ it 'should return false when asked to delete a nonexistent key' do
112
+ @cache.delete('invalid').should be_false
113
+ end
114
+
115
+ it 'should convert keys to strings when storing them' do
116
+ @cache.write(:symbol_key, 'value')
117
+ @cache.read('symbol_key').should == 'value'
118
+ end
119
+
120
+ it 'should convert keys to strings when reading them' do
121
+ @cache.read(:existing_key).should == 'existing_value'
122
+ end
123
+
124
+ it 'should convert keys to strings when fetching them' do
125
+ @cache.fetch(:existing_key).should == 'existing_value'
126
+ end
127
+
128
+ it 'should convert keys to strings when deleting them' do
129
+ @cache.delete(:existing_key).should be_true
130
+ @cache.read('existing_key').should be_nil
131
+ end
132
+ end
133
+
134
+ after(:all) do
135
+ File.delete(FILE_NAME) if File.exists?(FILE_NAME)
136
+ end
137
+ end
@@ -0,0 +1,253 @@
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 'spec_helper'
16
+
17
+ require 'faraday'
18
+ require 'signet/oauth_1/client'
19
+ require 'google/api_client'
20
+ require 'google/api_client/version'
21
+
22
+ shared_examples_for 'configurable user agent' do
23
+ include ConnectionHelpers
24
+
25
+ it 'should allow the user agent to be modified' do
26
+ client.user_agent = 'Custom User Agent/1.2.3'
27
+ client.user_agent.should == 'Custom User Agent/1.2.3'
28
+ end
29
+
30
+ it 'should allow the user agent to be set to nil' do
31
+ client.user_agent = nil
32
+ client.user_agent.should == nil
33
+ end
34
+
35
+ it 'should not allow the user agent to be used with bogus values' do
36
+ (lambda do
37
+ client.user_agent = 42
38
+ client.execute(:uri=>'https://www.google.com/')
39
+ end).should raise_error(TypeError)
40
+ end
41
+
42
+ it 'should transmit a User-Agent header when sending requests' do
43
+ client.user_agent = 'Custom User Agent/1.2.3'
44
+
45
+ conn = stub_connection do |stub|
46
+ stub.get('/') do |env|
47
+ headers = env[:request_headers]
48
+ headers.should have_key('User-Agent')
49
+ headers['User-Agent'].should == client.user_agent
50
+ [200, {}, ['']]
51
+ end
52
+ end
53
+ client.execute(:uri=>'https://www.google.com/', :connection => conn)
54
+ conn.verify
55
+ end
56
+ end
57
+
58
+ describe Google::APIClient do
59
+ include ConnectionHelpers
60
+
61
+ let(:client) { Google::APIClient.new(:application_name => 'API Client Tests') }
62
+
63
+ it 'should make its version number available' do
64
+ Google::APIClient::VERSION::STRING.should be_instance_of(String)
65
+ end
66
+
67
+ it 'should default to OAuth 2' do
68
+ Signet::OAuth2::Client.should === client.authorization
69
+ end
70
+
71
+ describe 'configure for no authentication' do
72
+ before do
73
+ client.authorization = nil
74
+ end
75
+ it_should_behave_like 'configurable user agent'
76
+ end
77
+
78
+ describe 'configured for OAuth 1' do
79
+ before do
80
+ client.authorization = :oauth_1
81
+ client.authorization.token_credential_key = 'abc'
82
+ client.authorization.token_credential_secret = '123'
83
+ end
84
+
85
+ it 'should use the default OAuth1 client configuration' do
86
+ client.authorization.temporary_credential_uri.to_s.should ==
87
+ 'https://www.google.com/accounts/OAuthGetRequestToken'
88
+ client.authorization.authorization_uri.to_s.should include(
89
+ 'https://www.google.com/accounts/OAuthAuthorizeToken'
90
+ )
91
+ client.authorization.token_credential_uri.to_s.should ==
92
+ 'https://www.google.com/accounts/OAuthGetAccessToken'
93
+ client.authorization.client_credential_key.should == 'anonymous'
94
+ client.authorization.client_credential_secret.should == 'anonymous'
95
+ end
96
+
97
+ it_should_behave_like 'configurable user agent'
98
+ end
99
+
100
+ describe 'configured for OAuth 2' do
101
+ before do
102
+ client.authorization = :oauth_2
103
+ client.authorization.access_token = '12345'
104
+ end
105
+
106
+ # TODO
107
+ it_should_behave_like 'configurable user agent'
108
+ end
109
+
110
+ describe 'when executing requests' do
111
+ before do
112
+ @prediction = client.discovered_api('prediction', 'v1.2')
113
+ client.authorization = :oauth_2
114
+ @connection = stub_connection do |stub|
115
+ stub.post('/prediction/v1.2/training?data=12345') do |env|
116
+ env[:request_headers]['Authorization'].should == 'Bearer 12345'
117
+ [200, {}, '{}']
118
+ end
119
+ end
120
+ end
121
+
122
+ after do
123
+ @connection.verify
124
+ end
125
+
126
+ it 'should use default authorization' do
127
+ client.authorization.access_token = "12345"
128
+ client.execute(
129
+ :api_method => @prediction.training.insert,
130
+ :parameters => {'data' => '12345'},
131
+ :connection => @connection
132
+ )
133
+ end
134
+
135
+ it 'should use request scoped authorization when provided' do
136
+ client.authorization.access_token = "abcdef"
137
+ new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
138
+ client.execute(
139
+ :api_method => @prediction.training.insert,
140
+ :parameters => {'data' => '12345'},
141
+ :authorization => new_auth,
142
+ :connection => @connection
143
+ )
144
+ end
145
+
146
+ it 'should accept options with batch/request style execute' do
147
+ client.authorization.access_token = "abcdef"
148
+ new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
149
+ request = client.generate_request(
150
+ :api_method => @prediction.training.insert,
151
+ :parameters => {'data' => '12345'}
152
+ )
153
+ client.execute(
154
+ request,
155
+ :authorization => new_auth,
156
+ :connection => @connection
157
+ )
158
+ end
159
+
160
+
161
+ it 'should accept options in array style execute' do
162
+ client.authorization.access_token = "abcdef"
163
+ new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
164
+ client.execute(
165
+ @prediction.training.insert, {'data' => '12345'}, '', {},
166
+ { :authorization => new_auth, :connection => @connection }
167
+ )
168
+ end
169
+ end
170
+
171
+ describe 'when retiries enabled' do
172
+ before do
173
+ client.retries = 2
174
+ end
175
+
176
+ after do
177
+ @connection.verify
178
+ end
179
+
180
+ it 'should follow redirects' do
181
+ client.authorization = nil
182
+ @connection = stub_connection do |stub|
183
+ stub.get('/foo') do |env|
184
+ [302, {'location' => 'https://www.google.com/bar'}, '{}']
185
+ end
186
+ stub.get('/bar') do |env|
187
+ [200, {}, '{}']
188
+ end
189
+ end
190
+
191
+ client.execute(
192
+ :uri => 'https://www.gogole.com/foo',
193
+ :connection => @connection
194
+ )
195
+ end
196
+
197
+ it 'should refresh tokens on 401 tokens' do
198
+ client.authorization.access_token = '12345'
199
+ expect(client.authorization).to receive(:fetch_access_token!)
200
+
201
+ @connection = stub_connection do |stub|
202
+ stub.get('/foo') do |env|
203
+ [401, {}, '{}']
204
+ end
205
+ stub.get('/foo') do |env|
206
+ [200, {}, '{}']
207
+ end
208
+ end
209
+
210
+ client.execute(
211
+ :uri => 'https://www.gogole.com/foo',
212
+ :connection => @connection
213
+ )
214
+ end
215
+
216
+ it 'should retry on 500 errors' do
217
+ client.authorization = nil
218
+
219
+ @connection = stub_connection do |stub|
220
+ stub.get('/foo') do |env|
221
+ [500, {}, '{}']
222
+ end
223
+ stub.get('/foo') do |env|
224
+ [200, {}, '{}']
225
+ end
226
+ end
227
+
228
+ client.execute(
229
+ :uri => 'https://www.gogole.com/foo',
230
+ :connection => @connection
231
+ ).status.should == 200
232
+
233
+ end
234
+
235
+ it 'should fail after max retries' do
236
+ client.authorization = nil
237
+ count = 0
238
+ @connection = stub_connection do |stub|
239
+ stub.get('/foo') do |env|
240
+ count += 1
241
+ [500, {}, '{}']
242
+ end
243
+ end
244
+
245
+ client.execute(
246
+ :uri => 'https://www.gogole.com/foo',
247
+ :connection => @connection
248
+ ).status.should == 500
249
+ count.should == 3
250
+ end
251
+
252
+ end
253
+ end
@@ -0,0 +1,56 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ $LOAD_PATH.uniq!
3
+
4
+ require 'rspec'
5
+ require 'faraday'
6
+
7
+ Faraday::Adapter.load_middleware(:test)
8
+
9
+ module Faraday
10
+ class Connection
11
+ def verify
12
+ if app.kind_of?(Faraday::Adapter::Test)
13
+ app.stubs.verify_stubbed_calls
14
+ else
15
+ raise TypeError, "Expected test adapter"
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ module ConnectionHelpers
22
+ def stub_connection(&block)
23
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
24
+ block.call(stub)
25
+ end
26
+ connection = Faraday.new do |builder|
27
+ builder.options.params_encoder = Faraday::FlatParamsEncoder
28
+ builder.adapter(:test, stubs)
29
+ end
30
+ end
31
+ end
32
+
33
+ module JSONMatchers
34
+ class EqualsJson
35
+ def initialize(expected)
36
+ @expected = JSON.parse(expected)
37
+ end
38
+ def matches?(target)
39
+ @target = JSON.parse(target)
40
+ @target.eql?(@expected)
41
+ end
42
+ def failure_message
43
+ "expected #{@target.inspect} to be #{@expected}"
44
+ end
45
+ def negative_failure_message
46
+ "expected #{@target.inspect} not to be #{@expected}"
47
+ end
48
+ end
49
+
50
+ def be_json(expected)
51
+ EqualsJson.new(expected)
52
+ end
53
+ end
54
+
55
+ RSpec.configure do |config|
56
+ end
@@ -0,0 +1,97 @@
1
+ require 'rubygems/package_task'
2
+ require 'rake/clean'
3
+
4
+ CLOBBER.include('pkg')
5
+
6
+ namespace :gem do
7
+ GEM_SPEC = Gem::Specification.new do |s|
8
+ unless s.respond_to?(:add_development_dependency)
9
+ puts 'The gem spec requires a newer version of RubyGems.'
10
+ exit(1)
11
+ end
12
+
13
+ s.name = PKG_NAME
14
+ s.version = PKG_VERSION
15
+ s.author = PKG_AUTHOR
16
+ s.email = PKG_AUTHOR_EMAIL
17
+ s.summary = PKG_SUMMARY
18
+ s.description = PKG_DESCRIPTION
19
+ s.license = 'Apache 2.0'
20
+ s.files = PKG_FILES.to_a
21
+
22
+ s.extra_rdoc_files = %w( README.md )
23
+ s.rdoc_options.concat ['--main', 'README.md']
24
+
25
+ # Dependencies used in the main library
26
+ s.add_runtime_dependency('signet', '>= 0.5.0')
27
+ s.add_runtime_dependency('addressable', '>= 2.3.2')
28
+ s.add_runtime_dependency('uuidtools', '>= 2.1.0')
29
+ s.add_runtime_dependency('autoparse', '>= 0.3.3')
30
+ s.add_runtime_dependency('faraday', '>= 0.9.0')
31
+ s.add_runtime_dependency('multi_json', '>= 1.0.0')
32
+ s.add_runtime_dependency('extlib', '>= 0.9.15')
33
+ s.add_runtime_dependency('jwt', '>= 0.1.5')
34
+ s.add_runtime_dependency('retriable', '>= 1.4')
35
+ # Dependencies used in the CLI
36
+ s.add_runtime_dependency('launchy', '>= 2.1.1')
37
+
38
+ # Dependencies used in the examples
39
+ s.add_development_dependency('rake', '>= 0.9.0')
40
+ s.add_development_dependency('rspec', '>= 2.11.0')
41
+
42
+ s.require_path = 'lib'
43
+
44
+ s.homepage = PKG_HOMEPAGE
45
+ end
46
+
47
+ Gem::PackageTask.new(GEM_SPEC) do |p|
48
+ p.gem_spec = GEM_SPEC
49
+ p.need_tar = true
50
+ p.need_zip = true
51
+ end
52
+
53
+ desc 'Show information about the gem'
54
+ task :debug do
55
+ puts GEM_SPEC.to_ruby
56
+ end
57
+
58
+ desc "Generates .gemspec file"
59
+ task :gemspec do
60
+ spec_string = GEM_SPEC.to_ruby
61
+
62
+ begin
63
+ Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
64
+ rescue
65
+ abort "unsafe gemspec: #{$!}"
66
+ else
67
+ File.open("#{GEM_SPEC.name}.gemspec", 'w') do |file|
68
+ file.write spec_string
69
+ end
70
+ end
71
+ end
72
+
73
+ desc 'Install the gem'
74
+ task :install => ['clobber', 'gem:package'] do
75
+ sh "#{SUDO} gem install --local pkg/#{GEM_SPEC.full_name}"
76
+ end
77
+
78
+ desc 'Uninstall the gem'
79
+ task :uninstall do
80
+ installed_list = Gem.source_index.find_name(PKG_NAME)
81
+ if installed_list &&
82
+ (installed_list.collect { |s| s.version.to_s}.include?(PKG_VERSION))
83
+ sh(
84
+ "#{SUDO} gem uninstall --version '#{PKG_VERSION}' " +
85
+ "--ignore-dependencies --executables #{PKG_NAME}"
86
+ )
87
+ end
88
+ end
89
+
90
+ desc 'Reinstall the gem'
91
+ task :reinstall => [:uninstall, :install]
92
+ end
93
+
94
+ desc 'Alias to gem:package'
95
+ task 'gem' => 'gem:package'
96
+
97
+ task 'gem:release' => 'gem:gemspec'