Import refactored library. See MIGRATING.MD for details
This commit is contained in:
1 parent
9b7809174d
commit
f584a2cec8
373 files changed
+255715
-474
No files matched your search
@@ -0,0 +1,170 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/core/api_command'
|
||||
require 'google/apis/core/json_representation'
|
||||
require 'hurley/test'
|
||||
|
||||
RSpec.describe Google::Apis::Core::HttpCommand do
|
||||
include TestHelpers
|
||||
include_context 'HTTP client'
|
||||
|
||||
let(:model_class) do
|
||||
Class.new do
|
||||
attr_accessor :value
|
||||
end
|
||||
end
|
||||
|
||||
let(:representer_class) do
|
||||
Class.new(Google::Apis::Core::JsonRepresentation) do
|
||||
property :value
|
||||
end
|
||||
end
|
||||
|
||||
context('with a request body') do
|
||||
let(:command) do
|
||||
request = model_class.new
|
||||
request.value = 'hello'
|
||||
command = Google::Apis::Core::ApiCommand.new(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
command.request_representation = representer_class
|
||||
command.request_object = request
|
||||
command
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(headers: { 'Content-Type' => 'application/json' }, body: %({}))
|
||||
end
|
||||
|
||||
it 'should serialize the request object' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals').with do |req|
|
||||
be_json_eql(%({"value":"hello"})).matches?(req.body)
|
||||
end).to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
context('with a JSON response') do
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::ApiCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
command.response_representation = representer_class
|
||||
command.response_class = model_class
|
||||
command
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(headers: { 'Content-Type' => 'application/json' }, body: %({"value" : "hello"}))
|
||||
end
|
||||
|
||||
it 'should return a model instance' do
|
||||
result = command.execute(client)
|
||||
expect(result).to be_kind_of(model_class)
|
||||
end
|
||||
|
||||
it 'should return a populated object' do
|
||||
result = command.execute(client)
|
||||
expect(result.value).to eql 'hello'
|
||||
end
|
||||
end
|
||||
|
||||
context('with an invalid content-type response') do
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::ApiCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
command.response_representation = representer_class
|
||||
command.response_class = model_class
|
||||
command
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(headers: { 'Content-Type' => 'text/plain' }, body: %(Ignore me))
|
||||
end
|
||||
|
||||
it 'should return nil' do
|
||||
result = command.execute(client)
|
||||
expect(result).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
context('with a field parameter') do
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::ApiCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
command.query['fields'] = ':items(:id, :long_name)'
|
||||
command
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, /.*/)
|
||||
.to_return(headers: { 'Content-Type' => 'application/json' }, body: %({}))
|
||||
end
|
||||
|
||||
it 'should normalize fields params' do
|
||||
command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.with(query: { 'fields' => 'items(id, longName)' })) .to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
context('with a rate limit response') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::ApiCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
json = <<EOF
|
||||
{
|
||||
"error": {
|
||||
"errors": [
|
||||
{
|
||||
"domain": "global",
|
||||
"reason": "rateLimitExceeded",
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
],
|
||||
"code": 403,
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [403, 'Rate Limit Exceeded'], headers: { 'Content-Type' => 'application/json' }, body: json)
|
||||
.to_return(headers: { 'Content-Type' => 'application/json' }, body: %({}))
|
||||
end
|
||||
|
||||
it 'should retry' do
|
||||
command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')).to have_been_made.times(2)
|
||||
end
|
||||
end
|
||||
|
||||
context('with an empty error body') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::ApiCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
json = %({})
|
||||
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [403, 'Rate Limit Exceeded'], headers: { 'Content-Type' => 'application/json' }, body: json)
|
||||
end
|
||||
|
||||
it 'should raise client error' do
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::ClientError)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,128 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/core/batch'
|
||||
require 'google/apis/core/json_representation'
|
||||
require 'hurley/test'
|
||||
|
||||
RSpec.describe Google::Apis::Core::BatchCommand do
|
||||
include TestHelpers
|
||||
include_context 'HTTP client'
|
||||
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::BatchCommand.new(:post, 'https://www.googleapis.com/batch')
|
||||
end
|
||||
|
||||
let(:get_command) { Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals/1') }
|
||||
|
||||
let(:post_with_string_command) do
|
||||
command = Google::Apis::Core::HttpCommand.new(:post, 'https://www.googleapis.com/zoo/animals/2')
|
||||
command.body = 'Hello world'
|
||||
command.header[:content_type] = 'text/plain'
|
||||
command
|
||||
end
|
||||
|
||||
let(:post_with_io_command) do
|
||||
command = Google::Apis::Core::HttpCommand.new(:post, 'https://www.googleapis.com/zoo/animals/3')
|
||||
command.body = StringIO.new('Goodbye!')
|
||||
command.header[:content_type] = 'text/plain'
|
||||
command
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
response = <<EOF
|
||||
--batch123
|
||||
Content-Type: application/http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
Hello
|
||||
--batch123
|
||||
Content-Type: application/http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
world
|
||||
--batch123
|
||||
Content-Type: application/http
|
||||
|
||||
HTTP/1.1 500 Server Error
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
Error!
|
||||
--batch123--
|
||||
EOF
|
||||
stub_request(:post, 'https://www.googleapis.com/batch')
|
||||
.to_return(headers: { 'Content-Type' => 'multipart/mixed; boundary=batch123' }, body: response)
|
||||
end
|
||||
|
||||
it 'should send content' do
|
||||
b = ->(_res, _err) {}
|
||||
command.add(get_command, &b)
|
||||
command.add(post_with_string_command, &b)
|
||||
command.add(post_with_io_command, &b)
|
||||
command.execute(client)
|
||||
|
||||
expected_body = <<EOF.gsub(/\n/, "\r\n")
|
||||
--RubyApiBatchRequest
|
||||
Content-Length: 58
|
||||
Content-Type: application/http
|
||||
Content-Transfer-Encoding: binary
|
||||
|
||||
GET /zoo/animals/1? HTTP/1.1
|
||||
Host: www.googleapis.com
|
||||
|
||||
|
||||
--RubyApiBatchRequest
|
||||
Content-Length: 96
|
||||
Content-Type: application/http
|
||||
Content-Transfer-Encoding: binary
|
||||
|
||||
POST /zoo/animals/2? HTTP/1.1
|
||||
Content-Type: text/plain
|
||||
Host: www.googleapis.com
|
||||
|
||||
Hello world
|
||||
--RubyApiBatchRequest
|
||||
Content-Length: 93
|
||||
Content-Type: application/http
|
||||
Content-Transfer-Encoding: binary
|
||||
|
||||
POST /zoo/animals/3? HTTP/1.1
|
||||
Content-Type: text/plain
|
||||
Host: www.googleapis.com
|
||||
|
||||
Goodbye!
|
||||
--RubyApiBatchRequest--
|
||||
|
||||
EOF
|
||||
expect(a_request(:post, 'https://www.googleapis.com/batch').with(body: expected_body)).to have_been_made
|
||||
end
|
||||
|
||||
it 'should send decode responses' do
|
||||
expect do |b|
|
||||
command.add(get_command, &b)
|
||||
command.add(post_with_string_command, &b)
|
||||
command.add(post_with_io_command, &b)
|
||||
command.execute(client)
|
||||
end.to yield_successive_args(['Hello', nil], ['world', nil], [nil, an_instance_of(Google::Apis::ServerError)])
|
||||
end
|
||||
|
||||
it 'should raise error if batch is empty' do
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::BatchError)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,90 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/core/download'
|
||||
require 'google/apis/core/json_representation'
|
||||
require 'hurley/test'
|
||||
require 'tempfile'
|
||||
require 'tmpdir'
|
||||
|
||||
RSpec.describe Google::Apis::Core::DownloadCommand do
|
||||
include TestHelpers
|
||||
include_context 'HTTP client'
|
||||
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::DownloadCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
command.download_dest = dest
|
||||
command
|
||||
end
|
||||
|
||||
shared_examples 'should download' do
|
||||
context 'with successful response' do
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(headers: { 'Content-Type' => 'application/json' }, body: %(Hello world))
|
||||
end
|
||||
|
||||
it 'should not include a range header' do
|
||||
command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| !req.headers.key?('Range') }
|
||||
).to have_been_made
|
||||
end
|
||||
|
||||
it 'should receive content' do
|
||||
expect(received).to eql 'Hello world'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with disconnects' do
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(body: ['Hello ', Timeout::Error])
|
||||
.to_return(body: 'world')
|
||||
end
|
||||
|
||||
it 'should receive entire content' do
|
||||
expect(received).to eql('Hello world')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with default destination' do
|
||||
let(:dest) { nil }
|
||||
let(:received) { command.execute(client).string }
|
||||
include_examples 'should download'
|
||||
end
|
||||
|
||||
context 'with IO destination' do
|
||||
let(:dest) { Tempfile.new('test') }
|
||||
let(:received) do
|
||||
command.execute(client)
|
||||
dest.rewind
|
||||
dest.read
|
||||
end
|
||||
|
||||
include_examples 'should download'
|
||||
end
|
||||
|
||||
context 'with filename destination' do
|
||||
let(:dest) { File.join(Dir.mktmpdir, 'test.txt') }
|
||||
let(:received) do
|
||||
command.execute(client)
|
||||
File.read(dest)
|
||||
end
|
||||
|
||||
include_examples 'should download'
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/core/hashable'
|
||||
|
||||
RSpec.describe Google::Apis::Core::Hashable do
|
||||
let(:child_class) do
|
||||
Class.new do
|
||||
include Google::Apis::Core::Hashable
|
||||
attr_accessor :value
|
||||
end
|
||||
end
|
||||
|
||||
let(:model_class) do
|
||||
Class.new do
|
||||
include Google::Apis::Core::Hashable
|
||||
attr_accessor :value
|
||||
attr_accessor :value2
|
||||
attr_accessor :children
|
||||
end
|
||||
end
|
||||
|
||||
let(:model) do
|
||||
obj = model_class.new
|
||||
obj.value = 'hello'
|
||||
obj.value2 = {
|
||||
a: 'a'
|
||||
}
|
||||
child = child_class.new
|
||||
child.value = 'goodbye'
|
||||
obj.children = [child]
|
||||
obj
|
||||
end
|
||||
|
||||
let(:hash) { model.to_h }
|
||||
|
||||
it 'should serialize attributes' do
|
||||
expect(hash).to include(value: 'hello')
|
||||
end
|
||||
|
||||
it 'should serialize collections' do
|
||||
expect(hash).to include(children: [{ value: 'goodbye' }])
|
||||
end
|
||||
|
||||
it 'should serialize hashes' do
|
||||
expect(hash[:value2]).to include(a: 'a')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,238 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/core/http_command'
|
||||
require 'hurley/test'
|
||||
|
||||
RSpec.describe Google::Apis::Core::HttpCommand do
|
||||
include TestHelpers
|
||||
include_context 'HTTP client'
|
||||
|
||||
context('with credentials') do
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
command.options.authorization = authorization
|
||||
command
|
||||
end
|
||||
|
||||
context('that are refreshable') do
|
||||
let(:authorization) do
|
||||
calls = 0
|
||||
auth = object_double(Signet::OAuth2::Client.new)
|
||||
allow(auth).to receive(:apply!) do |header|
|
||||
header['Authorization'] = sprintf('Bearer a_token_value_%d', calls)
|
||||
calls += 1
|
||||
end
|
||||
auth
|
||||
end
|
||||
|
||||
it 'should send credentials' do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals').to_return(body: %(Hello world))
|
||||
result = command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['Authorization'] == 'Bearer a_token_value_0' }).to have_been_made
|
||||
end
|
||||
|
||||
context('with authorizaton error') do
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [401, 'Unauthorized'])
|
||||
.to_return(body: %(Hello world))
|
||||
end
|
||||
|
||||
it 'should refresh if auth error received' do
|
||||
result = command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['Authorization'] == 'Bearer a_token_value_1' }).to have_been_made
|
||||
end
|
||||
|
||||
it 'should ignore retry count' do
|
||||
command.options.retries = 0
|
||||
result = command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['Authorization'] == 'Bearer a_token_value_1' }).to have_been_made
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context('that are bare tokens`') do
|
||||
let(:authorization) { 'a_token_value' }
|
||||
|
||||
it 'should send credentials' do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals').to_return(body: %(Hello world))
|
||||
result = command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| expect(req.headers['Authorization']).to eql 'Bearer a_token_value' }).to have_been_made
|
||||
end
|
||||
|
||||
it 'should send not refresh' do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals').to_return(status: [401, 'Unauthorized'])
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::AuthorizationError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context('with a successful response') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals').to_return(body: %(Hello world))
|
||||
end
|
||||
|
||||
it 'should return the response body if block not present' do
|
||||
result = command.execute(client)
|
||||
expect(result).to eql 'Hello world'
|
||||
end
|
||||
|
||||
it 'should call block if present' do
|
||||
expect { |b| command.execute(client, &b) }.to yield_with_args('Hello world', nil)
|
||||
end
|
||||
end
|
||||
|
||||
context('with server errors') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [500, 'Server error']).times(2)
|
||||
.to_return(body: %(Hello world))
|
||||
end
|
||||
|
||||
it 'should return the response body' do
|
||||
result = command.execute(client)
|
||||
expect(result).to eql 'Hello world'
|
||||
end
|
||||
|
||||
it 'should raise error if retries exceeded' do
|
||||
command.options.retries = 1
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::ServerError)
|
||||
end
|
||||
|
||||
context('with callbacks') do
|
||||
it 'should return the response body after retries' do
|
||||
expect { |b| command.execute(client, &b) }.to yield_successive_args(
|
||||
[nil, an_instance_of(Google::Apis::ServerError)],
|
||||
[nil, an_instance_of(Google::Apis::ServerError)],
|
||||
['Hello world', nil])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context('with options') do
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
command.options.header = { 'X-Foo' => 'bar' }
|
||||
command
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(body: %(Hello world))
|
||||
end
|
||||
|
||||
it 'should send user headers' do
|
||||
result = command.execute(client)
|
||||
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['X-Foo'] == 'bar' }).to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
context('with redirects') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [302, 'Redirect'], headers: { 'Location' => 'https://zoo.googleapis.com/animals' })
|
||||
stub_request(:get, 'https://zoo.googleapis.com/animals')
|
||||
.to_return(body: %(Hello world))
|
||||
end
|
||||
|
||||
it 'should return the response body' do
|
||||
result = command.execute(client)
|
||||
expect(result).to eql 'Hello world'
|
||||
end
|
||||
end
|
||||
|
||||
context('with too many redirects') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [302, 'Redirect'], headers: { 'Location' => 'https://www.googleapis.com/zoo/animals' }).times(6)
|
||||
end
|
||||
|
||||
it 'should raise error if retries exceeded' do
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::RedirectError)
|
||||
end
|
||||
end
|
||||
|
||||
context('with no server response') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals').to_timeout
|
||||
end
|
||||
|
||||
it 'should raise transmission error' do
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::TransmissionError)
|
||||
end
|
||||
end
|
||||
|
||||
context('with invalid status code') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [0, 'Wat!?'])
|
||||
end
|
||||
|
||||
it 'should raise transmission error' do
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::TransmissionError)
|
||||
end
|
||||
end
|
||||
|
||||
context('with client errors') do
|
||||
let(:command) do
|
||||
Google::Apis::Core::HttpCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(status: [400, 'Invalid request'])
|
||||
end
|
||||
|
||||
it 'should raise error without retry' do
|
||||
command.options.retries = 1
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::ClientError)
|
||||
end
|
||||
|
||||
it 'should call block if present' do
|
||||
expect { |b| command.execute(client, &b) }.to yield_with_args(nil, an_instance_of(Google::Apis::ClientError))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,192 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/core/json_representation'
|
||||
|
||||
RSpec.describe Google::Apis::Core::JsonRepresentation do
|
||||
let(:child_class) do
|
||||
Class.new do
|
||||
attr_accessor :value
|
||||
end
|
||||
end
|
||||
|
||||
let(:model_class) do
|
||||
Class.new do
|
||||
attr_accessor :unset_value
|
||||
attr_accessor :nil_value
|
||||
attr_accessor :numeric_value
|
||||
attr_accessor :string_value
|
||||
attr_accessor :boolean_value
|
||||
attr_accessor :date_value
|
||||
attr_accessor :bytes_value
|
||||
attr_accessor :items
|
||||
attr_accessor :child
|
||||
attr_accessor :children
|
||||
end
|
||||
end
|
||||
|
||||
let(:representer_class) do
|
||||
klass = child_class
|
||||
Class.new(Google::Apis::Core::JsonRepresentation) do
|
||||
property :unset_value, as: 'unsetValue'
|
||||
property :nil_value, as: 'nilValue'
|
||||
property :numeric_value, as: 'numericValue'
|
||||
property :string_value, as: 'stringValue'
|
||||
property :boolean_value, as: 'booleanValue'
|
||||
property :date_value, as: 'dateValue', type: DateTime
|
||||
property :bytes_value, as: 'bytesValue', base64: true
|
||||
property :items
|
||||
property :child, class: klass do
|
||||
property :value
|
||||
end
|
||||
collection :children, class: klass do
|
||||
property :value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'it serializes' do
|
||||
it 'does not serialize unset values' do
|
||||
expect(json).not_to have_json_path('unsetValue')
|
||||
end
|
||||
|
||||
it 'serializes explicit nil values' do
|
||||
expect(json).to be_json_eql(%(null)).at_path('nilValue')
|
||||
end
|
||||
|
||||
it 'serializes numeric values' do
|
||||
expect(json).to be_json_eql(%(123)).at_path('numericValue')
|
||||
end
|
||||
|
||||
it 'serializes string values' do
|
||||
expect(json).to be_json_eql(%("test")).at_path('stringValue')
|
||||
end
|
||||
|
||||
it 'serializes boolean values' do
|
||||
expect(json).to be_json_eql(%(true)).at_path('booleanValue')
|
||||
end
|
||||
|
||||
it 'serializes date values' do
|
||||
expect(json).to be_json_eql(%("2015-05-01T12:00:00+00:00")).at_path('dateValue')
|
||||
end
|
||||
|
||||
it 'serializes byte values to base64' do
|
||||
expect(json).to be_json_eql(%("SGVsbG8gd29ybGQ=")).at_path('bytesValue')
|
||||
end
|
||||
|
||||
it 'serializes basic collections' do
|
||||
expect(json).to be_json_eql(%([1,2,3])).at_path('items')
|
||||
end
|
||||
|
||||
it 'serializes nested objects' do
|
||||
expect(json).to be_json_eql(%({"value" : "child"})).at_path('child')
|
||||
end
|
||||
|
||||
it 'serializes object collections' do
|
||||
expect(json).to be_json_eql(%([{"value" : "child"}])).at_path('children')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with model object' do
|
||||
let(:json) { representer_class.new(model).to_json(skip_undefined: true) }
|
||||
let(:model) do
|
||||
model = model_class.new
|
||||
model.nil_value = nil
|
||||
model.numeric_value = 123
|
||||
model.string_value = 'test'
|
||||
model.date_value = DateTime.new(2015, 5, 1, 12)
|
||||
model.boolean_value = true
|
||||
model.bytes_value = 'Hello world'
|
||||
model.items = [1, 2, 3]
|
||||
model.child = child_class.new
|
||||
model.child.value = 'child'
|
||||
model.children = [model.child]
|
||||
model
|
||||
end
|
||||
|
||||
include_examples 'it serializes'
|
||||
end
|
||||
|
||||
context 'with hash' do
|
||||
let(:json) { representer_class.new(model).to_json(skip_undefined: true) }
|
||||
let(:model) do
|
||||
{
|
||||
nil_value: nil,
|
||||
string_value: 'test',
|
||||
numeric_value: 123,
|
||||
date_value: DateTime.new(2015, 5, 1, 12),
|
||||
boolean_value: true,
|
||||
bytes_value: 'Hello world',
|
||||
items: [1, 2, 3],
|
||||
child: {
|
||||
value: 'child'
|
||||
},
|
||||
children: [{ value: 'child' }]
|
||||
}
|
||||
end
|
||||
|
||||
include_examples 'it serializes'
|
||||
end
|
||||
|
||||
context 'when de-serializing' do
|
||||
let(:model) { representer_class.new(model_class.new).from_json(json) }
|
||||
let(:json) do
|
||||
json = <<EOF
|
||||
{ "stringValue": "test",
|
||||
"nilValue": null,
|
||||
"booleanValue": true,
|
||||
"numericValue": 123,
|
||||
"dateValue": "2015-05-01T12:00:00+00:00",
|
||||
"bytesValue": "SGVsbG8gd29ybGQ=",
|
||||
"items": [1,2,3],
|
||||
"child": {"value" : "hello"},
|
||||
"children": [{"value" : "hello"}]
|
||||
}
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'deserializes string values' do
|
||||
expect(model.string_value).to eql 'test'
|
||||
end
|
||||
|
||||
it 'deserializes null values' do
|
||||
expect(model.nil_value).to be_nil
|
||||
end
|
||||
|
||||
it 'deserializes numeric values' do
|
||||
expect(model.numeric_value).to eql 123
|
||||
end
|
||||
|
||||
it 'deserializes boolean values' do
|
||||
expect(model.boolean_value).to be_truthy
|
||||
end
|
||||
|
||||
it 'deserializes date values' do
|
||||
expect(model.date_value).to eql DateTime.new(2015, 5, 1, 12)
|
||||
end
|
||||
|
||||
it 'deserializes basic collections' do
|
||||
expect(model.items).to contain_exactly(1, 2, 3)
|
||||
end
|
||||
|
||||
it 'deserializes nested objects' do
|
||||
expect(model.child.value).to eql 'hello'
|
||||
end
|
||||
|
||||
it 'serializes object collections' do
|
||||
expect(model.children[0].value).to eql 'hello'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,247 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/options'
|
||||
require 'google/apis/core/base_service'
|
||||
require 'google/apis/core/json_representation'
|
||||
require 'hurley/test'
|
||||
|
||||
RSpec.describe Google::Apis::Core::BaseService do
|
||||
include TestHelpers
|
||||
|
||||
let(:service) { Google::Apis::Core::BaseService.new('https://www.googleapis.com/', '') }
|
||||
|
||||
before do
|
||||
Google::Apis::ClientOptions.default.application_name = 'test'
|
||||
Google::Apis::ClientOptions.default.application_version = '1.0'
|
||||
end
|
||||
|
||||
it 'should inherit default options' do
|
||||
expect(service.client_options.application_name).to eql 'test'
|
||||
end
|
||||
|
||||
it 'should include application in user agent' do
|
||||
agent = service.send(:user_agent)
|
||||
expect(agent).to match /^test\/1.0/
|
||||
end
|
||||
|
||||
it 'should inherit authorization' do
|
||||
Google::Apis::RequestOptions.default.authorization = 'a token'
|
||||
expect(service.authorization).to eql 'a token'
|
||||
end
|
||||
|
||||
it 'should allow overiding authorization' do
|
||||
Google::Apis::RequestOptions.default.authorization = 'a token'
|
||||
service.authorization = 'another token'
|
||||
expect(service.authorization).to eql 'another token'
|
||||
end
|
||||
|
||||
shared_examples 'with options' do
|
||||
it 'should inherit service options' do
|
||||
service.request_options.retries = 2
|
||||
expect(command.options.retries).to eql 2
|
||||
end
|
||||
|
||||
it 'should include per-request options' do
|
||||
expect(command.options.authorization).to eql 'foo'
|
||||
end
|
||||
|
||||
it 'should allow per-request options to override service options' do
|
||||
service.request_options.authorization = 'bar'
|
||||
expect(command.options.authorization).to eql 'foo'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when making raw http requests' do
|
||||
context 'with :get methods' do
|
||||
before(:example) do
|
||||
stub_request(:get, 'https://www.googleapis.com/zoo/animals').to_return(body: 'hello world')
|
||||
end
|
||||
|
||||
it 'should return body for get' do
|
||||
response = service.http(:get, 'https://www.googleapis.com/zoo/animals')
|
||||
expect(response).to eq 'hello world'
|
||||
end
|
||||
|
||||
it 'should return allow downloads' do
|
||||
response = service.http(:get, 'https://www.googleapis.com/zoo/animals', download_dest: StringIO.new)
|
||||
expect(response.string).to eq 'hello world'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with :post methods' do
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals').to_return(body: '')
|
||||
end
|
||||
|
||||
it 'should post body' do
|
||||
service.http(:post, 'https://www.googleapis.com/zoo/animals', body: 'hello')
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with(body: 'hello')).to have_been_made
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when making simple commands' do
|
||||
let(:command) { service.send(:make_simple_command, :get, 'zoo/animals', authorization: 'foo') }
|
||||
|
||||
it 'should return the correct command type' do
|
||||
expect(command).to be_an_instance_of(Google::Apis::Core::ApiCommand)
|
||||
end
|
||||
|
||||
it 'should build a correct URL' do
|
||||
url = command.url.expand({}).to_s
|
||||
expect(url).to eql 'https://www.googleapis.com/zoo/animals'
|
||||
end
|
||||
|
||||
include_examples 'with options'
|
||||
end
|
||||
|
||||
context 'when making download commands' do
|
||||
let(:command) { service.send(:make_download_command, :get, 'zoo/animals', authorization: 'foo') }
|
||||
|
||||
it 'should return the correct command type' do
|
||||
expect(command).to be_an_instance_of(Google::Apis::Core::DownloadCommand)
|
||||
end
|
||||
|
||||
it 'should build a correct URL' do
|
||||
url = command.url.expand({}).to_s
|
||||
expect(url).to eql 'https://www.googleapis.com/zoo/animals'
|
||||
end
|
||||
|
||||
it 'should include alt=media in params' do
|
||||
expect(command.query).to include('alt' => 'media')
|
||||
end
|
||||
|
||||
include_examples 'with options'
|
||||
end
|
||||
|
||||
context 'when making upload commands' do
|
||||
let(:command) { service.send(:make_upload_command, :post, 'zoo/animals', authorization: 'foo') }
|
||||
|
||||
it 'should return the correct command type' do
|
||||
expect(command).to be_an_instance_of(Google::Apis::Core::ResumableUploadCommand)
|
||||
end
|
||||
|
||||
it 'should build a correct URL' do
|
||||
url = command.url.expand({}).to_s
|
||||
expect(url).to eql 'https://www.googleapis.com/upload/zoo/animals'
|
||||
end
|
||||
|
||||
include_examples 'with options'
|
||||
end
|
||||
|
||||
context 'with batch' do
|
||||
before(:example) do
|
||||
response = <<EOF.gsub(/\n/, "\r\n")
|
||||
--batch123
|
||||
Content-Type: application/http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
Hello
|
||||
--batch123--
|
||||
EOF
|
||||
stub_request(:post, 'https://www.googleapis.com/batch')
|
||||
.to_return(headers: { 'Content-Type' => 'multipart/mixed; boundary=batch123' }, body: response)
|
||||
end
|
||||
|
||||
it 'should add commands to a batch' do
|
||||
expect do |b|
|
||||
service.batch do |service|
|
||||
command = service.send(:make_simple_command, :get, 'zoo/animals', {})
|
||||
service.send(:execute_or_queue_command, command, &b)
|
||||
end
|
||||
end.to yield_with_args('Hello', nil)
|
||||
end
|
||||
|
||||
it 'should disallow uploads in batch' do
|
||||
expect do |b|
|
||||
service.batch do |service|
|
||||
command = service.send(:make_upload_command, :post, 'zoo/animals', {})
|
||||
service.send(:execute_or_queue_command, command, &b)
|
||||
end
|
||||
end.to raise_error(Google::Apis::ClientError)
|
||||
end
|
||||
|
||||
it 'should disallow downloads in batch' do
|
||||
expect do |b|
|
||||
service.batch do |service|
|
||||
command = service.send(:make_download_command, :get, 'zoo/animals', {})
|
||||
service.send(:execute_or_queue_command, command, &b)
|
||||
end
|
||||
end.to raise_error(Google::Apis::ClientError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with batch uploads' do
|
||||
before(:example) do
|
||||
response = <<EOF.gsub(/\n/, "\r\n")
|
||||
--batch123
|
||||
Content-Type: application/http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
Hello
|
||||
--batch123--
|
||||
EOF
|
||||
stub_request(:put, 'https://www.googleapis.com/upload/')
|
||||
.to_return(headers: { 'Content-Type' => 'multipart/mixed; boundary=batch123' }, body: response)
|
||||
end
|
||||
|
||||
it 'should add upload to a batch' do
|
||||
expect do |b|
|
||||
service.batch_upload do |service|
|
||||
command = service.send(:make_upload_command, :post, 'zoo/animals', {})
|
||||
command.upload_source = StringIO.new('test')
|
||||
command.upload_content_type = 'text/plain'
|
||||
service.send(:execute_or_queue_command, command, &b)
|
||||
end
|
||||
end.to yield_with_args('Hello', nil)
|
||||
end
|
||||
|
||||
it 'should use multipart upload' do
|
||||
expect do |b|
|
||||
service.batch_upload do |service|
|
||||
command = service.send(:make_upload_command, :post, 'zoo/animals', {})
|
||||
command.upload_source = StringIO.new('test')
|
||||
command.upload_content_type = 'text/plain'
|
||||
expect(command).to be_an_instance_of(Google::Apis::Core::MultipartUploadCommand)
|
||||
service.send(:execute_or_queue_command, command, &b)
|
||||
end
|
||||
end.to yield_with_args('Hello', nil)
|
||||
end
|
||||
|
||||
it 'should disallow downloads in batch' do
|
||||
expect do |b|
|
||||
service.batch_upload do |service|
|
||||
command = service.send(:make_download_command, :get, 'zoo/animals', {})
|
||||
service.send(:execute_or_queue_command, command, &b)
|
||||
end
|
||||
end.to raise_error(Google::Apis::ClientError)
|
||||
end
|
||||
|
||||
it 'should disallow simple commands in batch' do
|
||||
expect do |b|
|
||||
service.batch_upload do |service|
|
||||
command = service.send(:make_simple_command, :get, 'zoo/animals', {})
|
||||
service.send(:execute_or_queue_command, command, &b)
|
||||
end
|
||||
end.to raise_error(Google::Apis::ClientError)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,238 @@
|
||||
# Copyright 2015 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'google/apis/core/upload'
|
||||
require 'google/apis/core/json_representation'
|
||||
require 'hurley/test'
|
||||
|
||||
# TODO: JSON Response decoding
|
||||
# TODO: Upload from IO
|
||||
# TODO: Upload from file
|
||||
|
||||
RSpec.describe Google::Apis::Core::UploadIO do
|
||||
let(:upload_io) { Google::Apis::Core::UploadIO.from_file(file) }
|
||||
|
||||
context 'with text file' do
|
||||
let(:file) { File.join(FIXTURES_DIR, 'files', 'test.txt') }
|
||||
it 'should infer content type from file' do
|
||||
expect(upload_io.content_type).to eql('text/plain')
|
||||
end
|
||||
|
||||
it 'should allow overriding the mime type' do
|
||||
io = Google::Apis::Core::UploadIO.from_file(file, content_type: 'application/json')
|
||||
expect(io.content_type).to eql('application/json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with unknown type' do
|
||||
let(:file) { File.join(FIXTURES_DIR, 'files', 'test.blah') }
|
||||
it 'should use the default mime type' do
|
||||
expect(upload_io.content_type).to eql('application/octet-stream')
|
||||
end
|
||||
|
||||
it 'should allow overriding the mime type' do
|
||||
io = Google::Apis::Core::UploadIO.from_file(file, content_type: 'application/json')
|
||||
expect(io.content_type).to eql('application/json')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Google::Apis::Core::RawUploadCommand do
|
||||
include TestHelpers
|
||||
include_context 'HTTP client'
|
||||
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::RawUploadCommand.new(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
command.upload_source = file
|
||||
command.upload_content_type = 'text/plain'
|
||||
command
|
||||
end
|
||||
|
||||
shared_examples 'should upload' do
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals').to_return(body: '')
|
||||
end
|
||||
|
||||
it 'should send content' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with(body: "Hello world\n")).to have_been_made
|
||||
end
|
||||
|
||||
it 'should send upload protocol' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['X-Goog-Upload-Protocol'] == 'raw' }).to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
context('with StringIO input') do
|
||||
let(:file) { StringIO.new("Hello world\n") }
|
||||
include_examples 'should upload'
|
||||
end
|
||||
|
||||
context('with IO input') do
|
||||
let(:file) { File.open(File.join(FIXTURES_DIR, 'files', 'test.txt'), 'r') }
|
||||
include_examples 'should upload'
|
||||
|
||||
it 'should not close stream' do
|
||||
expect(file.closed?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context('with file path input') do
|
||||
let(:file) { File.join(FIXTURES_DIR, 'files', 'test.txt') }
|
||||
include_examples 'should upload'
|
||||
end
|
||||
|
||||
context('with invalid input') do
|
||||
let(:file) { -> {} }
|
||||
it 'should raise client error' do
|
||||
expect { command.execute(client) }.to raise_error(Google::Apis::ClientError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Google::Apis::Core::MultipartUploadCommand do
|
||||
include TestHelpers
|
||||
include_context 'HTTP client'
|
||||
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::MultipartUploadCommand.new(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
command.upload_source = StringIO.new('Hello world')
|
||||
command.upload_content_type = 'text/plain'
|
||||
command.body = 'metadata'
|
||||
command
|
||||
end
|
||||
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals').to_return(body: %(Hello world))
|
||||
end
|
||||
|
||||
it 'should send content' do
|
||||
expected_body = <<EOF.gsub(/\n/, "\r\n")
|
||||
--RubyApiClientUpload
|
||||
Content-Type: application/json
|
||||
|
||||
metadata
|
||||
--RubyApiClientUpload
|
||||
Content-Length: 11
|
||||
Content-Type: text/plain
|
||||
Content-Transfer-Encoding: binary
|
||||
|
||||
Hello world
|
||||
--RubyApiClientUpload--
|
||||
|
||||
EOF
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with(body: expected_body)).to have_been_made
|
||||
end
|
||||
|
||||
it 'should send upload protocol' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['X-Goog-Upload-Protocol'] == 'multipart' }).to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Google::Apis::Core::ResumableUploadCommand do
|
||||
include TestHelpers
|
||||
include_context 'HTTP client'
|
||||
|
||||
let(:command) do
|
||||
command = Google::Apis::Core::ResumableUploadCommand.new(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
command.upload_source = StringIO.new('Hello world')
|
||||
command.upload_content_type = 'text/plain'
|
||||
command
|
||||
end
|
||||
|
||||
context 'with uninterrupted upload' do
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'active', 'X-Goog-Upload-URL' => 'https://www.googleapis.com/zoo/animals' })
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'final' }, body: %(OK))
|
||||
end
|
||||
|
||||
it 'should send upload protocol' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['X-Goog-Upload-Protocol'] == 'resumable' }).to have_been_made
|
||||
end
|
||||
|
||||
it 'should send start command' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['X-Goog-Upload-Command'] == 'start' }).to have_been_made
|
||||
end
|
||||
|
||||
it 'should send upload command' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with { |req| req.headers['X-Goog-Upload-Command'].include?('upload') }).to have_been_made
|
||||
end
|
||||
|
||||
it 'should send upload content' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with(body: 'Hello world')).to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
context 'with retriable error on start' do
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_timeout
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'active', 'X-Goog-Upload-URL' => 'https://www.googleapis.com/zoo/animals' })
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'active', 'X-Goog-Upload-Size-Received' => '6' })
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'final' }, body: %(OK))
|
||||
end
|
||||
|
||||
it 'should retry start command and continue' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with(body: 'Hello world')).to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
context 'with interruption' do
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'active', 'X-Goog-Upload-URL' => 'https://www.googleapis.com/zoo/animals' })
|
||||
.to_return(status: [500, 'Server error'])
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'active', 'X-Goog-Upload-Size-Received' => '6' })
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'final' }, body: %(OK))
|
||||
end
|
||||
|
||||
it 'should send remaining upload content after failure' do
|
||||
command.execute(client)
|
||||
expect(a_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.with(body: 'world')).to have_been_made
|
||||
end
|
||||
end
|
||||
|
||||
context 'with cancelled upload' do
|
||||
before(:example) do
|
||||
stub_request(:post, 'https://www.googleapis.com/zoo/animals')
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'active', 'X-Goog-Upload-URL' => 'https://www.googleapis.com/zoo/animals' })
|
||||
.to_return(status: [500, 'Server error'])
|
||||
.to_return(headers: { 'X-Goog-Upload-Status' => 'cancelled' })
|
||||
end
|
||||
|
||||
it 'should raise error' do
|
||||
expect { command.execute(client) }.to raise_error Google::Apis::ClientError
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user