cure-google-api-client 0.8.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +178 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +202 -0
  5. data/README.md +218 -0
  6. data/Rakefile +41 -0
  7. data/google-api-client.gemspec +43 -0
  8. data/lib/cacerts.pem +2183 -0
  9. data/lib/compat/multi_json.rb +19 -0
  10. data/lib/google/api_client.rb +750 -0
  11. data/lib/google/api_client/auth/compute_service_account.rb +28 -0
  12. data/lib/google/api_client/auth/file_storage.rb +59 -0
  13. data/lib/google/api_client/auth/installed_app.rb +126 -0
  14. data/lib/google/api_client/auth/jwt_asserter.rb +126 -0
  15. data/lib/google/api_client/auth/key_utils.rb +93 -0
  16. data/lib/google/api_client/auth/pkcs12.rb +41 -0
  17. data/lib/google/api_client/auth/storage.rb +102 -0
  18. data/lib/google/api_client/auth/storages/file_store.rb +58 -0
  19. data/lib/google/api_client/auth/storages/redis_store.rb +54 -0
  20. data/lib/google/api_client/batch.rb +326 -0
  21. data/lib/google/api_client/charset.rb +33 -0
  22. data/lib/google/api_client/client_secrets.rb +179 -0
  23. data/lib/google/api_client/discovery.rb +19 -0
  24. data/lib/google/api_client/discovery/api.rb +310 -0
  25. data/lib/google/api_client/discovery/media.rb +77 -0
  26. data/lib/google/api_client/discovery/method.rb +363 -0
  27. data/lib/google/api_client/discovery/resource.rb +156 -0
  28. data/lib/google/api_client/discovery/schema.rb +117 -0
  29. data/lib/google/api_client/environment.rb +42 -0
  30. data/lib/google/api_client/errors.rb +65 -0
  31. data/lib/google/api_client/gzip.rb +28 -0
  32. data/lib/google/api_client/logging.rb +32 -0
  33. data/lib/google/api_client/media.rb +259 -0
  34. data/lib/google/api_client/railtie.rb +18 -0
  35. data/lib/google/api_client/reference.rb +27 -0
  36. data/lib/google/api_client/request.rb +350 -0
  37. data/lib/google/api_client/result.rb +255 -0
  38. data/lib/google/api_client/service.rb +233 -0
  39. data/lib/google/api_client/service/batch.rb +110 -0
  40. data/lib/google/api_client/service/request.rb +144 -0
  41. data/lib/google/api_client/service/resource.rb +40 -0
  42. data/lib/google/api_client/service/result.rb +162 -0
  43. data/lib/google/api_client/service/simple_file_store.rb +151 -0
  44. data/lib/google/api_client/service/stub_generator.rb +61 -0
  45. data/lib/google/api_client/service_account.rb +21 -0
  46. data/lib/google/api_client/version.rb +26 -0
  47. data/spec/google/api_client/auth/storage_spec.rb +122 -0
  48. data/spec/google/api_client/auth/storages/file_store_spec.rb +40 -0
  49. data/spec/google/api_client/auth/storages/redis_store_spec.rb +70 -0
  50. data/spec/google/api_client/batch_spec.rb +248 -0
  51. data/spec/google/api_client/client_secrets_spec.rb +53 -0
  52. data/spec/google/api_client/discovery_spec.rb +708 -0
  53. data/spec/google/api_client/gzip_spec.rb +98 -0
  54. data/spec/google/api_client/media_spec.rb +178 -0
  55. data/spec/google/api_client/request_spec.rb +29 -0
  56. data/spec/google/api_client/result_spec.rb +207 -0
  57. data/spec/google/api_client/service_account_spec.rb +169 -0
  58. data/spec/google/api_client/service_spec.rb +618 -0
  59. data/spec/google/api_client/simple_file_store_spec.rb +133 -0
  60. data/spec/google/api_client_spec.rb +352 -0
  61. data/spec/spec_helper.rb +66 -0
  62. metadata +339 -0
