Skip to content

Commit ca8275f

Browse files
authored
feat: Add storage specific download to respond with http header
1 parent 04c2332 commit ca8275f

File tree

5 files changed

+163
-5
lines changed

5 files changed

+163
-5
lines changed

google-apis-core/lib/google/apis/core/base_service.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
require 'google/apis/core/batch'
2121
require 'google/apis/core/upload'
2222
require 'google/apis/core/download'
23+
require 'google/apis/core/storage_download'
2324
require 'google/apis/options'
2425
require 'googleauth'
2526
require 'httpclient'

google-apis-core/lib/google/apis/core/batch.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def prepare!
120120
end
121121

122122
def ensure_valid_command(command)
123-
if command.is_a?(Google::Apis::Core::BaseUploadCommand) || command.is_a?(Google::Apis::Core::DownloadCommand)
123+
if command.is_a?(Google::Apis::Core::BaseUploadCommand) || command.is_a?(Google::Apis::Core::DownloadCommand) || command.is_a?(Google::Apis::Core::StorageDownloadCommand)
124124
fail Google::Apis::ClientError, 'Can not include media requests in batch'
125125
end
126126
fail Google::Apis::ClientError, 'Invalid command object' unless command.is_a?(HttpCommand)

google-apis-core/spec/google/apis/core/service_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,25 @@
168168
include_examples 'with options'
169169
end
170170

171+
context 'when making storage download commands' do
172+
let(:command) { service.send(:make_storage_download_command, :get, 'zoo/animals', authorization: 'foo') }
173+
174+
it 'should return the correct command type' do
175+
expect(command).to be_an_instance_of(Google::Apis::Core::StorageDownloadCommand)
176+
end
177+
178+
it 'should build a correct URL' do
179+
url = command.url.expand({}).to_s
180+
expect(url).to eql 'https://www.googleapis.com/zoo/animals'
181+
end
182+
183+
it 'should include alt=media in params' do
184+
expect(command.query).to include('alt' => 'media')
185+
end
186+
187+
include_examples 'with options'
188+
end
189+
171190
context 'when making upload commands' do
172191
let(:command) { service.send(:make_upload_command, :post, 'zoo/animals', authorization: 'foo') }
173192

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Copyright 2022 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+
require 'google/apis/core/storage_download'
17+
require 'google/apis/core/json_representation'
18+
require 'tempfile'
19+
require 'tmpdir'
20+
21+
RSpec.describe Google::Apis::Core::StorageDownloadCommand do
22+
include TestHelpers
23+
include_context 'HTTP client'
24+
25+
let(:command) do
26+
command = Google::Apis::Core::StorageDownloadCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
27+
command.download_dest = dest
28+
command
29+
end
30+
31+
shared_examples 'should download' do
32+
context 'with successful response' do
33+
before(:example) do
34+
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
35+
.to_return(headers: { 'Content-Type' => 'application/json' }, body: %(Hello world))
36+
end
37+
38+
it 'should not include a range header' do
39+
command.execute(client)
40+
expect(a_request(:get, 'https://www.googleapis.com/zoo/animals')
41+
.with { |req| !req.headers.key?('Range') }
42+
).to have_been_made
43+
end
44+
45+
it 'should receive content' do
46+
expect(received).to eql 'Hello world'
47+
end
48+
end
49+
50+
context 'with error' do
51+
before(:example) do
52+
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
53+
.to_return(status: [404, 'Not Found'], body: '')
54+
end
55+
56+
it 'should raise error' do
57+
expect {received}.to raise_error(Google::Apis::ClientError)
58+
end
59+
end
60+
61+
context 'with disconnects' do
62+
before(:example) do
63+
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
64+
.to_return(body: ['Hello ', Timeout::Error])
65+
.to_return(status: [206, 'Partial content'], body: 'world')
66+
end
67+
68+
it 'should receive entire content' do
69+
expect(received).to eql('Hello world')
70+
end
71+
end
72+
73+
context 'with disconnects and no partial response' do
74+
before(:example) do
75+
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
76+
.to_return(body: ['Hello ', Timeout::Error])
77+
.to_return(body: 'Hello world')
78+
end
79+
80+
it 'should receive entire content' do
81+
expect(received).to eql('Hello world')
82+
end
83+
end
84+
85+
context 'with redirect' do
86+
before(:example) do
87+
stub_request(:get, 'https://www.googleapis.com/zoo/animals')
88+
.to_return(status: [302, 'Content moved'], headers: { 'Location' => 'https://content.googleapis.com/files/12345' }, body: %(Content moved))
89+
stub_request(:get, 'https://content.googleapis.com/files/12345')
90+
.to_return(headers: { 'Content-Type' => 'application/json' }, body: %(Hello world))
91+
end
92+
93+
it 'should receive content' do
94+
expect(received).to eql 'Hello world'
95+
end
96+
end
97+
end
98+
99+
context 'with filename destination' do
100+
let(:dest) { File.join(Dir.mktmpdir, 'test.txt') }
101+
let(:received) do
102+
command.execute(client)
103+
File.read(dest)
104+
end
105+
106+
include_examples 'should download'
107+
end
108+
109+
context 'with default destination' do
110+
let(:dest) { nil }
111+
let(:received) { command.execute(client)[0].string }
112+
include_examples 'should download'
113+
end
114+
115+
context 'with IO destination' do
116+
let(:dest) { Tempfile.new('test') }
117+
let(:received) do
118+
command.execute(client)
119+
dest.rewind
120+
dest.read
121+
end
122+
123+
include_examples 'should download'
124+
end
125+
126+
context 'with #write destination' do
127+
let(:dest) { WritableIO.new(StringIO.new) }
128+
let(:received) { command.execute(client)[0].io.string }
129+
130+
include_examples 'should download'
131+
132+
WritableIO = Struct.new(:io) do
133+
def write(data)
134+
io.write(data)
135+
end
136+
end
137+
end
138+
end

google-apis-generator/lib/google/apis/generator/templates/_method.tmpl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,18 @@ def <%= api_method.generated_name %>(<% for param in api_method.required_paramet
5858
command.upload_source = upload_source
5959
command.upload_content_type = content_type
6060
end
61-
<% elsif api_method.supports_media_download? -%>
61+
<% elsif api_method.supports_media_download? && api.name == 'Storage' %>
6262
if download_dest.nil?
6363
command = make_simple_command(:<%= api_method.http_method.downcase %>, '<%= api_method.path %>', options)
6464
else
65-
command = make_download_command(:<%= api_method.http_method.downcase %>, '<%= api_method.path %>', options)
65+
command = make_storage_download_command(:<%= api_method.http_method.downcase %>, '<%= api_method.path %>', options)
6666
command.download_dest = download_dest
6767
end
68-
<% elsif api_method.supports_media_download? && api.name == 'Storage' %>
68+
<% elsif api_method.supports_media_download? -%>
6969
if download_dest.nil?
7070
command = make_simple_command(:<%= api_method.http_method.downcase %>, '<%= api_method.path %>', options)
7171
else
72-
command = make_storage_download_command(:<%= api_method.http_method.downcase %>, '<%= api_method.path %>', options)
72+
command = make_download_command(:<%= api_method.http_method.downcase %>, '<%= api_method.path %>', options)
7373
command.download_dest = download_dest
7474
end
7575
<% else -%>

0 commit comments

Comments
 (0)