21700: Install Bundler system-wide in Rails postinst
[arvados.git] / sdk / ruby-google-api-client / spec / google / api_client / media_spec.rb
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