@@ -0,0 +1,98 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2012 Google Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'spec_helper'
17
+
18
+ require 'google/api_client'
19
+
20
+ RSpec.describe Google::APIClient::Gzip do
21
+
22
+ def create_connection(&block)
23
+ Faraday.new do |b|
24
+ b.response :charset
25
+ b.response :gzip
26
+ b.adapter :test do |stub|
27
+ stub.get '/', &block
28
+ end
29
+ end
30
+ end
31
+
32
+ it 'should ignore non-zipped content' do
33
+ conn = create_connection do |env|
34
+ [200, {}, 'Hello world']
35
+ end
36
+ result = conn.get('/')
37
+ expect(result.body).to eq("Hello world")
38
+ end
39
+
40
+ it 'should decompress gziped content' do
41
+ conn = create_connection do |env|
42
+ [200, { 'Content-Encoding' => 'gzip'}, Base64.decode64('H4sICLVGwlEAA3RtcADzSM3JyVcozy/KSeECANXgObcMAAAA')]
43
+ end
44
+ result = conn.get('/')
45
+ expect(result.body).to eq("Hello world\n")
46
+ end
47
+
48
+ it 'should inflate with the correct charset encoding' do
49
+ conn = create_connection do |env|
50
+ [200,
51
+ { 'Content-Encoding' => 'deflate', 'Content-Type' => 'application/json;charset=BIG5'},
52
+ Base64.decode64('eJxb8nLp7t2VAA8fBCI=')]
53
+ end
54
+ result = conn.get('/')
55
+ expect(result.body.encoding).to eq(Encoding::BIG5)
56
+ expect(result.body).to eq('日本語'.encode("BIG5"))
57
+ end
58
+
59
+ describe 'with API Client' do
60
+
61
+ before do
62
+ @client = Google::APIClient.new(:application_name => 'test')
63
+ @client.authorization = nil
64
+ end
65
+
66
+
67
+ it 'should send gzip in user agent' do
68
+ conn = create_connection do |env|
69
+ agent = env[:request_headers]['User-Agent']
70
+ expect(agent).not_to be_nil
71
+ expect(agent).to include 'gzip'
72
+ [200, {}, 'Hello world']
73
+ end
74
+ @client.execute(:uri => 'http://www.example.com/', :connection => conn)
75
+ end
76
+
77
+ it 'should send gzip in accept-encoding' do
78
+ conn = create_connection do |env|
79
+ encoding = env[:request_headers]['Accept-Encoding']
80
+ expect(encoding).not_to be_nil
81
+ expect(encoding).to include 'gzip'
82
+ [200, {}, 'Hello world']
83
+ end
84
+ @client.execute(:uri => 'http://www.example.com/', :connection => conn)
85
+ end
86
+
87
+ it 'should not send gzip in accept-encoding if disabled for request' do
88
+ conn = create_connection do |env|
89
+ encoding = env[:request_headers]['Accept-Encoding']
90
+ expect(encoding).not_to include('gzip') unless encoding.nil?
91
+ [200, {}, 'Hello world']
92
+ end
93
+ response = @client.execute(:uri => 'http://www.example.com/', :gzip => false, :connection => conn)
94
+ puts response.status
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,178 @@
1
+ # Copyright 2012 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 'google/api_client'
18
+
19
+ fixtures_path = File.expand_path('../../../fixtures', __FILE__)
20
+
21
+ RSpec.describe Google::APIClient::UploadIO do
22
+ it 'should reject invalid file paths' do
23
+ expect(lambda do
24
+ media = Google::APIClient::UploadIO.new('doesnotexist', 'text/plain')
25
+ end).to raise_error
26
+ end
27
+
28
+ describe 'with a file' do
29
+ before do
30
+ @file = File.expand_path('files/sample.txt', fixtures_path)
31
+ @media = Google::APIClient::UploadIO.new(@file, 'text/plain')
32
+ end
33
+
34
+ it 'should report the correct file length' do
35
+ expect(@media.length).to eq(File.size(@file))
36
+ end
37
+
38
+ it 'should have a mime type' do
39
+ expect(@media.content_type).to eq('text/plain')
40
+ end
41
+ end
42
+
43
+ describe 'with StringIO' do
44
+ before do
45
+ @content = "hello world"
46
+ @media = Google::APIClient::UploadIO.new(StringIO.new(@content), 'text/plain', 'test.txt')
47
+ end
48
+
49
+ it 'should report the correct file length' do
50
+ expect(@media.length).to eq(@content.length)
51
+ end
52
+
53
+ it 'should have a mime type' do
54
+ expect(@media.content_type).to eq('text/plain')
55
+ end
56
+ end
57
+ end
58
+
59
+ RSpec.describe Google::APIClient::RangedIO do
60
+ before do
61
+ @source = StringIO.new("1234567890abcdef")
62
+ @io = Google::APIClient::RangedIO.new(@source, 1, 5)
63
+ end
64
+
65
+ it 'should return the correct range when read entirely' do
66
+ expect(@io.read).to eq("23456")
67
+ end
68
+
69
+ it 'should maintain position' do
70
+ expect(@io.read(1)).to eq('2')
71
+ expect(@io.read(2)).to eq('34')
72
+ expect(@io.read(2)).to eq('56')
73
+ end
74
+
75
+ it 'should allow rewinds' do
76
+ expect(@io.read(2)).to eq('23')
77
+ @io.rewind()
78
+ expect(@io.read(2)).to eq('23')
79
+ end
80
+
81
+ it 'should allow setting position' do
82
+ @io.pos = 3
83
+ expect(@io.read).to eq('56')
84
+ end
85
+
86
+ it 'should not allow position to be set beyond range' do
87
+ @io.pos = 10
88
+ expect(@io.read).to eq('')
89
+ end
90
+
91
+ it 'should return empty string when read amount is zero' do
92
+ expect(@io.read(0)).to eq('')
93
+ end
94
+
95
+ it 'should return empty string at EOF if amount is nil' do
96
+ @io.read
97
+ expect(@io.read).to eq('')
98
+ end
99
+
100
+ it 'should return nil at EOF if amount is positive int' do
101
+ @io.read
102
+ expect(@io.read(1)).to eq(nil)
103
+ end
104
+
105
+ end
106
+
107
+ RSpec.describe Google::APIClient::ResumableUpload do
108
+ CLIENT = Google::APIClient.new(:application_name => 'API Client Tests') unless defined?(CLIENT)
109
+
110
+ after do
111
+ # Reset client to not-quite-pristine state
112
+ CLIENT.key = nil
113
+ CLIENT.user_ip = nil
114
+ end
115
+
116
+ before do
117
+ @drive = CLIENT.discovered_api('drive', 'v2')
118
+ @file = File.expand_path('files/sample.txt', fixtures_path)
119
+ @media = Google::APIClient::UploadIO.new(@file, 'text/plain')
120
+ @uploader = Google::APIClient::ResumableUpload.new(
121
+ :media => @media,
122
+ :api_method => @drive.files.insert,
123
+ :uri => 'https://www.googleapis.com/upload/drive/v1/files/12345')
124
+ end
125
+
126
+ it 'should consider 20x status as complete' do
127
+ request = @uploader.to_http_request
128
+ @uploader.process_http_response(mock_result(200))
129
+ expect(@uploader.complete?).to eq(true)
130
+ end
131
+
132
+ it 'should consider 30x status as incomplete' do
133
+ request = @uploader.to_http_request
134
+ @uploader.process_http_response(mock_result(308))
135
+ expect(@uploader.complete?).to eq(false)
136
+ expect(@uploader.expired?).to eq(false)
137
+ end
138
+
139
+ it 'should consider 40x status as fatal' do
140
+ request = @uploader.to_http_request
141
+ @uploader.process_http_response(mock_result(404))
142
+ expect(@uploader.expired?).to eq(true)
143
+ end
144
+
145
+ it 'should detect changes to location' do
146
+ request = @uploader.to_http_request
147
+ @uploader.process_http_response(mock_result(308, 'location' => 'https://www.googleapis.com/upload/drive/v1/files/abcdef'))
148
+ expect(@uploader.uri.to_s).to eq('https://www.googleapis.com/upload/drive/v1/files/abcdef')
149
+ end
150
+
151
+ it 'should resume from the saved range reported by the server' do
152
+ @uploader.chunk_size = 200
153
+ @uploader.to_http_request # Send bytes 0-199, only 0-99 saved
154
+ @uploader.process_http_response(mock_result(308, 'range' => '0-99'))
155
+ method, url, headers, body = @uploader.to_http_request # Send bytes 100-299
156
+ expect(headers['Content-Range']).to eq("bytes 100-299/#{@media.length}")
157
+ expect(headers['Content-length']).to eq("200")
158
+ end
159
+
160
+ it 'should resync the offset after 5xx errors' do
161
+ @uploader.chunk_size = 200
162
+ @uploader.to_http_request
163
+ @uploader.process_http_response(mock_result(500)) # Invalidates range
164
+ method, url, headers, body = @uploader.to_http_request # Resync
165
+ expect(headers['Content-Range']).to eq("bytes */#{@media.length}")
166
+ expect(headers['Content-length']).to eq("0")
167
+ @uploader.process_http_response(mock_result(308, 'range' => '0-99'))
168
+ method, url, headers, body = @uploader.to_http_request # Send next chunk at correct range
169
+ expect(headers['Content-Range']).to eq("bytes 100-299/#{@media.length}")
170
+ expect(headers['Content-length']).to eq("200")
171
+ end
172
+
173
+ def mock_result(status, headers = {})
174
+ reference = Google::APIClient::Reference.new(:api_method => @drive.files.insert)
175
+ double('result', :status => status, :headers => headers, :reference => reference)
176
+ end
177
+
178
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2012 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 'google/api_client'
18
+
19
+ RSpec.describe Google::APIClient::Request do
20
+ CLIENT = Google::APIClient.new(:application_name => 'API Client Tests') unless defined?(CLIENT)
21
+
22
+ it 'should normalize parameter names to strings' do
23
+ request = Google::APIClient::Request.new(:uri => 'https://www.google.com', :parameters => {
24
+ :a => '1', 'b' => '2'
25
+ })
26
+ expect(request.parameters['a']).to eq('1')
27
+ expect(request.parameters['b']).to eq('2')
28
+ end
29
+ end
@@ -0,0 +1,207 @@
1
+ # Copyright 2012 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 'google/api_client'
18
+
19
+ RSpec.describe Google::APIClient::Result do
20
+ CLIENT = Google::APIClient.new(:application_name => 'API Client Tests') unless defined?(CLIENT)
21
+
22
+ describe 'with the plus API' do
23
+ before do
24
+ CLIENT.authorization = nil
25
+ @plus = CLIENT.discovered_api('plus', 'v1')
26
+ @reference = Google::APIClient::Reference.new({
27
+ :api_method => @plus.activities.list,
28
+ :parameters => {
29
+ 'userId' => 'me',
30
+ 'collection' => 'public',
31
+ 'maxResults' => 20
32
+ }
33
+ })
34
+ @request = @reference.to_http_request
35
+
36
+ # Response double
37
+ @response = double("response")
38
+ allow(@response).to receive(:status).and_return(200)
39
+ allow(@response).to receive(:headers).and_return({
40
+ 'etag' => '12345',
41
+ 'x-google-apiary-auth-scopes' =>
42
+ 'https://www.googleapis.com/auth/plus.me',
43
+ 'content-type' => 'application/json; charset=UTF-8',
44
+ 'date' => 'Mon, 23 Apr 2012 00:00:00 GMT',
45
+ 'cache-control' => 'private, max-age=0, must-revalidate, no-transform',
46
+ 'server' => 'GSE',
47
+ 'connection' => 'close'
48
+ })
49
+ end
50
+
51
+ describe 'with a next page token' do
52
+ before do
53
+ allow(@response).to receive(:body).and_return(
54
+ <<-END_OF_STRING
55
+ {
56
+ "kind": "plus#activityFeed",
57
+ "etag": "FOO",
58
+ "nextPageToken": "NEXT+PAGE+TOKEN",
59
+ "selfLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?",
60
+ "nextLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?maxResults=20&pageToken=NEXT%2BPAGE%2BTOKEN",
61
+ "title": "Plus Public Activity Feed for ",
62
+ "updated": "2012-04-23T00:00:00.000Z",
63
+ "id": "123456790",
64
+ "items": []
65
+ }
66
+ END_OF_STRING
67
+ )
68
+ @result = Google::APIClient::Result.new(@reference, @response)
69
+ end
70
+
71
+ it 'should indicate a successful response' do
72
+ expect(@result.error?).to be_falsey
73
+ end
74
+
75
+ it 'should return the correct next page token' do
76
+ expect(@result.next_page_token).to eq('NEXT+PAGE+TOKEN')
77
+ end
78
+
79
+ it 'should escape the next page token when calling next_page' do
80
+ reference = @result.next_page
81
+ expect(Hash[reference.parameters]).to include('pageToken')
82
+ expect(Hash[reference.parameters]['pageToken']).to eq('NEXT+PAGE+TOKEN')
83
+ url = reference.to_env(CLIENT.connection)[:url]
84
+ expect(url.to_s).to include('pageToken=NEXT%2BPAGE%2BTOKEN')
85
+ end
86
+
87
+ it 'should return content type correctly' do
88
+ expect(@result.media_type).to eq('application/json')
89
+ end
90
+
91
+ it 'should return the result data correctly' do
92
+ expect(@result.data?).to be_truthy
93
+ expect(@result.data.class.to_s).to eq(
94
+ 'Google::APIClient::Schema::Plus::V1::ActivityFeed'
95
+ )
96
+ expect(@result.data.kind).to eq('plus#activityFeed')
97
+ expect(@result.data.etag).to eq('FOO')
98
+ expect(@result.data.nextPageToken).to eq('NEXT+PAGE+TOKEN')
99
+ expect(@result.data.selfLink).to eq(
100
+ 'https://www.googleapis.com/plus/v1/people/foo/activities/public?'
101
+ )
102
+ expect(@result.data.nextLink).to eq(
103
+ 'https://www.googleapis.com/plus/v1/people/foo/activities/public?' +
104
+ 'maxResults=20&pageToken=NEXT%2BPAGE%2BTOKEN'
105
+ )
106
+ expect(@result.data.title).to eq('Plus Public Activity Feed for ')
107
+ expect(@result.data.id).to eq("123456790")
108
+ expect(@result.data.items).to be_empty
109
+ end
110
+ end
111
+
112
+ describe 'without a next page token' do
113
+ before do
114
+ allow(@response).to receive(:body).and_return(
115
+ <<-END_OF_STRING
116
+ {
117
+ "kind": "plus#activityFeed",
118
+ "etag": "FOO",
119
+ "selfLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?",
120
+ "title": "Plus Public Activity Feed for ",
121
+ "updated": "2012-04-23T00:00:00.000Z",
122
+ "id": "123456790",
123
+ "items": []
124
+ }
125
+ END_OF_STRING
126
+ )
127
+ @result = Google::APIClient::Result.new(@reference, @response)
128
+ end
129
+
130
+ it 'should not return a next page token' do
131
+ expect(@result.next_page_token).to eq(nil)
132
+ end
133
+
134
+ it 'should return content type correctly' do
135
+ expect(@result.media_type).to eq('application/json')
136
+ end
137
+
138
+ it 'should return the result data correctly' do
139
+ expect(@result.data?).to be_truthy
140
+ expect(@result.data.class.to_s).to eq(
141
+ 'Google::APIClient::Schema::Plus::V1::ActivityFeed'
142
+ )
143
+ expect(@result.data.kind).to eq('plus#activityFeed')
144
+ expect(@result.data.etag).to eq('FOO')
145
+ expect(@result.data.selfLink).to eq(
146
+ 'https://www.googleapis.com/plus/v1/people/foo/activities/public?'
147
+ )
148
+ expect(@result.data.title).to eq('Plus Public Activity Feed for ')
149
+ expect(@result.data.id).to eq("123456790")
150
+ expect(@result.data.items).to be_empty
151
+ end
152
+ end
153
+
154
+ describe 'with JSON error response' do
155
+ before do
156
+ allow(@response).to receive(:body).and_return(
157
+ <<-END_OF_STRING
158
+ {
159
+ "error": {
160
+ "errors": [
161
+ {
162
+ "domain": "global",
163
+ "reason": "parseError",
164
+ "message": "Parse Error"
165
+ }
166
+ ],
167
+ "code": 400,
168
+ "message": "Parse Error"
169
+ }
170
+ }
171
+ END_OF_STRING
172
+ )
173
+ allow(@response).to receive(:status).and_return(400)
174
+ @result = Google::APIClient::Result.new(@reference, @response)
175
+ end
176
+
177
+ it 'should return error status correctly' do
178
+ expect(@result.error?).to be_truthy
179
+ end
180
+
181
+ it 'should return the correct error message' do
182
+ expect(@result.error_message).to eq('Parse Error')
183
+ end
184
+ end
185
+
186
+ describe 'with 204 No Content response' do
187
+ before do
188
+ allow(@response).to receive(:body).and_return('')
189
+ allow(@response).to receive(:status).and_return(204)
190
+ allow(@response).to receive(:headers).and_return({})
191
+ @result = Google::APIClient::Result.new(@reference, @response)
192
+ end
193
+
194
+ it 'should indicate no data is available' do
195
+ expect(@result.data?).to be_falsey
196
+ end
197
+
198
+ it 'should return nil for data' do
199
+ expect(@result.data).to eq(nil)
200
+ end
201
+
202
+ it 'should return nil for media_type' do
203
+ expect(@result.media_type).to eq(nil)
204
+ end
205
+ end
206
+ end
207
+ end